flowerwaiter 2019-03-06 02:43:25 浏览 97 评论 0
系统研发与运维
测试技术
架构
配置
持续集成
测试
持续交付
负载均衡
pipeline
单元测试
GitHub
摘要: 今天我们讨论 CI/CD, 即持续集成 (Continuous Integration) 与持续部署(Continuous Deployment), 这对于软件交付工程师或程序员来说非常重要. 首先我们说 CI - 持续集成, 这是为保证不同功能的开发人员所贡献的代码保持同步, 简单的说就是通过自动测试, 验证与反馈的方式实现程序员间的协同.
今天我们讨论 CI/CD, 即持续集成 (Continuous Integration) 与持续部署(Continuous Deployment), 这对于软件交付工程师或程序员来说非常重要.
首先我们说 CI - 持续集成, 这是为保证不同功能的开发人员所贡献的代码保持同步, 简单的说就是通过自动测试, 验证与反馈的方式实现程序员间的协同. 比如说开发团队将自己的代码库都放在 GitHub 上, 然后每个开发人员都 Fork 了一个副本在本地做开发测试, 最终我们希望将每个开发人员的代码段集成到主线 (Mainline) 中, 在这之前我们需要创建测试案例保证程序不仅可以单步运行, 也可以按照主线的逻辑运行不至于影响其他模块. 在持续集成的场景中, 开发人员可以不断拉测试案例来验证程序运行正常, 与主线兼容良好, 不会在发布时有巨大改动.
再说持续部署, 他将持续集成所编译的程序部署到环境中, 既然是持续部署, 就可以是某个特定项目的多个场景, 比如说临时环境 (Staging Environment), 测试环境(Testing Environment), 验收环境(Acceptance Environment) 最后是生产环境(Production Environment). 当然也包括了各个环境中的高可用, 负载均衡等场景.
持续集成和持续部署的工具有 AWS CodeBuild/CodeDeploy,Atlassian Bamboo 和 Jenkins. 我们拿一个 Python Flask web 应用来说, 首先我们需要做本地测试, 包括单元测试, 语义测试和功能测试. 通过了上述这些测试才能说明本地开发完成. 接下来我们需要拉取一些需求, 这些需求是要将本地代码段并入总线 (Master Branch) 前的一组测试案例, 包括安装, 测试案例执行, 语义分析, 单元测试和评论(为和项目组其他成员协同开发, 必须兼容评论功能).
并入总线后, 我们会继续测试包的安装, 构建, 创建缺陷, 创建版本, 推到'提交'阶段(提交阶段是持续集成和持续部署的分水岭). 进入部署阶段, 工具会从'提交'库中获取安装包, 继续在临时环境测试, 部署场景验证, 负载均衡测试, 并发连接测试, 应用安装, 验证和提交.
在临时环境有测试人员, 甚至会有最终用户, 完成全部功能点的测试之后会提交进入下一环境, 比如测试环境或验收环境. 上到临时环境之后, AWS 的 CodeBuild 可以模拟负载均衡环境来验证程序对环境的适应性.
我们的 Python Flask Web 应用程序也非常简单, 只是一个调用 REST API 的安装程序.
我们在 CodeBuild 中创建一个项目:
输入项目名称, 必要的话, 可以添加注释.
接下来我们选择程序源, 我们的代码库存放在 GitHub 上, 用户名是 bundyfx 下的 flaskerino 数据库. 关于 Webhook, 在 GitHub 的代码库中不需要创建 Webhook, 通过 AWS CodeBuild 项目中的复选框会自动关联 GitHub 的代码库从而自动创建 Webhook.
接下来可以选择运行环境, 包括选择 CodeBuild 的镜像还是自定义 Docker 镜像, 操作系统, 编译环境和版本等等.
如果最后选择使用 buildspec.YAML 来作为 Build 的配置文件, 以下是此 YAML 文件的样式:
在这个 YAML 文件中, 我们可以看到 CodeBuild 分为两个阶段(Phase): 安装阶段和预构建阶段. 在安装阶段, 首先执行的是更新 pip(对于不熟悉 python 开发的朋友, 这里普及一下, pip 是 Python 包管理工具, 该工具提供了对 Python 包的查找, 下载, 安装, 卸载的功能); 然后是安装根目录下即 setup.py 中定义的所有安装包, 即 flask 和 pylint
预构建阶段执行的两个命令, 先是找到所有 *.py 的文件, 然后对其语义进行检查(即 pylint,python linting); 然后在对此项目做单元测试. 之后我们定义了一个 artifacts: 语句, 意为将所有输出文件作为制品打包提交给下一阶段.
制品输出位置只有 Amazon S3 可选, 它相当于一个制品杂货店, CodeBuild 可以在这个杂货店里寄存和取出制品部署到各个环境中.
除了上述选项之外, 还有些高级选项, 包括选择加密 S3, 制品打包格式, 资源耗费(一般情况 3GB,2vCPU 绰绰有余了), 环境变量等等.
和其他的云产品一样, AWS CodeBuild 仅根据你的使用时间来收费. 创建完 CodeBuild 的项目之后, 由于我们之前勾选了自动关联 GitHub 的代码库变化. 在 GitHub 中我们也就自动创建了关联的 Webhook.
在 URL 的释义中标明了 pull_request and push, 意为当 GitHub 的此代码库收到推送更新时, CodeBuild 会自动对新版本进行构建(包括我们上面所说到的安装, 语义测试和单元测试); 当 CodeBuild 这边的项目执行完某个测试之后, 在 GitHub 的代码库也会收到一个 comments 标记测试情况.
在定义完应用名和部署组名后, 进入部署方式的选择, CodeDeploy 提供了两种部署方式, 分别是就地部署 (In-place deployment) 和迭代部署(Blue/green deployment). 前者意为直接用最新版本替换当前的运行程序, 期间可能有文件夹和目录结构的更新, CodeDeploy 会自动将相关前端应用指向新的目录位置; 后者更适用于有负载均衡的生产场景, 比如当前程序有 60 个实例运行在负载均衡器下, 最新版本同样有这些实例. 程序可以在指定时间切换, 同时保留之前的版本, 以便在新版本运行故障时回切. 这里我们从生产出发, 选择迭代部署(Blue/Green Deployment)
在环境配置中, 建议选择复制自动定标组(Automatically copyAuto Scaling group), 意为将现行环境的资源分配情况复制到最新版本中并有自适应功能, 以保证迭代后对并发压力的应对能力.
在这个配置的下方我们可以看到当前正在运行的所有实例的 ID 列表以及当前是否启用了负载均衡, 这跟我们之后所要配置的迭代方案有密切关系.
在部署设置中, 迭代部署的默认配置是一次仅更新一个实例, 且立即切换客户端的访问流量到新实例, 对于旧实例在切换一小时后停止运行.
当然我们也可以修改这个默认配置, 建议是既然要立即切换客户端访问实例, 何不一次性替换掉所有的实例. 至于旧实例的保留时间, 看内部规定或外部法律, 这里不做推荐.
最后输入具有部署权限的账号名称, 点击 Create Application 即可完成预部署.
在我们上期讲 CodeBuild 的时候谈到了 Amazon S3 制品库, 这里我们也可以根据提示直接将 S3 中的制品位置输入到脚本中完成部署.
值得一提的是, 通过 CodeDeploy, 不仅可以将程序部署在 AWS 上, 还可以部署在本地环境中.
对于任何一个程序的开发, 有没有什么工具能够可视化地看到其处在哪一阶段呢? 这里就引出了本期的重点: CodePipeline 是一个持续提交服务(continuous delivery service), 可以方便地建模, 可视化, 自动部署目标软件, 更直观地控制软件发布的各个阶段.
因此理论上说, 通过 CodePipeline 可以将我们之前所创建的 Build 和 Application 关联起来. 我们先创建一个 Pipeline 试一下, 名字和我们之前创建的 build 和 application 一致.
接着我们选择代码库的位置, 跟之前一样, 我们选择 GitHub 上的位置.
在选择 Build 提供者时, 因为我们先前创建了项目, 这里选择 CodeBuild 的提供者以及对应的项目名称即可.
同样, 下一步时选择部署对象. 由于我们之前的部署提供者是 AWS 的 CodeDeploy, 选择这个提供者并选择之前创建的应用名和部署组名.
最后我们给刚创建的 AWS Pipeline 服务取个名字.
CodePipeline 就自动帮我们梳理了整个开发流程, 并自动开始运行.
运行到每一步, 我们都可以进入看到运行的每个细节, 比如 Build 的运行情况. 每一个阶段前的小三角箭头都可以继续下钻查看进一步的运行情况.
再比如 CodeDeploy 阶段, 我们可以中断任意正在运行的阶段; 查看每一个高可用下属实例的状态及客户流量信息.
除了按照 Code Pipeline 的向导部署各个阶段外, 我们还可以直接编辑当前的 Pipeline, 例如删掉某个阶段, 或添加某个自定义的新阶段.
可添加的阶段包括审批, 源码, 构建, 测试, 部署和激活. 在测试阶段通过之后, 我们可以考虑将代码部署到生产环境了. 这时候我们在之前创建的 Code Pipeline 中添加一个生产阶段.
在生产阶段的配置中, 我们需要将其指向到生产的部署组.
保存之后, Code Pipeline 就会自动进入蓝绿部署阶段.
在详情页可以查看当前阶段的部署详细报告.
运行完成后, 我们就可以考虑更新当前的版本了, 点击 Pipeline 下方的 Release Change 更新版本.
系统会提示最近的变更将覆盖原始代码, 是否据悉, 我们点击发布(Release).
这期的内容就到这里, 谢谢大家.
来源: https://yq.aliyun.com/articles/692460