基于阿里云容器的 CI/CD 落地实践


基于阿里云容器的 CI/CD 落地实践文章插图
背景大家好 , 笔者所在的团队当前面临落地公司业务数字化转型的重大任务 。 我们面临的主要研发挑战是如何快速得迭代出不断新增的开发需求 , 由于没有太多历史包袱 , 团队选择的技术栈也是相对成熟与流行的 , 比如我负责的Devops主要是基于阿里云ACK容器以及Jenkins2.0+进行搭建实施 。
阿里云ACK容器也是基于K8S1.16.9封装的云服务 , 我们选择的是托管版本 , 即master节点托管于阿里云 , 我们只负责worker节点集群的运维与管理 。 这样做的好处是使团队力量尽可能得集中在业务层面 , 基础设施层面的运维工作尽量服务化 。 选择Jenkins2.0有诸多好处 , 比如Jenkins是经典的CI实施工具平台 , 开发测试多数熟悉这种使用方式 , 无需再次学习 。 2.0版本以后 , 引入了声明式的Jenkinsfile语法 , 这种流水线编排格式与基于声明式API的K8S能够更天然地集成 , 并且Jenkins生态圈的plugin十分丰富 , 基本可以通过配置方式满足团队构建多语言多项目CICD任务的使用场景 。
?
核心问题目前实施CICD的业务 , 基本都要解决以下核心问题 。
?

  • 交付物是什么?
  • 部署环境有哪些?
  • 环境配置信息是什么?
  • 如何自动化地执行构建,部署任务?
  • 如果构建 , 部署任务执行失败 , 或者部署环境的应用运行失败 , 如何感知故障的发生?
交付物定义与结构交付物对象是在整个CICD流程中需要最先确定的实体 , 是开发跟devops之间交互的对接物 。 开发与devops一同参与交付物实体的定义 , 再由devops针对定义提供交付物的通用模版 。
?
  • 交付物定义
团队对于交付物的定义是基于dockerfile生成的微服务镜像 。
devops提供了基于阿里云容器镜像服务的私有仓库来存放 , 如图:
基于阿里云容器的 CI/CD 落地实践文章插图
?
开发基于dockerfile提供镜像打包定义 , 我们以java应用为例 , 镜像内容主要包括基于openjdk基础镜像的工作目录定以及指定启动cmd , 示例代码如下:
FROM openjdk:11.0.8WORKDIR /home/demoCOPY target/index-0.0.1-SNAPSHOT.jar app.jarENTRYPOINT ["java","-jar","app.jar"]
  • 交付物结构
每个应用部署交付物都归档在一个独立的镜像仓库 , 镜像仓库命名规范为项目名称.应用服务名称,镜像tag的命名规范里应包含每次构建物里所包含的代码变更内容 , 以latest commit id来表示 , 以及构建发生的时间信息 , 以yyyymmddd-hhmm格式表示时间戳 , 示例如图:
基于阿里云容器的 CI/CD 落地实践文章插图
?
交付物镜像应是包含了除了环境配置信息以外的应用部署的全部信息的实体 。 以java应用为例 , 该交付物是基于openjdk的jar包的镜像实体 。 环境配置信息可以由环境变量传递并改写 。
?
部署环境与配置
  • 部署环境
CICD理念解决的核心问题之一是在如何在多环境下部署同一交付物 。 典型的部署环境主要有4种:
  • dev开发环境
交付物生成的环境 。 在开发环境内 , 交付物第一次生成 , 需要经过必要的单元测试通过率以及代码安全性检查等步骤 , 该环境的交付物是可提测的部署物 。
  • test测试环境
交付物开始集成测试以及回归测试的环境 。 该环境的交付物是可上生产的部署物 。
  • stage预发布环境
预发布环境的使用场景会依据需求而有所不同 。 有些公司会将预发布环境用作demo环境作为poc功能展示;有些公司会在预发布环境中进行流量压力测试 , 确保上生产之前的服务负载与资源配置相匹配;有些公司做蓝绿发布或者A/B测试时 , 则会利用stage环境来做流量切换 。 无论stage环境如何被使用 , stage部署环境都需与生产部署环境配置保持一致 。
  • prod生产环境
生产发布环境是交付物最终运行环境 , 对用户提供服务 。
?
  • 环境配置
环境配置信息是CICD过程中 , 独立与交付物 , 但依赖于部署环境的一系列环境变量信息 。 基于K8S集群部署时 , 实现的主要方式是ConfigMap以及Secret资源对象 。
?
构建自动化我们有了Dockerfile来描述交付物的定义 , 简单来说只要docker build 然后docker push到私有镜像仓库就完成了构建 。 基于Jenkins搭建自动化的构建任务就是将这个过程自动化 。 后文实施部分会详细讲述 。