GitOps · CI/CD · 运维工程师

CI/CD 自动化
发布平台建设

主导建设统一 CI/CD 发布平台并演进到 GitOps 模式(Jenkins 管 CI + Argo CD 管 CD),实现全流程标准化、自动化、可审计,解决发版依赖人工、环境不一致、回滚慢的问题。

项目周期2024.06 – 2025.10
核心引擎Jenkins + Argo CD
环境双集群 · 四环境
我的角色整体设计主导
⚠️ 提示:本页面试问答与代码示例为基于项目技术栈整理的草稿,请逐条核对,确认是你真实做过、能讲清楚的内容后再用于面试。
📋项目概述
背景、目标与我的职责
项目背景

研发团队发版依赖人工操作、流程不规范、各环境差异大、发布风险高、周期长。本项目主导建设统一 CI/CD 自动化发布平台,把从代码提交到生产部署的全流程标准化、自动化,让发布可控、可追溯、可回滚。

我的职责
  • 设计 Jenkins 管 CI + Argo CD 管 CD 的 GitOps 流水线,Git 作为唯一可信源
  • 拆分代码仓与配置仓,Jenkins 写回配置仓 tag 触发 Argo CD 自动同步
  • 规划云上双 ACK 集群(非生产共享 + 生产独立),用 Argo CD 统一纳管
  • 基于 Helm 分环境 values 实现配置与镜像解耦,镜像一次构建多环境晋级
  • 引入 Argo Rollouts 实现金丝雀发布,基于 Prometheus 指标自动放量/回滚
  • 集成 Trivy 镜像扫描准入,对接钉钉实现生产手动同步审批与全节点通知
技术栈
JenkinsArgo CDArgo RolloutsDockerKubernetes 阿里云 ACKHelmGitLabHarbor TrivyPrometheusShell钉钉 API
🔀环境架构与 GitOps 流水线设计
Jenkins 管 CI、Argo CD 管 CD,云上多 K8s 环境如何串联
整体模式:从「推」到「拉」的 GitOps

传统模式是 Jenkins 直接 helm upgrade 把变更到集群,Jenkins 要持有所有集群凭证,风险高、难审计。本项目升级为 GitOps 拉模式:Jenkins 只负责 CI 并把镜像版本写回 Git 配置仓库,Argo CD 常驻集群内、监听配置仓库,主动拉取并同步变更。Git 仓库成为唯一可信源,集群状态始终向 Git 对齐。

两个仓库分工(GitOps 的基础)
  • 应用代码仓(app repo):放业务代码 + Dockerfile,Jenkins 监听它触发 CI。
  • 配置仓(config repo / GitOps repo):放 Helm Chart 和各环境 values,Argo CD 监听它。镜像版本(tag)就写在这里——改这里,Argo CD 才会动。
代码和配置分仓是 GitOps 的关键。好处:发布动作 = 改配置仓的一行 tag,留下 Git 记录;回滚 = revert 这个 commit。
环境架构:双 ACK 集群

非生产共享集群用 namespace 隔离 dev / test / staging,省成本;生产独立集群物理隔离保安全。一套 Argo CD 同时纳管两个集群,每个环境对应一个 Argo CD Application,指向配置仓里对应的 values 路径和目标集群。

① CI 阶段 · Jenkins(构建一次镜像)
git push 代码仓
单元测试
SonarQube 扫描
Trivy 镜像扫描
推送 Harbor
↓ Jenkins 不连集群,改去写 Git
② 衔接点 · Jenkins 更新配置仓的镜像 tag
yq 改 values 的 image.tag
git commit & push 配置仓
↓ Argo CD 检测到配置仓变化(自动 pull)
③ CD 阶段 · Argo CD(监听配置仓,同步到集群)
检测 Git 变更
渲染 Helm Chart
diff 对比集群现状
sync 同步
↓ 按 Application 分发到对应集群/namespace
④ 非生产共享集群(自动同步)
App: dev → ns dev
App: test → ns test
App: staging → ns staging
↓ 生产独立走
⑤ 生产独立集群(手动同步 + 钉钉审批)
App: prod → ns prod
manual sync 待审批
异常自愈 / 回滚
串联的关键:Git 是中枢

整条链路的衔接点在 Git 配置仓:Jenkins 写 tag → 配置仓变更 → Argo CD 拉取同步。环境的区分由 Argo CD 的 Application 定义(每个 App 绑定一份 values + 一个目标集群)。非生产 App 开自动同步、生产 App 设手动同步+审批,安全与效率兼顾。

⚙️核心能力详解
Jenkins CI + Argo CD GitOps 的完整实现过程
① CI 阶段:Jenkins 构建镜像 + 写回配置仓

关键变化:Jenkins 不再连集群部署。CI 跑完测试、扫描、构建、推 Harbor 后,最后一步是修改配置仓里对应环境 values 的镜像 tag 并 push。发布动作从「执行命令」变成「提交一次 Git」。

// Jenkinsfile —— 只做 CI,结尾写回配置仓触发 GitOps pipeline { agent any environment { HARBOR = 'harbor.xxx.com/myapp' APP = 'user-service' TAG = "${env.GIT_COMMIT.take(8)}" // commit短ID做镜像tag,唯一可追溯 } stages { stage('测试 & 扫描') { steps { sh 'mvn -q test' sh 'sonar-scanner' // 代码质量门禁 } } stage('构建并推送镜像') { steps { sh 'docker build -t $HARBOR/$APP:$TAG .' sh 'trivy image --severity HIGH,CRITICAL --exit-code 1 $HARBOR/$APP:$TAG' // 高危漏洞阻断 sh 'docker push $HARBOR/$APP:$TAG' } } // ===== 衔接点:算出目标环境,改配置仓tag并push ===== stage('更新配置仓(触发GitOps)') { steps { script { // 分支决定改哪个环境的values if (env.BRANCH_NAME == 'develop') { env.ENV = 'dev' } else if (env.BRANCH_NAME ==~ /release\/.*/) { env.ENV = 'staging' } else if (env.TAG_NAME ==~ /v.*/) { env.ENV = 'prod' } } withCredentials([usernamePassword(credentialsId: 'git-bot', usernameVariable: 'U', passwordVariable: 'P')]) { sh 'git clone https://$U:$P@git.xxx.com/myapp/config-repo.git cfg' dir('cfg') { // yq改对应环境values里的image.tag —— 这一行就是"发布" sh 'yq -i ".image.tag = strenv(TAG)" envs/$ENV/values.yaml' sh 'git commit -am "deploy $APP:$TAG to $ENV"' sh 'git push' // push后Argo CD自动感知 } } } } } post { success { sh './notify-dingtalk.sh ci-ok $APP $TAG $ENV' } failure { sh './notify-dingtalk.sh ci-fail $APP $TAG' } } }
面试强调:Jenkins全程不持有任何集群kubeconfig,凭证收敛到Argo CD,这是GitOps比传统推模式更安全的核心。
② CD 阶段:Argo CD Application 定义环境

每个环境一个 Argo CD Application,绑定「配置仓路径 + 目标集群 + 目标 namespace」。环境的区分全在这里,不在流水线里。非生产开自动同步,生产设手动同步。

# dev环境(非生产共享集群,自动同步) apiVersion: argoproj.io/v1alpha1 kind: Application metadata: { name: user-service-dev, namespace: argocd } spec: source: repoURL: https://git.xxx.com/myapp/config-repo.git path: envs/dev # 监听这个目录 targetRevision: main destination: server: https://nonprod-cluster # 指向非生产集群 namespace: dev syncPolicy: automated: { prune: true, selfHeal: true } # 自动同步+自愈 # prod环境(生产独立集群,手动同步——配合审批) spec: destination: server: https://prod-cluster # 指向生产独立集群 namespace: prod syncPolicy: {} # 不写automated = 手动同步
③ 自动同步 vs 手动同步(生产管控)
  • 非生产(自动):Jenkins一push,Argo CD几秒内检测到diff自动sync,开发自助、无需介入。
  • 生产(手动):Argo CD检测到diff后状态变OutOfSync但不动手,等运维在钉钉审批后,在Argo CD UI或CLI点sync才真正发布。
  • selfHeal自愈:有人手动改了集群里的资源(偏离Git),Argo CD会自动改回与Git一致,杜绝配置漂移。
# 生产手动同步(审批通过后执行) argocd app sync user-service-prod # 触发同步到生产集群 argocd app get user-service-prod # 查看同步与健康状态
④ 分环境 values:差异都收在配置仓

同一个 Helm Chart,配置仓里每个环境一份 values 覆盖差异。dev 最小资源、prod 高可用+弹性。镜像与配置彻底解耦,Jenkins 只改 tag 那一行。

# envs/dev/values.yaml(开发:最小资源) replicaCount: 1 resources: { requests: { cpu: 100m, memory: 256Mi } } ingress: { host: dev.myapp.com } # envs/prod/values.yaml(生产:高可用 + 弹性) replicaCount: 3 resources: { requests: { cpu: 500m, memory: 1Gi } } autoscaling: { enabled: true, maxReplicas: 10 } ingress: { host: www.myapp.com }
⑤ 回滚:revert 一个 commit

GitOps 的回滚极其干净——Git 是唯一可信源,回滚就是把配置仓回退到上一个 commit,Argo CD 自动把集群同步回旧状态。也可直接用 Argo CD 的 history 回滚。

# 方式一:Git回退(最符合GitOps理念) git revert HEAD && git push # Argo CD自动同步回旧版本 # 方式二:Argo CD直接回滚到历史版本 argocd app history user-service-prod # 查看部署历史 argocd app rollback user-service-prod 12 # 回滚到指定history ID
🚦发布策略
滚动 / 蓝绿 / 金丝雀,怎么选、怎么落地
三种策略对比
策略原理优点代价适用
滚动更新
Rolling
逐批替换旧 Pod,新旧并存过渡 不额外占资源,K8s 原生默认 新旧版本短暂共存;出问题影响面已铺开 日常发布、向后兼容的变更
蓝绿
Blue-Green
新版本(绿)整套起好,流量一次性切过去 秒级切换、秒级回滚,无新旧混跑 要双倍资源 不容忍新旧混跑、要快速回滚的核心系统
金丝雀
Canary
先放小比例流量给新版本,逐步加码 影响面可控,能用真实流量验证 配置复杂,需指标分析支撑 高风险变更、想用线上流量验证
本项目怎么用
  • 非生产 + 多数生产发布:滚动更新,配好 readiness 探针和 maxSurge/maxUnavailable,简单稳定。
  • 生产核心服务:金丝雀,借助 Argo Rollouts 按 10%→30%→60%→100% 逐步放量,每步自动看指标,异常自动回滚。
  • 需要瞬时切换的场景:蓝绿,整套新版本就绪后一次切流量,回滚就是把流量切回去。
滚动更新:参数是关键

K8s 默认策略,重点在两个参数控制替换节奏,配合探针避免「Pod 起来了但还没就绪就接流量」。

# Deployment 滚动更新参数 strategy: type: RollingUpdate rollingUpdate: maxSurge: 25% # 最多超出期望副本数25%(控制新增速度) maxUnavailable: 0 # 0=先起新的再停旧的,保证不掉容量 readinessProbe: # 就绪前不接流量,避免发布抖动 httpGet: { path: /health, port: 8080 } initialDelaySeconds: 10
金丝雀:用 Argo Rollouts 落地

原生 Deployment 做不了精细金丝雀,引入 Argo Rollouts(Argo 生态,和 Argo CD 天然搭配)。用 Rollout 资源替代 Deployment,定义放量步骤,每步暂停观察或由指标自动判断是否继续。

# Rollout —— 金丝雀逐步放量 apiVersion: argoproj.io/v1alpha1 kind: Rollout spec: strategy: canary: steps: - setWeight: 10 # 先给新版本10%流量 - pause: { duration: 5m } # 观察5分钟 - setWeight: 30 - analysis: # 自动分析:查Prometheus指标 templates: [{ templateName: success-rate }] - setWeight: 60 - pause: {} # 无duration=人工确认后继续 - setWeight: 100 # 全量
金丝雀自动判断:AnalysisTemplate

放量过程中,Argo Rollouts 查 Prometheus 指标(如成功率、P99 延迟),达标才继续放量,不达标自动回滚到旧版本——这是金丝雀真正的价值,不靠人盯。

# AnalysisTemplate —— 成功率低于95%则判定失败、自动回滚 kind: AnalysisTemplate spec: metrics: - name: success-rate successCondition: result[0] >= 0.95 # 成功率≥95%才通过 provider: prometheus: address: http://prometheus:9090 query: sum(rate(http_requests_total{code!~"5.."}[2m])) / sum(rate(http_requests_total[2m]))
面试落脚点:金丝雀的精髓不是"放10%流量",而是用真实流量的指标自动决策放量或回滚,把发布风险量化、自动化。
📈项目成果
数值请按实际填写
发布周期
大幅缩短
人工干预
↓ 减少
回滚时间
分钟级
发布可追溯
100%
建议替换为量化数字,如「发版从半天缩到 X 分钟」「回滚从 X 分钟缩到 1 分钟」,越具体越有说服力。
🎤面试项目介绍话术
约 50 秒口述脚本
💬 推荐话术 · 50秒版本
"我主导建设过一个统一的 CI/CD 自动化发布平台,并把它演进到了 GitOps 模式(停顿) 之前团队发版靠人工,流程不规范、环境差异大、风险高。我用 Jenkins 负责 CI——测试、扫描、构建镜像、推 Harbor, 然后 CD 交给 Argo CD:Jenkins 只把镜像版本写回 Git 配置仓,Argo CD 监听配置仓自动同步到集群, 这样 Git 成了唯一可信源,Jenkins 不持有集群凭证,更安全,回滚就是 revert 一个 commit。 环境上是双 ACK 集群,非生产共享、生产独立,Argo CD 统一纳管,生产设手动同步配合钉钉审批。 发布策略上,核心服务用 Argo Rollouts 做金丝雀,按比例放量、用 Prometheus 指标自动判断健康,不达标自动回滚。 整体把发布周期大幅缩短、人工干预减少,发布全程透明可追溯。"
面试常见问题
点击展开查看答题思路(请核对真实性)
Q1这个 CI/CD 平台和你简历里 GitOps 流水线、ACK 项目有什么区别?+

这个问题很可能被问,因为三处都涉及 CI/CD,要讲清侧重点不同:

  • 本项目:聚焦发布平台本身,并演进到 GitOps(Jenkins 管 CI + Argo CD 管 CD),亮点是 Git 为唯一可信源、发布策略(金丝雀/蓝绿)、审批与自愈。
  • ACK 项目:聚焦上云改造,CI/CD 只是其中一环,重点在容器化迁移和可观测。
  • 能讲出演进:从 Jenkins 直接推部署 → GitOps 拉模式,体现你对发布范式演进的理解。
关键:别让面试官觉得你"同一件事写了三遍"。强调本项目的差异化抓手是 GitOps + 发布策略 + 自愈,这是技术深度的体现。
Q2声明式 Pipeline 和脚本式 Pipeline 怎么选?+
  • 声明式:结构化、易读、有固定语法骨架(pipeline/stages/steps),团队协作和维护友好,大多数标准流水线用它。
  • 脚本式:本质是 Groovy,灵活度高,适合复杂逻辑、动态生成 stage 的场景。
  • 实践:主体用声明式保证规范统一,个别复杂逻辑用 script 块嵌入脚本式,两者可混用。
Q3生产发布失败了,怎么快速回滚?回滚要注意什么?+
  • GitOps 回滚(首选):把配置仓 revert 到上一个 commit 并 push,Argo CD 自动把集群同步回旧版本——回滚就是一次 Git 操作,干净可追溯。
  • Argo CD 回滚:也可用 argocd app rollback 直接回到历史部署版本。
  • 镜像版本管理:每次发布镜像 tag 唯一(带 commitID),回滚精确到具体版本。
  • 注意数据库:代码能回滚,但数据库 schema 变更不能简单回滚——要做向前兼容的迁移,这是回滚最大的坑。
  • 回滚后告警:回滚也要走通知,触发故障复盘。
加分点:主动提"数据库变更不可逆"这个坑,说明你考虑过回滚的真实边界,不是只会敲命令。
Q4多套环境的配置差异是怎么管理的?怎么保证一致性?+
  • Helm values 分环境:同一个 Chart,每个环境一份 values 覆盖差异(副本数、资源、域名、配置中心地址),差异全收在 values 里。
  • 镜像不可变:CI 只构建一次,同一个镜像从 dev 一路晋级到 prod,杜绝"重新构建导致环境不一致"。
  • 集群隔离:非生产共享集群用 namespace 隔离,生产独立集群物理隔离,互不影响。
  • 预发兜底:staging 配置尽量贴近生产,是上生产前最后一道验证。
关键区分:「配置不同、镜像相同」——这是保证一致性的核心。被追问时强调镜像不可变 + values 外置这两点。
Q5钉钉审批是怎么对接的?审批没通过流水线怎么处理?+
  • 对接方式:Jenkins 在生产部署 stage 前调用钉钉自定义机器人/工作流 API,推送审批卡片。
  • 阻塞等待:流水线用 input 步骤或轮询审批结果,等到审批通过才继续,超时则自动终止。
  • 未通过:审批拒绝则流水线标记为 ABORTED,不部署,并通知发起人。
  • 可追溯:谁发起、谁审批、什么时间,都有记录,满足合规要求。
Q6为什么生产要独立集群?GitOps 下一套 Argo CD 怎么管多个集群?+

为什么独立:

  • 生产和非生产物理隔离,避免测试环境的问题(资源抢占、误操作)波及生产。
  • 满足安全合规——生产集群权限可单独收紧。
  • 非生产合并成共享集群用 namespace 隔离,省成本。

一套 Argo CD 管多集群:

  • Argo CD 用 argocd cluster add 把非生产、生产两个集群都纳管进来。
  • 每个环境一个 Application,destination 指向对应集群和 namespace。
  • 集群凭证收敛在 Argo CD(不在 Jenkins),Jenkins 只管推代码和写 Git,权限边界更清晰。
和传统模式的关键区别:凭证从 Jenkins 转移到 Argo CD。Jenkins 被攻破也连不到集群,安全性提升。
Q7什么是 GitOps?和传统 CI/CD 部署有什么区别?+
  • 核心定义:以 Git 为唯一可信源,集群的期望状态全部声明在 Git 里,由控制器(Argo CD)持续把集群实际状态向 Git 对齐。
  • 推 vs 拉:传统是「推」——Jenkins 主动 kubectl/helm 把变更推到集群;GitOps 是「拉」——Argo CD 在集群内主动拉取 Git 变更同步。
  • 可追溯:每次发布都是一次 Git commit,谁改的、改了啥、什么时间,全程留痕。
  • 自愈:集群被手动改动会自动纠回 Git 状态,杜绝配置漂移。
一句话:GitOps = 声明式 + Git 为源 + 自动同步 + 自愈。回滚 = revert commit,这是它最优雅的地方。
Q8为什么要拆代码仓和配置仓?放一个仓不行吗?+
  • 避免死循环:放一个仓,CI 改 tag 提交会再次触发 CI,循环触发。
  • 职责清晰:代码仓给开发,配置仓给运维/发布,权限可分开管控。
  • 发布与开发解耦:改配置仓发布不需要动代码,回滚也只动配置仓。
  • Argo CD 只盯配置仓:监听对象单一,逻辑简单。
Q9金丝雀和蓝绿的区别?什么场景用哪个?+
  • 蓝绿:新版本整套起好,流量一次性全切过去。切换快、回滚快,但要双倍资源,且不能用真实流量渐进验证。
  • 金丝雀:新版本逐步放量(10%→30%→100%),用真实流量分阶段验证。资源占用小,但配置复杂、需指标支撑。
  • 选型:要瞬时切换、不容忍新旧混跑 → 蓝绿;要用线上流量验证高风险变更、影响面可控 → 金丝雀。
一句话区分:蓝绿是「全切,赌一把但能秒回」,金丝雀是「试探着放量,边放边看」。
Q10金丝雀发布怎么自动判断新版本健康、要不要继续放量?+
  • 定指标:用 Argo Rollouts 的 AnalysisTemplate 定义判断指标,常用成功率(非5xx占比)、P99 延迟、错误率。
  • 查数据源:从 Prometheus 查这些指标的实时值。
  • 设阈值:比如成功率 ≥95% 才算通过,达标自动进入下一放量步骤。
  • 不达标自动回滚:指标低于阈值,Rollout 自动中止并回滚到旧版本,不需要人盯着。
这是金丝雀的精髓——不是简单放10%流量,而是用真实流量指标自动决策,把发布风险量化、自动化。能讲清这点是高级运维的加分项。