cicd 最佳实践

cicd 最佳实践

日常运维发布场景:

  1. 运维负责线上环境和应用部署
  2. 有一百多个或更多的基于不同开发语言进行的项目
  3. 对接前端后端测试等多个团队
  4. CICD 除了发版外, 其它依赖调整项也较多

常见困难

构建环境版本极多

  • java 有 jdk1.8, jdk15, 17,
  • go 有 1.21, 1.24 等
  • nodejs 有 14, 16, 17, 21, 并且附加 npm, pnpm, bun, yarn 等组合
  • 编译环境还有 centos7 和 ubuntu22 和 24 等

运行环境多

  • 项目 1,2,3 的生产环境
  • 项目 1,2,3 的开发环境
  • 项目 1,2,3 的测试环境
  • 项目 1,2,3 的 UAT 环境
  • 项目 1,2,3 的特定版本联调环境

部署环境复杂

  • eks 集群部署
  • 有本地 k8s 的部署
  • 有很多 docker-compose 部署的中间件
  • 二进制直接运行的服务

代码仓库多

  • github 多个组织, 每个组织下几十个仓库
  • 本地有 gitlib, 外部团队本地的 gitea

早期的发布模式

第一阶段: 人工打包 运维人员拉取代码, 构建, 上传部署

第二阶段: jenkins pipeline 选择 job 和环境后点击构建, 给各团队分配不同的相应环境的账号权限

第三阶段: jenkins + gitops 仓库 pipeline 流水线放置在统一的 git 仓库内集中管理; 选择 job, 分支, 目标环境 然后发布;

难点

  1. 依赖集中式构建环境, jenkins 机器上环境越加复杂
  2. 运维深度参与, 打包阶段需要与研发多轮沟通调试
  3. jenkins 的插件体系陈旧, 扩展性较差

新的部署发布设计

基础原则

  1. 开发测试环境的版本发布由开发人员控制
  2. 生产环境的版本发布由运维人员控制

ci 部分

主要日常难点

  1. 仓库权限, 经常账号没有权限, 多个账号不知道应该使用哪一个
  2. 编译构建, 工具不对, 工具版本不对, 依赖缺失, 环境变量或构建参数冲突

解决办法: 将 CI 部分还回去, 让最了解这部分的开发人员来做;

运维这里只接收最终交付物, 不再是源代码;

最终交付物的形式可以是: docker 镜像, 二进制文件, tar 包

运维可以辅助开发人员进行构建, 如提供服务器, maven 仓库, 编写 pipeline 流水线模板文件等

推荐的构建打包方式

  1. github Actions
  2. gitlab workflows
  3. jenkins pipeline

交付物

  1. 统一交付为镜像, 提供仓库地址和 tag
  2. 如果是二进制文件或 tar 包交付, 则上传到 s3, 提供 url 路径

其它事项: 如是否添加代码单元测试流程, 代码漏扫质量检查, 构建工具版本选择和升级等动作由开发人员决定;

CD 部分

推荐发布方式

场景: 几个小项目的开发环境

方式 1: github Actions 单独一个 workflows 进行环境发布, 直接由开发人员维护, 运维只提供如仓库权限集群权限等信息; 合并代码到 dev 分支后自动触发构建和发布流程;

方式 2: argocd 监听项目仓库的部署清单文件, 自动应用变更;

方式 3: jenkins pipeline + webhook 加入发布流程

场景: 几个小项目的生产环境

方式 1: argocd 监听项目仓库, 不自动同步, 需要手工确认后同步;

方式 2: jenkins pipeline 输入镜像 tag 或构建物 url 后选择环境发布;

方式 3: 开发人员向 gitops 仓库提交 pr, 运维合并后触发 workflows 或 argocd 监听同步;

场景: 大型项目的开发环境

第一次部署, 以 gitops 仓库为准, 从仓库内的 yaml 清单文件进行部署

第二次更新 1. 以 镜像仓库最新 tag 为准, argocd 监听仓库最新镜像, 2. 自动更新线上环境; 3. tag 信息可选是否写 gitops 仓库, 或人工定期合并;

场景: 大型项目的生产环境环境

方式 1: argocd 监听镜像版本办法

第一次部署, 以 gitops 仓库为准, 从仓库内的 yaml 清单文件进行部署。

第二次更新, 1. 以 镜像仓库最新 tag 为准, argocd 监听仓库最新镜像 2. 但不自动更新环境, 需要人工点击确认后发布 3. 新的线上 tag 信息定期人工或定时任务合并到 gitops 仓库中;

方式 2: 发布人员向 gitops 仓库提交 pr, 运维合并后 argocd 从仓库同步或 webhook 的方式;

我更看好方式 2 这种 gitops 仓库 + argocd 管理一个项目全部环境的方式

优点

  • 有人员审核才能合并 pr, 相当于点击了一次发布动作
  • 有发版记录, 谁提交的 pr 就是谁发起的版本更新
  • 方便回退
  • 新建项目时只需要使用 argocd cli 应用资源文件, 比较方便
  • 批量变更方便
  • 更符合 SRE 运维概念

注意事项

  • 密钥和关键地址信息不能放在仓库中

常见组合

方式 1: jenkins 打包 + 发布, pipeline 文件放置在项目仓库内

方式 2: jenkins 打包 + 发布, pipeline 文件放置在统一的 gitops 项目仓库内

方式 3: github Actions 打包 + 发布

方式 4: github Actions 打包, argocd 发布, 监听项目仓库

方式 5: github Actions 打包, jenkins 发布, pipeline 文件放置在项目仓库内

方式 6: github Actions 打包, argocd 发布, 监听 gitops 项目仓库

问: pipeline 和 workflows 和 资源清单文件放在哪里?

  • 几个小项目就直接放置在项目仓库中
  • 项目数量非常多时, 需要一个独立的仓库存放

问: 打包构建工具

  • 开发人员一般比较熟悉 github Actions, 或 gitliab ci 等方式
  • jenkins 开发人员一般都不怎么熟悉;

问: 发布工具

  • 在集群外部推的方式发布, 就用 jenkins
  • 在集群内部拉的方式方式, argocd 更合适
最后更新于