CloudFront Extensions官方使用指南的使用指南

一、背景

Amazon CloudFront Extensions是亚马逊云科技开发的基于CloudFront的扩展方案,提供监控、版本控制、一键部署的Lambda@Edge函数等功能。目前CloudFront Extensions仅支持部署到AWS全球区域,不支持中国区域。

CloudFront Extensions作为AWS中国团队自开发的解决方案,通过CloudFormation堆栈进行部署,它包含了基于图形界面的WEB UI进行交互。However,官方文档编写不足,没有AWS基础的新用户上手困难。

本文针对以上痛点编写。

二、在AWS全球区域的账号内部署CloudFront Extensions管理平台

1、使用CloudFormation模版部署

首先登录到AWS全球区域的控制台,然后再额外打开一个浏览器标签页,访问亚马逊云科技中国区官网的这里。在页面上点击在全球区域控制台中启动方案的按钮,即可开始部署。如下截图。

随后浏览器会跳转到已经登录的AWS控制台,这也就是之前为何要先必须先登录好AWS全球区域控制台。

注意此时打开的CloudFront是美东1区域(us-east-1)也就是弗吉尼亚北部(N.Virginia),这是因为CloudFront是全球服务,配置CloudFront所需要的函数、SSL证书等都必须在这个区域。因此浏览器打开这个区域后,请不要切换到其他区域。当前CloudFront已经自动代入了模版地址,点击Next按钮即可继续。如下截图。

在Stack名称位置保持默认值,设置管理员名,例如为admin,输入管理员邮箱,设置密码。如下截图。

在下方监控Monitoring位置,在CloudFront Log Type位置选择实时监控yes-Realtime,需要注意实时监控的成本较高,产生的流式日志体量较大。您也可以选择非实时,或者关闭日志监控。在Domain List域名清单位置,输入大写的ALL,表示会监控所有Cloudfront的发布点。在监控周期上推荐选择默认的5分钟。其他选项保持默认即可。

这里推荐选5分钟是因为后台负责日志落盘的Kinesis Data Firehose是按照60秒间隔处理的。Kinesis Data Firehose从Kinesis Data Stream接收数据,再调用Lambda分析日志中的来源IP写回到DynamoDB,然后在S3设置分区键作为目录保存。整个处理周期并不能实现1分钟的间隔。因此选择默认的五分钟即可。

另外,这里CloudFormation部署时候选择实时监控,并不会打开现有任何CloudFront发布点的日志开关。这里选择实时监控,意味着本Stack堆栈会通过CloudFormation自动创建实时日志分析所需要的Kinesis Data Stream/Kinesis Data Firehose/Athena/DynamoDB等后台服务组件,并通过封装好的API Gateway接口,展示在控制台上。如果希望启用实时日志,在本CloudFormation部署完毕后,还需要在CloudFront上手工开启实时日志。

页面设置如下截图。

在下方SSL验证邮箱位置,输入一个邮箱作为SNS通知提示的邮箱。然后点击下一步。如下截图。

在向导的下一步,无需设置,将页面移动到最下方,点击下一步。如下截图。

在向导最后一步,选中两个确认按钮,这将允许CloudFormation创建所需要IAM角色。如下截图。

创建过程中,刚才输入的邮箱,会收到确认邮件,此时点击Confirm即可确认。如下截图。

在CloudFormation的Stack堆栈界面反复刷新,等待大概5分钟即可看到状态显示为创建完成。点击Output输出标签页,查看登录入口。如下截图。

Output标签页找到最下方的Web Console CloudFront URL,这个网址管理员登录入口。将其复制下来。如下截图。

基础环境部署完成。

2、初始化管理员账号

使用上一步复制下来的Web Console CloudFront URL,用浏览器打开。输入上一步设置的用户名和密码。点击登录。如下截图。

登录成功。如下截图。

三、配置实时监控日志分析

如前文所述,在CloudFormation堆栈创建界面上选择实时监控,意味着本Stack堆栈会通过CloudFormation自动创建实时日志分析所需要的Kinesis Data Stream/Kinesis Data Firehose/Athena/DynamoDB等后台服务组件,并通过封装好的API Gateway接口,展示在控制台上。如果希望启用实时日志,在本CloudFormation部署完毕后,还需要在CloudFront上手工开启实时日志。

1、开启CloudFront实时日志

进入CloudWatch服务界面,点击左侧的日志菜单,能看到当前发布点的日志都处于禁用状态。如下截图。

击右侧标签页Real-time configurations实时日志配置菜单,点击右上角创建按钮。如下截图。

Name位置,输入日志流的名称,在Sample rate采样率位置输入100,表示100%的采样。在字段位置,从下拉框中选择如下字段,注意选择的时候,保持顺序:

  • timestamp
  • c-ip
  • sc-status
  • sc-bytes
  • cs-host
  • cs-uri-stem
  • cs-bytes
  • time-taken
  • x-edge-response-result-type
  • x-edge-detailed-result-type
  • c-country

选择好字段之后,在Endpoint位置选择CloudFormation自动创建好的Kinesis流(位于us-east-1),然后继续向下滚动屏幕。如下截图。

在创建IAM Role位置,选择Create new service role,这时候会自动创建相应的IAM Role。在CloudFront发布点的下拉框中,选择要监控的发布点的名字,在Cache behaviors缓存规则位置选择默认。最后点击右下角的创建按钮。如下截图。

创建完成,向导返回Standard标签页界面,可以看到刚才新配置的日志已经显示为Enabled。如下截图。

此时切换到实时日志配置标签页,在其中也能看到刚才创建的配置已经出现在清单中。点击名字可以查看详情。如下截图。

点击详情后,向下滚动页面,可以看到新创建的日志与现有的发布点的绑定关系,在刚创建好的时候是Disabled状态,等待几分钟后再刷新页面,这里就会变为Enabled。如下截图。

现在实时的日志已经打开。

CloudFront Extensions方案会通过Kinesis Data Stream接收日志,然后通过Kinesis Data Firehose落盘到S3存储桶,最后借助Athena执行SQL查询分析生成报表。如果希望验证实时日志打开的效果,可进入美东1区域的Kinesis服务,查看Cloudfront日志流,通过选择对应的分区,可看到访问日志已经打到Kinesis流中。如下截图。

2、查看实时日志

现在登录到Cloudfront Extensions的控制台界面,点击左侧菜单的日志按钮,然后从发布点清单中,选择现有的发布点。如下截图。

从右侧的监控页中即可看到相关数据。点击右上角刷新按钮可刷新页面显示数据。如下截图。

积攒一段时间的数据后,可看到日志报表输出效果。如下截图。

四、配置扩展函数实现图片缩放

图片缩放的算力超过了CloudFront Functions能够修改的范围,因此需使用Lambda@Edge来进行运算实现图片缩放,并将修改尺寸后的新图片写入S3桶的操作。以下部署将基于CloudFront Extensions部署这一功能。

1、基础函数部署

首先进入CloudFront Extensions控制台。点击左侧Extensions菜单下的Repository,在右侧选择image-resize功能,然后点击部署。如下截图。

在部署向导第一步,选择CDN发布点,选择Behaviors是默认Default·,然后点击Next`下一步。如下截图。

在函数Stage位置选择origin-response,这是因为图片resize的过程是在S3源站返回CloudFront阶段执行的函数来修改尺寸。在适配尺寸类型的位置输入fill,这表示将拉伸图片适应尺寸要求。在最后的S3BucketName位置,输入存放图片的S3存储桶。这个存储桶与当前CDN发布点所发布的S3存储桶是同一个S3存储桶,这样修改尺寸后的图片,也会被保存在这个存储桶中。如下截图。

在创建向导中review设置,不用修改,然后点击Deploy按钮。如下截图。

点击部署后,页面提示正在部署。点击View deployment status可以跳转到CloudFormation查看模版部署状态。如下截图。

跳转到CloudFormation后,可看到新的堆栈正在部署中。如下截图。

现在等待3-5分钟等待函数部署完成。

2、确认CloudFront函数触发器配置生效(本步骤为确认,不需要修改)

在上一步CloudFormation完成部署后,现在进入CloudFront服务控制台。从发布点位置,找到上一步配置的发布点,点击Behaviors行为菜单,选中默认的行为,点击编辑按钮。如下截图。

将页面滚动到最下方,可看到在Origin response位置,已经绑定好了Lambda@Edge函数了。如下截图。

在本页面不需要继续操作了,可以点击取消按钮返回,也可以直接关闭窗口。

3、修改函数运行资源并发布函数

CloudFront Extensions解决方案中给出的函数是参考示例,可根据实际需要进行修改。在本例中,由CloudFormation创建出来的Lambda@Edge函数使用默认最小的128MB,对应的计算资源很低。因此当需要对数MB大小的图片进行Resize变换分辨率时候,响应速度非常慢。我们可将Lambda@Edge的运行资源从默认的128MB内存调整到1024MB,即可实现快速响应。

同时,由于Lambda@Edge是可以多函数并发的,因此当大量请求从互联网发来时候,不用担心其并发和延迟。如果函数达到了1000以上并发,可通过预置计算容量、调高Limit等方式满足高并发需求。

为了修改函数的运行资源,首先进入上一步的CloudFormation模版界面,可看到新的堆栈名为Resizeimage-xxxxxx,点击其名称进入详情页面。如下截图。

在详情页面中,点击Resources标签页,查看名为xxxx-ResizeLambdaEdgeFunction-xxxxx的函数。点击函数名称跳转。如下截图。

在Lambda函数页面上,找到Configuration配置标签页,在左侧菜单第一项General Configuration中,可看到其Memory内存是128MB。点击修改,将其修改为1024MB。如下截图。

在Lambda函数页面上,点击Actions操作下拉框,点击Deploy to Lambda@Edge。如下截图。

在弹出页面上,Select an option位置选择Configure new CloudFront trigger新部署触发器。在发布点位置,再次选择要配置的发布点。在行为位置选择默认的*行为。在Event事件下拉框中,选择Origin response事件(注意这里容易选错,请仔细对照)。在确认对话框中选择Confirm deploy to Lambda@Edge。最后点击部署按钮。如下截图。

部署过程需要等待3-5分钟,Lambda@Edge函数会被部署到全球负责运行函数的Regional Cache Center。

4、修改S3存储桶策略

本次部署的最后一个修改,是要在S3存储桶上为CloudFront运行角色赋予s3:listBucket权限,用于确认被缩放的文件是否存在。

在一个普通的发布S3存储桶的过程中,一般使用CloudFront的OAC功能进行授权,这样S3存储桶无需设置为Public,即可向CloudFront提供访问授权。这个配置过程可参考这篇博客。此时的S3存储桶策略只需要配置s3:getObject即可。当使用Lambda@Edge进行缩放时候,以上权限配置还需要增补一个s3:listBucket权限。操作方法如下。

进入当前CloudFront发布点对外发布的S3存储桶,找到Permissions权限标签页。向下滚动页面找到存储桶策略。如下截图。

在存储桶策略位置,点击编辑按钮,修改现有存储桶策略。如下截图。

现有存储桶策略之前是按照CloudFront OAC授权配置的,即S3存储桶不需要Public,即可为CloudFront提供访问权限。在如下部分要增加对应的片段,分别是在Actions部分的s3:listBucket和在Resources部分的"arn:aws:s3:::myblogupload"。此外,由于原先资源写法是单行,现在增加了第二条,因此还需要使用方括号把它们放进去并在每一行后加,隔离。如下截图。

策略修改后类似如下:

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::yourbucketname/*",
                "arn:aws:s3:::yourbucketname"
            ],
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1xxxxxxxx"
                }
            }
        }
    ]
}

这样即可运行Lambda@Edge查询对应文件。

5、测试函数运行结果

现在通过浏览器访问测试,选取一张图片,其普通访问行为和缩放访问行为分别是:

  • https://xxxx.com/image/a-01.png
  • https://xxxx.com/image/800×600/a-01.png
  • https://xxxx.com/image/1400×900/a-01.png

以上几个网址,分别是不缩放的原始图片,以及不同分辨率缩放方式调用。分别用浏览器测试测试,可看到测试成功。如下截图。

Lambda@Edge函数在执行完毕Resize修改分辨率后,会在存储桶内原始文件所在目录下,以分辨率为Prefix生成目录,里边保存的是修改过分辨率的图片。可以在S3存储桶内浏览文件来确认。如下截图。

由此确认Resize缩放功能工作正常。

五、手工方式配置更多函数

CloudFront Extensions提供的是一套扩展能力,在不部署整套CloudFront Extensions的情况下,也可以从Github获取代码样例,然后手工部署实现特定效果。

点击这里可获得Lambda@Edge代码(官方文档 & Github),他们包括:

  • Authentication with Cognito
  • 图片缩放
  • 限速
  • 防盗链
  • 添加安全标头
  • 根据设备类型跳转
  • Cross origin resource sharing
  • 修改响应状态码
  • 修改响应标头
  • 根据权重访问源站
  • Failover to alternative origin
  • Support 302 from origin
  • 标准化query string从而提高缓存命中率
  • Authentication with Alibaba Cloud
  • Rewrite host for custom origin
  • Serverless load balancer
  • Custom response with new URL

注:以上部分功能需要与其他服务进行联动。

点击这里可获得CloudFront Functions代码(官方文档 & Github),他们包括:

  • 添加安全标头
  • Cross origin resource sharing
  • 添加cache control标头
  • Add origin headers
  • 客户端IP透传
  • 根据地理位置跳转
  • Default dir index 
  • Verify JSON web token
  • Customize request host

部署过程,Lambda@Edge函数的用法可参考本篇博客。CloudFront Functions的用法可参考本篇博客。

六、参考文档

Amazon CloudFront Extensions 官网

https://www.amazonaws.cn/solutions/amazon-cloudfront-extensions/?nc1=h_ls

CloudFront Extensions实施指南

https://awslabs.github.io/aws-cloudfront-extensions/zh/

Github上源代码

https://github.com/awslabs/aws-cloudfront-extensions