1. 前述
通过本文章,您将了解如何通过AWS CodePipeline,AWS CodeBuild,AWS CloudFormation 来实现基于Amazon ECS的持续集成持续部署方案。
开发人员在GitHub中提交的新版本代码,会自动触发代码获取,打包镜像,上传镜像仓库,更新新版本容器服务,注册到负载均衡器等操作。
方案中会涉及使用如下组件:
GitHub:示例使用的源,一个提交到GitHub上的PHP示例网站。AWS CodePipeline支持GitHub, AWS CodeCommit服务,或者S3作为源。此次实例使用的Demo软件工程可以从以下链接Fork:
https://github.com/awslabs/ecs-demo-php-simple-app
Docker:作为发布服务使用的容器。演示方案的Build阶段会使用AWS CodeBuild托管的ubuntu/docker 1.12.1基础镜像。
Amazon EC2:作为ECS的容器宿主机集群。
Amazon VPC:服务所在的网络。
Amazon ECS:AWS托管的容器编排服务。文档链接 http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/Welcome.html
Amazon ECR:AWS 托管的容器镜像仓库。文档链接 http://docs.aws.amazon.com/zh_cn/AmazonECR/latest/userguide/what-is-ecr.html
AWS CodePipeline:AWS 托管的持续集成持续交付服务,可以快速可靠的更新应用程序和服务,集成支持GitHub,Jenkins等主流开源工具。文档链接 http://docs.aws.amazon.com/zh_cn/codepipeline/latest/userguide/welcome.html
AWS CodeBuild:AWS 托管的构建服务,用于打包代码生成可部署的软件包。文档链接 http://docs.aws.amazon.com/zh_cn/codebuild/latest/userguide/welcome.html
AWS CloudFormation:批量创建和管理AWS资源的自动化脚本。文档链接 http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/Welcome.html
2.方案架构
流程如下:
- 开发者将一个新版本的代码工程提交到GitHub
- Pipeline的Source阶段,检测到指定GitHub的repo有新版本的更新,从GitHub上拉取代码工程,开启已设定好的CICD Pipeline
- Pipeline的Build阶段,AWS CodeBuild将新版本的代码工程打包为Docker镜像
- AWS CodeBuild将打包好的镜像推送到Amazon ECR
- Pipeline的Deploy阶段,AWS CodePipeline触发AWS CloudFormation,其定义了Amazon ECS的Task definition和service
- AWS CloudFormation创建新版本的Task definition关联到新版本的Docker镜像,并更新Service
- Amazon ECS从Amazon ECR中取到新版本的Docker镜像,并运行来替换旧Task以完成服务的更新部署
3. 搭建
搭建部分分为以下几个步骤:基础设施,与CICD Pipeline的搭建。
3.1 基础设施部分的搭建
这里需要准备好网络,负载均衡器,S3以及运行ECS所需要的宿主机集群。
3.1.1 网络搭建
创建VPC,子网,Internet Gateway,路由表。将Internet Gateway Attach到VPC上,路由表配置0.0.0.0/0指向Internet Gateway,并关联子网。
之后的EC2宿主机集群,负载均衡器等都使用在这个网络里。
3.1.2 负载均衡器
创建ALB应用负载均衡器,监听80端口
选择对应的子网
新建安全组,端口80,并新建目标组
注册目标此时不选择,ECS创建服务时会注册集群和对应端口进来。
下一步审核后创建。
3.1.3 ECS宿主机集群
在ECS的界面下,创建集群
实例配置保持默认或根据情况自行选择,示例中保持默认。
联网配置,选择创建好的VPC,子网,创建Role允许宿主机上的ECS代理调用ECS服务的API。
创建后画面下面会显示集群信息
集群一览会显示
修改ECS宿主机集群的安全组,inbound源设置为建好的应用负载均衡器的安全组ID
3.1.4 ECR镜像仓库创建
创建一个用于Build阶段上传存放软件工程Docker镜像的镜像仓库
ECS界面下,创建存储库,创建好后如下
3.1.5 S3桶创建
创建一个S3桶用来存放Deploy阶段CloudFormation使用的脚本模版,创建桶时选择和以上服务同一Region,并且打开桶的版本控制。
将CloudFormation模版压缩zip后上传到桶中。
示例中将模版文件service.yaml放在templates文件夹后压缩为templates.zip。
service.yaml如下,注意缩进
到此基础设施部分的搭建工作结束。
3.2 Pipeline的搭建
分为Source,Build以及Deploy三阶段:
Source阶段设置GitHub上的软件工程位置,并设置Deploy阶段会使用的CloudFormation脚本模版来更新ECS服务,
Build阶段使用AWS CodeBuild来打包软件工程到Docker镜像并上传到ECR,
Deploy阶段使用Source阶段引入的CloudFormation脚本,找到对应的宿主机集群,负载均衡器,以及上传到ECR的Docker镜像等对象,更新服务。
AWS CodePipeline创建后的展示图是这样的,串起了整个CICD流程
在AWS CodePipeline界面点击创建管道Pipeline,可以看到画面左侧一个基本流程,从源,到生成Build,到部署Deploy,到角色等配置。实际应用中用户可以随实际需要,或随着CICD流程的由简入繁在创建后编辑加入新的阶段或操作。
点击下一步。
3.2.1 Source阶段配置
源提供商下拉菜单选择GitHub,
点击连接到GitHub来授权访问权,来允许AWS CodePipeline从GitHub上获取软件工程源内容,认证后选择GitHub上软件工程所在位置和分支
此次实例使用的Demo软件工程可以从以下链接Fork:
https://github.com/awslabs/ecs-demo-php-simple-app
点击下一步。
3.2.2 Build阶段配置
AWS CodePipeline在Build阶段支持包括AWS CodeBuild,Jenkins在内的引擎,此方案选用AWS 托管的CodeBuild服务
选择新建构建项目
选择AWS CodeBuild托管的镜像,支持Ubuntu系统,运行时支持包括Java,Python,Go语言,Node.js,Docker在内的众多选择,此次方案使用Docker。
构建规范这里选择使用buildspec.yml,里面预定了AWS CodeBuild在Build生命周期中要执行的动作,如login到ECR,打包Docker镜像,给Docker镜像打tag,上传Docker镜像到已login的ECR镜像仓库。
Buildspec.yml放在GitHub软件工程源代码目录中,如果复制粘贴的话注意yaml文件的缩进
选择Role
新建一个Role,这个Role允许AWS CodeBuild来调用相关的AWS服务,此方案中需要调用包括S3,ECR,CloudWatch在内的服务。
*默认创建的Role不具备对ECR的权限,需要在保存构建项目后,到IAM找到新创建的Role,编辑添加对ECR的权限否则后面Pipeline执行到Build时会报错。
保存构建项目。
点击下一步。
3.2.3 Deploy
AWS CodePipeline部署阶段支持包括AWS CloudFormation,AWS CodeDeploy,AWS Elastic Beanstalk在内的服务提供商,此方案选用AWS CloudFormation来部署ECS容器服务。
这里暂时选择无部署,等Pipeline创建好后,编辑引入Deploy的CloudFormation模版源,再进行配置。
点击下一步。
3.2.4 角色
配置AWS CodePipeline对AWS服务的调用权限,包括S3,AWS CodeBuild,AWS CloudFormation,IAM等。点击创建角色到IAM界面选择相对应的策略创建。
创建好后画面回到Pipeline,IAM创建好的Role已经显示在里面。
点击下一步。
3.2.5 审核后创建管道。
管道创建好后会自动运行,现有的从GitHub软件工程源代码抓取工程,打包Docker镜像并推送到ECR上。界面上显示如图
3.2.6 添加Deploy阶段CloudFormation需要的模版源以及配置Deploy阶段
点击编辑,点击Source阶段右上角的画笔图标
可以看到AWS CodePipeline的编辑界面在南北纵向和东西横向都可以添加
在GitHub这个Source右侧,点击添加操作,选择源,操作名称Template,选择S3,输入创建好的S3桶的地址
画面往下拉,注意在输出项目这里,输入Template。
Pipeline中各阶段的传递需要制定南北向的输入输出,即Source阶段S3源的输出Template,在Deploy阶段用输入Template来衔接。
点击更新。
点击Build阶段下面的添加阶段,画面右侧选择部署,选择AWS CloudFormation
操作模式选择创建或更新堆栈,输入创建的堆栈名称,模版这里输入Template::templates/service.yaml,也就是对应的输入是S3源桶中templates.zip里的service.yaml文件。功能选择CAPABILITY_NAMED_IAM。
同样需要创建一个Role,允许AWS CloudFormation调用包括IAM,ECS,ECR在内的AWS服务。
在IAM界面创建好后选择Role。
高级这里点开
在参数覆盖这里输入CloudFormation需要传入的参数,其中的固定参数也可以在S3的service.yaml中直接定义。
Tag是Build阶段传出的Docker镜像Tag使用的值,传入CloudFormation中用于建立Task Definition的Container时从ECR拉取对应版本的Docker镜像。
DesiredCount,即想要在ECS的Service中建立的Task的数量。
Cluster,即建立好的宿主机集群的名称。
TargetGroup,即建立好的宿主机集群的应用负载均衡器的ARN。
Repository,即建立好的ECR的镜像仓库名称。
输入项目这里输入Build阶段和S3模版源的输出。
点击添加操作。
保存管道更改。
4. 运行以及模拟版本更新
4.1 运行
访问负载均衡器的DNS地址来确认目前服务已经运行正常。
4.2 模拟版本更新
4.2.1 修改代码
在开发本地更新代码,示例中在src/index.php加入一行文字
<h1 style="color:FF7F00;">Amazon ECS Awesome!</h1>
4.2.2 提交新版本后查看AWS CodePipeline各阶段触发
4.2.3 刷新服务来确认新修改的部分已经发布
如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案 | 亚马逊AWS官方博客
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/297122.html