cicd 最佳实践
日常运维发布场景:
- 运维负责线上环境和应用部署
- 有一百多个或更多的基于不同开发语言进行的项目
- 对接前端后端测试等多个团队
- 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, 分支, 目标环境 然后发布;
难点
- 依赖集中式构建环境, jenkins 机器上环境越加复杂
- 运维深度参与, 打包阶段需要与研发多轮沟通调试
- jenkins 的插件体系陈旧, 扩展性较差
新的部署发布设计
基础原则
- 开发测试环境的版本发布由开发人员控制
- 生产环境的版本发布由运维人员控制
ci 部分
主要日常难点
- 仓库权限, 经常账号没有权限, 多个账号不知道应该使用哪一个
- 编译构建, 工具不对, 工具版本不对, 依赖缺失, 环境变量或构建参数冲突
解决办法: 将 CI 部分还回去, 让最了解这部分的开发人员来做;
运维这里只接收最终交付物, 不再是源代码;
最终交付物的形式可以是: docker 镜像, 二进制文件, tar 包
运维可以辅助开发人员进行构建, 如提供服务器, maven 仓库, 编写 pipeline 流水线模板文件等
推荐的构建打包方式
- github Actions
- gitlab workflows
- jenkins pipeline
交付物
- 统一交付为镜像, 提供仓库地址和 tag
- 如果是二进制文件或 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 更合适