AWS 为开发者提供了 CodeCommit -> CodeBuild -> CodeDeploy 三个服务分别用于管理应用的代码库、构建、部署三个环节,并使用 CodePipline 编排流水线,以及使用 CodeStar 以快速构建模板项目。

AWS 上的流水线

CodeCommit 是一个私有的 git 代码版本管理库,CodeBuild 是一个基于 Docker 的构建环境,可以用一个叫buildspec.yml的 Yaml 配置文件定义构建规则(其实跟 Bash 脚本没啥区别),CodePipeline 是用于串联各个 Stage,这些都没啥新鲜的,对 AWS 而言,值得一书的恐怕还属 CodeDeploy。

CodeDeploy 介绍

CodeDeploy 在产品生命周期中掌管部署环节,支持 EC2 和 Lambda,亮点是和 AWS 其他服务高度集成,提供零宕机部署(包括蓝绿部署)。CodeDeploy 的规则定义起来比较简单,还可以和 Puppet/Chef 集成,但是需要对 AWS 的基础服务比如 EC2、ASG、ELB、S3 比较了解,上手难度并不大。本文主要解释基于 EC2 的 CodeDeploy 使用。

概念解释

AWS CodeDedeploy 定义了一些资源名称:

  • Application: 一个应用,也对应项目里一个 Project,一般对应一个代码仓库,包含多个环境。可以定义多个Deployment Groups
  • Deployment Groups: 对应应用的一个环境,包含了 instance 选区规则(Tag/ASG)、ELB、触发规则、Rollback 策略、权限(Role)以及 Deployment Configuration
  • Deployment Configuration: 部署策略,有 AllAtOnce、HalfAtATime、OneAtATime 三种默认策略,也支持自己定制,即指定在部署过程中一个 Deployment Groups 至少有多少个(百分比)的 instance 要在服务中。
  • Revision:一个新版本及为一个 Revision,需要提供 Repo(S3/Github)、Deployment Configuration、Rollback 策略等信息。

触发

CodeDeploy 的对象可以来自 S3 或者 Github,和所有的 AWS 资源对象操作一样,Trigger 方式可以选择 Console、cli、或是 sdk。

手动触发

触发相关的设置在 Deployment Groups 中,选择Deploy new revision,这里有两个可选方式:

  • S3 object + ETag: 被部署的文件必须被打包为一个文件(.zip或是 .tar)并上传到 S3 上,ETag 是该文件的一个哈希,会随文件变更改变,因此 Revision 里面实际上带了文件位置和版本号两个信息。
  • Github repository + commit ID: 与 S3 一样,信息需要定位到 Repo + 版本号,不同的是 Github 不需要把部署文件和部署脚本一起打包,另外第一次使用这个功能需要 Github 授权给 AWS CodeDeploy。

命令行 Deploy to S3 触发

AWS CLI 有一个 Deploy 的 namespace 可以用来触发 Application Deploy,对于 S3 参数如下:

aws deploy register-application-revision --application-name DemoApp --s3-location bundleType=tar,eTag=0d088076b9baa9bd71369367119e6b33,bucket=yidong-codedeploy,key=demoRevision.tar

Github 如下:

aws deploy register-application-revision —application-name DemoApp —github-location commitID=<value>,repository=adu-21/aws-codedeploy

如果被部署文件在本地而还没有提交到 S3 可以使用 aws deploy publish一键打包、上传、发布:

aws deploy push --application-name DemoApp --ignore-hidden-files --s3-location s3://yidong-codedeploy/newDemoRevision.zip --source .

Github 提交自动触发

Github 的集成可以做到部署文件提交到 Github 上就有一个 Webhook 到 CodeDeploy,并 Pull 最新版代码到 instance 上,需要给 CodeDeploy 配置 Github 账户 repo_deployment权限的 access token,并在 Repo 的 Services 中加入 AWS CodeDeploy 和 Github Auto-deployment 两个服务,具体可见:https://github.com/ADU-21/aws-codedeploy/settings/installations

执行

Deploy 执行的逻辑写在被部署文件根目录的一个 appspec.yml文件中,参见:https://github.com/ADU-21/aws-codedeploy/blob/master/appspec.yml:

version: 0.0                              # 版本号
os: linux                                 # 操作系统,只有 linux 和 windows 两个可选项

files:                                    # 定义某个本地文件拷贝到目标服务器的某个地址
  - source: files/index.html
    destination: /var/www/html

permissions:                              # 目标服务器上文件权限
  - object: /var/www/html
    pattern: index.html
    owner: apache
    group: apache
    mode: 644
    type:
      - file

hooks:                                     # 定义部署前后的一系列流程,通常调用本地完成
  BeforeInstall:
    - location: scripts/webserver-stop.sh
    - location: scripts/delete-old-index.sh
  AfterInstall:
    - location: scripts/sleep.sh
    - location: scripts/webserver-start.sh

对于 Hook 模块,有 ELB 的和没有 ELB 的有以下可选子模块:

图片来自:官方文档

蓝绿部署

AWS CodeDeploy 提供配置简单的 Blue/Green Deploy 服务,只需要配置 ELB 和 ASG 就可以完成自动创建新环境、Switch ELB、Terminate 旧环境几个步骤(如下图),完整步骤详见官方博客

图片来自:Performing Blue/Green Deployments with AWS CodeDeploy and Auto Scaling Groups

后记

今年 AWS 发布财报营收已经被微软超越。亚马逊的产品不得不说性能稳定性强大,但是易用性和商业模式上仍不及国内阿里、腾讯的产品,甚至不如 Rancher、Hashicorp 这样一些小公司的产品简洁、易上手。过去的一年在各种 PaaS 的竞争中 AWS 逐渐面临被 IaaS 化的命运,投资数年的 Serverless 因为它的不稳定、不成熟和平台绑定,在过去的几年中鲜有公司真正涉足,大多在观望状态。就我个人的使用体验而言,Serverless 的架构在较复杂的业务场景下对架构会带来非常大的挑战,资费优势也被 AWS 抖机灵的收费方式蚕食殆尽,17 年 AWS 收购 Cloud9 及迅速提升 Developer Tools 板块服务的行为就是想要补足 PaaS 这块短板。

我一直觉得像 FLAG(Facebook,LinkedIn,Amazon,Google)这种大公司,在如此体量的前提下还面临大量的服务更新和创新需求,还要求内部协作和资源共享,在多年的摸索中已经有了一套很好用的内部工具链,做 PaaS 只取决于你要如何以及以何种方式把这些工具公开出来。互联网的普及越来越广,企业越来越需要平台来支撑可持续、快速的迭代能力,大企业基于开源项目自建平台,小公司就向大公司租用 PaaS 服务。对讲求效率的小公司而言,一切非业务核心的技术能买则买,能外包就外包,能花钱的解决的问题,决不要花时间。

PaaS 仍然是很有潜力的一片蓝海,今年可以看到以阿里云效为代表的 DevOps 平台已经在发力,未来必然可以看到更加成熟的产品。