如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

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.方案架构

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

流程如下:

  1. 开发者将一个新版本的代码工程提交到GitHub
  2. Pipeline的Source阶段,检测到指定GitHub的repo有新版本的更新,从GitHub上拉取代码工程,开启已设定好的CICD Pipeline
  3. Pipeline的Build阶段,AWS CodeBuild将新版本的代码工程打包为Docker镜像
  4. AWS CodeBuild将打包好的镜像推送到Amazon ECR
  5. Pipeline的Deploy阶段,AWS CodePipeline触发AWS CloudFormation,其定义了Amazon ECS的Task definition和service
  6. AWS CloudFormation创建新版本的Task definition关联到新版本的Docker镜像,并更新Service
  7. 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端口

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

选择对应的子网

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

新建安全组,端口80,并新建目标组

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

注册目标此时不选择,ECS创建服务时会注册集群和对应端口进来。

下一步审核后创建。

3.1.3 ECS宿主机集群

在ECS的界面下,创建集群

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

实例配置保持默认或根据情况自行选择,示例中保持默认。

联网配置,选择创建好的VPC,子网,创建Role允许宿主机上的ECS代理调用ECS服务的API。

创建后画面下面会显示集群信息

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

集群一览会显示

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

修改ECS宿主机集群的安全组,inbound源设置为建好的应用负载均衡器的安全组ID

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

3.1.4 ECR镜像仓库创建

创建一个用于Build阶段上传存放软件工程Docker镜像的镜像仓库

ECS界面下,创建存储库,创建好后如下

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

3.1.5 S3桶创建

创建一个S3桶用来存放Deploy阶段CloudFormation使用的脚本模版,创建桶时选择和以上服务同一Region,并且打开桶的版本控制。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

将CloudFormation模版压缩zip后上传到桶中。

示例中将模版文件service.yaml放在templates文件夹后压缩为templates.zip。

service.yaml如下,注意缩进

Parameters:
Tag:
Type: String
Default: latest
DesiredCount:
Type: Number
Default: 0
TargetGroup:
Type: String
Cluster:
Type: String
Repository:
Type: String
Resources:
ECSServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument: |
{
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": [ "ecs.amazonaws.com" ]},
"Action": [ "sts:AssumeRole" ]
}]
}
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource: "*"
Effect: Allow
Action:
- ec2:*
- elasticloadbalancing:*
Service:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
Role: !Ref ECSServiceRole
DesiredCount: !Ref DesiredCount
TaskDefinition: !Ref TaskDefinition
LoadBalancers:
- ContainerName: simple-app
ContainerPort: 80
TargetGroupArn: !Ref TargetGroup
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Sub ${AWS::StackName}-simple-app
ContainerDefinitions:
- Name: simple-app
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Repository}:${Tag}
EntryPoint:
- /usr/sbin/apache2
- -D
- FOREGROUND
Essential: true
Memory: 128
MountPoints:
- SourceVolume: my-vol
ContainerPath: /var/www/my-vol
PortMappings:
- ContainerPort: 80
Environment:
- Name: Tag
Value: !Ref Tag
- Name: busybox
Image: busybox
EntryPoint:
- sh
- -c
Essential: false
Memory: 128
VolumesFrom:
- SourceContainer: simple-app
Command:
- /bin/sh -c "while true; do /bin/date > /var/www/my-vol/date; sleep 1; done"
Volumes:
- Name: my-vol

到此基础设施部分的搭建工作结束。

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,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

在AWS CodePipeline界面点击创建管道Pipeline,可以看到画面左侧一个基本流程,从源,到生成Build,到部署Deploy,到角色等配置。实际应用中用户可以随实际需要,或随着CICD流程的由简入繁在创建后编辑加入新的阶段或操作。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

点击下一步。

3.2.1 Source阶段配置

源提供商下拉菜单选择GitHub,

点击连接到GitHub来授权访问权,来允许AWS CodePipeline从GitHub上获取软件工程源内容,认证后选择GitHub上软件工程所在位置和分支

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

此次实例使用的Demo软件工程可以从以下链接Fork:

https://github.com/awslabs/ecs-demo-php-simple-app

点击下一步。

3.2.2 Build阶段配置

AWS CodePipeline在Build阶段支持包括AWS CodeBuild,Jenkins在内的引擎,此方案选用AWS 托管的CodeBuild服务

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

选择新建构建项目

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

选择AWS CodeBuild托管的镜像,支持Ubuntu系统,运行时支持包括Java,Python,Go语言,Node.js,Docker在内的众多选择,此次方案使用Docker。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

构建规范这里选择使用buildspec.yml,里面预定了AWS CodeBuild在Build生命周期中要执行的动作,如login到ECR,打包Docker镜像,给Docker镜像打tag,上传Docker镜像到已login的ECR镜像仓库。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

Buildspec.yml放在GitHub软件工程源代码目录中,如果复制粘贴的话注意yaml文件的缩进

version: 0.2
phases:
pre_build:
commands:
- $(aws ecr get-login)
- TAG="$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)"
build:
commands:
-    docker build --tag "替换创建好的ECR镜像仓库的URI:${TAG}" .
post_build:
commands:
- docker push "替换创建好的ECR镜像仓库的URI:${TAG}"
- printf '{"tag":"%s"}' $TAG > build.json
artifacts:
files: build.json

选择Role

新建一个Role,这个Role允许AWS CodeBuild来调用相关的AWS服务,此方案中需要调用包括S3,ECR,CloudWatch在内的服务。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

*默认创建的Role不具备对ECR的权限,需要在保存构建项目后,到IAM找到新创建的Role,编辑添加对ECR的权限否则后面Pipeline执行到Build时会报错。

保存构建项目。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

点击下一步。

3.2.3 Deploy

AWS CodePipeline部署阶段支持包括AWS CloudFormation,AWS CodeDeploy,AWS Elastic Beanstalk在内的服务提供商,此方案选用AWS CloudFormation来部署ECS容器服务。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

这里暂时选择无部署,等Pipeline创建好后,编辑引入Deploy的CloudFormation模版源,再进行配置。

点击下一步。

3.2.4 角色

配置AWS CodePipeline对AWS服务的调用权限,包括S3,AWS CodeBuild,AWS CloudFormation,IAM等。点击创建角色到IAM界面选择相对应的策略创建。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

创建好后画面回到Pipeline,IAM创建好的Role已经显示在里面。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

点击下一步。

3.2.5 审核后创建管道。

管道创建好后会自动运行,现有的从GitHub软件工程源代码抓取工程,打包Docker镜像并推送到ECR上。界面上显示如图

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

3.2.6 添加Deploy阶段CloudFormation需要的模版源以及配置Deploy阶段

点击编辑,点击Source阶段右上角的画笔图标

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

可以看到AWS CodePipeline的编辑界面在南北纵向和东西横向都可以添加

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

在GitHub这个Source右侧,点击添加操作,选择源,操作名称Template,选择S3,输入创建好的S3桶的地址

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

画面往下拉,注意在输出项目这里,输入Template。

Pipeline中各阶段的传递需要制定南北向的输入输出,即Source阶段S3源的输出Template,在Deploy阶段用输入Template来衔接。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

点击更新。

点击Build阶段下面的添加阶段,画面右侧选择部署,选择AWS CloudFormation

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

操作模式选择创建或更新堆栈,输入创建的堆栈名称,模版这里输入Template::templates/service.yaml,也就是对应的输入是S3源桶中templates.zip里的service.yaml文件。功能选择CAPABILITY_NAMED_IAM。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

同样需要创建一个Role,允许AWS CloudFormation调用包括IAM,ECS,ECR在内的AWS服务。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

在IAM界面创建好后选择Role。

高级这里点开

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

在参数覆盖这里输入CloudFormation需要传入的参数,其中的固定参数也可以在S3的service.yaml中直接定义。

{
"Tag" : { "Fn::GetParam" : [ "MyAppBuild", "build.json", "tag" ] },
"DesiredCount": "2",
"Cluster": "CICD-DEMO-CLUSTER-01",
"TargetGroup": "arn:aws:elasticloadbalancing:us-east-2:305890642658:targetgroup/CICD-DEMO-TG-01/b7649674ee8ab97b",
"Repository": "cicd-demo-ecr-01"
}

Tag是Build阶段传出的Docker镜像Tag使用的值,传入CloudFormation中用于建立Task Definition的Container时从ECR拉取对应版本的Docker镜像。

DesiredCount,即想要在ECS的Service中建立的Task的数量。

Cluster,即建立好的宿主机集群的名称。

TargetGroup,即建立好的宿主机集群的应用负载均衡器的ARN。

Repository,即建立好的ECR的镜像仓库名称。

 

输入项目这里输入Build阶段和S3模版源的输出。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

点击添加操作。

保存管道更改。

4. 运行以及模拟版本更新

4.1   运行

访问负载均衡器的DNS地址来确认目前服务已经运行正常。

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

4.2   模拟版本更新

4.2.1 修改代码

在开发本地更新代码,示例中在src/index.php加入一行文字

<h1 style="color:FF7F00;">Amazon ECS Awesome!</h1>

4.2.2 提交新版本后查看AWS CodePipeline各阶段触发

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

4.2.3 刷新服务来确认新修改的部分已经发布

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案

如何使用AWS CodePipeline,AWS CodeBuild与AWS CloudFormation实现Amazon ECS上的持续集成持续部署解决方案 | 亚马逊AWS官方博客

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/297122.html

(0)
上一篇 2023年8月29日 18:07
下一篇 2023年8月29日 18:15

相关推荐

发表回复

登录后才能评论