AWS Global已经有一套成熟的DevOps解决方案,通过使用AWS CodeCommit 作为代码存储,AWS CodeBuild作为代码构建,AWS CodePipeline作为持续集成,AWS CodeDeploy作为自动部署,实现CI/CD的整个过程。
目前在中国区,只有CodeDeploy和CodeBuild服务落地,因此,我们使用以下方式实现一套CI/CD的过程。架构如下所示:
说明:
- 1)代码存放在Github中
- 2)代码更新后触发Jenkins,Jenkins调用CodeBuild插件,执行构建
- 3)CodeBuild会将构建后的代码上传至S3上
- 4)构建完成之后,Jenkins收到CodeBuild的返回后,继续调用CodeDeploy插件,执行应用程序部署
- 5)CodeDeploy依赖每个应用程序服务器上安装的CodeDeploy Agent从S3下载构建后的代码,执行部署。
- 6)同时,借助SNS和CloudWatch监控部署的状态。
2.服务介绍
2.1. CodeBuild介绍
AWS CodeBuild是一个完全托管的构建服务,可以编译源代码,运行单元测试,并生产部署就绪的工作。
其输入是源代码存放位置,源码可支持S3, Github, Bitbucket, Github Enterprise。
中间过程是无服务器的构建的环境,支持的构建环境有Amazon Linux 2, Ubuntu, Docker, 这些环境所启动的资源对用户均是不可见的,面向用户即是Serverless, 因此用户便免于管理构建服务器等环境。
如何操作实际构建的命令呢?则是通过AWS所规定的一个文件 buildspec.yml,按照AWS规范的格式将构建的命令编写入buildspec.yml文件中,将该文件放入到源代码根路径下,AWS底层在进行构建时,拉取源代码后会自动寻找该文件,执行该文件定义的方式进行构建。
输出是构建后的文件,可以存储在S3上,如果是Docker, 也也可以将映像推送到ECR中。
2.2. CodeDeploy介绍
AWS CodeDeploy是一项部署服务, 在代码打包完成之后,将代码传到服务器上,重启应用程序以让新的代码提供服务的过程。
CodeDeploy 不仅仅能够支持AWS EC2的虚拟机上应用程序的部署,也支持AWS Lambda和本地实例的部署。
在应用程序服务器上,需要安装运行CodeDeploy Agent,我们将部署的方式,比如从何处拉取代码,拉取后的代码需要放置的路径,然后如何重启应用程序,如何验证部署后的测试等,这些部署方式按照AWS的规则,写入到指定文件appspec.yml中,该文件放置在源码的根路径下, Agent会自动读取该文件,执行部署的规则。
同时,CodeDeploy本身可以与AutoScaling, ELB 集成,实现滚动或者蓝绿发布。
CodeDeploy的组件
CodeDeploy组件相对于CodeBuild来说较多,因此我们先来认识一下CodeDeploy有哪些组件,下图为CodeDeploy组件构成:
从外到内,组件为:
应用程序:只是一个名称或容器, AWS CodeDeploy 使用此名称或容器来确保在部署期间引用正确的修订、部署配置和部署组。
部署:部署是指在一个或多个实例上安装内容的过程以及该过程中涉及的组件, 此内容可包含代码、Web 和配置文件、可执行文件、程序包、脚本等。AWS CodeDeploy 根据您指定的配置规则来部署源存储库中存储的内容。
部署组:部署组是一组作为部署目标的单个实例。部署组中包含单独标记的实例:
就地部署: 停止部署组中每个实例上的应用程序,安装最新的应用程序修订版,然后启动和验证应用程序的新版本。
蓝/绿部署: AWS会启动新的虚拟机实例,安装新版本的应用程序,再替换原来的虚拟机,终止原来的虚拟机。
修订: 修订包含 AWS CodeDeploy 将部署到您实例的源文件版本或者 AWS CodeDeploy 将在您实例上运行的脚本。
appsec.yml文件: (与你的代码打包在一起)告知codedeploy代码需要放置的路径,重启应用程序的方式等来进行部署操作。
部署配置: 部署配置是 AWS CodeDeploy 在部署期间使用的一组规则,指定了两规则:
1)在部署期间必须可用的正常EC2实例的数量(百分比或者数字),决定了部署的速率
2)部署成功条件和失败条件,即多少个实例部署成功则认为整个部署是成功的
Codedeploy Agent:AWS CodeDeploy的软件包,安装在需要进行部署的实例上,控制实例进行部署操作。
3.搭建部署
基于以上所述的架构,我们来搭建一个简易的环境,该环境在AWS下有两个EC2,运行Tomcat程序,EC2前端使用ALB做负载均衡,在GitHub上有一个Java的源代码,输入“Hello World“。
3.1. 部署前准备
1) AWS用户及权限
用户:需要一个用户的Access Key和Security Key,具有”AWSCodeDployFullAccess”, “CodeBuildFullAccess”和S3上传的权限,该AK/SK将配置在Jenkins里面,使Jenkins可以调用CodeBuild和CodeDeploy。
角色:创建一个角色给EC2使用,该角色有 ”AWSCodeDeployRole“, “S3FullAccess”, “ElasticLoadbalaceFullAccess”的权限
2)Jenkins环境准备
安装Jenkins, 安装请参考Jenkins官方文档
安装AWS CodeBuild 和 AWS CodeDeploy插件:进入到Jenkins “系统管理” à”管理插件”, 找到插件“AWS CodeBuild Plugin” 和 “AWS CodeDeploy Plugin”插件,进行安装。
3)应用程序虚拟机环境
a) 准备一个ALB及后端挂载两个EC2实例(Amazon Linux 2),运行一个简单的Tomcat程序,模拟线上环境。
Tomcat安装请参考官方文档,此处不赘述,请将Tomcat安装在/opt/tomcat路径下,并配置好通过systemctl 启动/停止Tomcat
b) 绑定role
EC2需要绑定角色, 使得EC2能够有权限访问S3,拉取代码,及访问CodeDeploy服务,汇报部署状态。
c) 在运行应用程序的虚拟上,需要安装好CodeDeploy Agent, 以Linux系统为例,安装方式如下,如果使用其它系统,则参考AWS官方文档进行安装。
d) 为此两台EC2打上标签, key为”CodeDeploy”, value为”True”
e) 配置好EC2后,将EC2挂载至ALB后端,并通过健康检查,验证ALB endpoint,确认访问成功
4) S3存储桶
在相同区域中,创建一个存储桶,存放构建后的代码,此处demo存储桶名称为: aws-devops-demo
5) 测试代码
准备hello word测试代码,可以参考此Git
代码文件如下:
–buildspec.xml # CodeBuild使用该文件进行构建,该Demo代码中,指定了构建方式,使用mv test, mv package进行构建
–appspec.xml # CodeDeploy使用该文件进行部署,该Demo代码中,指定了部署方式,将war包放入到tomcat webapp下,以及stop/start tomcat方式
–scripts/* # 该文件为CodeDeploy使用,在进行部署的时候,通过该目录下的脚本进行tomcat的stop/start及测试
–pom.xml #该文件为mvn 打包方式
–src/* #该文件为java 源码
3.2. 开始搭建
3.2.1. 创建CodeBuild
1)在AWS控制面板上,创建构建项目, 源代码选择GitHub, 输入GitHub 地址” https://github.com/tianer1211/aws-devops-demo”
2)项目环境如下图所示,此Demo代码基于Ubuntu环境进行构建
3.2.2. 创建CodeDeploy
1)创建CodeDeploy应用程序, 选择平台”EC2/本地”
2)创建完成之后,进入到应用程序部署组,创建部署组, 部署组配置如下:
3.2.3. 配置Jenkins
1)配置CodeDeploy, 进入到Jenkins “Manage Jenkins” ⇨ “Configure System”下,将之前创建的AWS用户的Access key和Secret Key配置到CodeDeploy下面,如下图所示:
2)创建Jenkins item, 选择“Freestyle project”
3)添加Build,选择“AWS CodeBuild”
4)配置中间步骤
说明:
由于中国区服务的限制,在没有AWS CodePipeline的服务器情况下,CodeBuild只能将构建后的文件上传至S3上,而Jenkins CodeDeploy插件在执行部署时,是将Workspace的目录下内容打包,而不能直接引用S3已构建好的文件。因此可以通过一些方式在中间做一个过渡,此处模拟通过执行Shel命令,使用aws cli将CodeBuild打包后的文件先下载至Jenkins Workspace目录下。(基于此方式,jenkins安装的服务器上已装好aws cli,并配置好profile,使得jenkins服务器有权限从S3下载文件)
也可以通过其它方式调用,比如Jenkins 插件AWS Steps,提供丰富AWS 接口,包括S3,CodeDeploy,可以在Jenkins Pipeline中灵活调用。
添加”build step”,选择”Execute shell”
在command中,输入以下命令,如果存储桶名称及路径不同,则替换相应名称和路径,实际生产环境中,可以丰富该脚本,对执行结果做判断,验证是否下载成功。
/bin/aws s3 cp –recursive s3://aws-devops-demo/tomcat-app/ $WORKSPACE/
5)添加CodeDeploy
添加”post-build action”, 选择”Deploy an application to AWS CodeDeploy”
填写CodeDeploy的详细信息:
6)执行构建
配置完成之后,则可以执行构建
7)查看结果
除了在Jenkins面板中可以查看部署的过程状态,也可以在AWS CodeBuild和AWS CodeDeploy中查看构建的结果和部署的结果。