🔀环境架构与 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」。
pipeline {
agent any
environment {
HARBOR = 'harbor.xxx.com/myapp'
APP = 'user-service'
TAG = "${env.GIT_COMMIT.take(8)}"
}
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'
}
}
stage('更新配置仓(触发GitOps)') {
steps {
script {
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') {
sh 'yq -i ".image.tag = strenv(TAG)" envs/$ENV/values.yaml'
sh 'git commit -am "deploy $APP:$TAG to $ENV"'
sh 'git push'
}
}
}
}
}
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」。环境的区分全在这里,不在流水线里。非生产开自动同步,生产设手动同步。
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 }
spec:
destination:
server: https://prod-cluster
namespace: prod
syncPolicy: {}
③ 自动同步 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 那一行。
replicaCount: 1
resources: { requests: { cpu: 100m, memory: 256Mi } }
ingress: { host: dev.myapp.com }
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 revert HEAD && git push
argocd app history user-service-prod
argocd app rollback user-service-prod 12
🚦发布策略
滚动 / 蓝绿 / 金丝雀,怎么选、怎么落地
三种策略对比
| 策略 | 原理 | 优点 | 代价 | 适用 |
滚动更新 Rolling |
逐批替换旧 Pod,新旧并存过渡 |
不额外占资源,K8s 原生默认 |
新旧版本短暂共存;出问题影响面已铺开 |
日常发布、向后兼容的变更 |
蓝绿 Blue-Green |
新版本(绿)整套起好,流量一次性切过去 |
秒级切换、秒级回滚,无新旧混跑 |
要双倍资源 |
不容忍新旧混跑、要快速回滚的核心系统 |
金丝雀 Canary |
先放小比例流量给新版本,逐步加码 |
影响面可控,能用真实流量验证 |
配置复杂,需指标分析支撑 |
高风险变更、想用线上流量验证 |
本项目怎么用
- 非生产 + 多数生产发布:滚动更新,配好 readiness 探针和 maxSurge/maxUnavailable,简单稳定。
- 生产核心服务:金丝雀,借助 Argo Rollouts 按 10%→30%→60%→100% 逐步放量,每步自动看指标,异常自动回滚。
- 需要瞬时切换的场景:蓝绿,整套新版本就绪后一次切流量,回滚就是把流量切回去。
滚动更新:参数是关键
K8s 默认策略,重点在两个参数控制替换节奏,配合探针避免「Pod 起来了但还没就绪就接流量」。
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0
readinessProbe:
httpGet: { path: /health, port: 8080 }
initialDelaySeconds: 10
金丝雀:用 Argo Rollouts 落地
原生 Deployment 做不了精细金丝雀,引入 Argo Rollouts(Argo 生态,和 Argo CD 天然搭配)。用 Rollout 资源替代 Deployment,定义放量步骤,每步暂停观察或由指标自动判断是否继续。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 30
- analysis:
templates: [{ templateName: success-rate }]
- setWeight: 60
- pause: {}
- setWeight: 100
金丝雀自动判断:AnalysisTemplate
放量过程中,Argo Rollouts 查 Prometheus 指标(如成功率、P99 延迟),达标才继续放量,不达标自动回滚到旧版本——这是金丝雀真正的价值,不靠人盯。
kind: AnalysisTemplate
spec:
metrics:
- name: success-rate
successCondition: result[0] >= 0.95
provider:
prometheus:
address: http://prometheus:9090
query: sum(rate(http_requests_total{code!~"5.."}[2m]))
/ sum(rate(http_requests_total[2m]))
面试落脚点:金丝雀的精髓不是"放10%流量",而是用真实流量的指标自动决策放量或回滚,把发布风险量化、自动化。
❓面试常见问题
点击展开查看答题思路(请核对真实性)
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%流量,而是用真实流量指标自动决策,把发布风险量化、自动化。能讲清这点是高级运维的加分项。