本文共 2000+ 字,阅读约需要 10 分钟。
本文基于之前完整实战环境,构建 Jenkins + Harbor + ArgoCD + Gitea 的 CI/CD + GitOps 自动化交付体系。从代码提交到应用上线,全流程自动化,并深入理解其背后的企业级架构设计思想。
构建一套企业级标准交付链路:
代码提交 → 自动构建 → 自动发布 → 自动部署 → 自动修复
并解决核心问题:
👉 如何让“部署”变成一件可控的事情?
开发者 → Gitea(源码仓库) → Jenkins(CI)
↓
Harbor(镜像仓库)
↓
GitOps Repo(部署声明)
↓
ArgoCD(CD)
↓
Kubernetes(运行环境)

这套系统不是“工具堆叠”,而是分层设计:
git push
核心组件:Jenkins + Kaniko
职责:
👉 输出结果:
Docker Image(唯一交付物)
核心组件:GitOps Repo(Gitea)
职责:
记录“期望状态”
例如:
image: my-app:v1.0.15
👉 这是整个系统的:
唯一事实源(Single Source of Truth)
核心组件:ArgoCD
职责:
核心组件:Kubernetes
职责:
CI 负责生成变更
Git 负责声明变更
CD 负责执行变更
Kubernetes 负责运行变更
git push

触发方式:
Gitea → Jenkins
源码 → Docker Image
👉 使用 Kaniko,避免 Docker 权限问题
my-app:v1 → my-app:v2

Jenkins 不会部署应用,只做一件事:
👉 修改 YAML:
image: my-app:v1
→
image: my-app:v2
然后:
git commit
git push

👉 GitOps 仓库变更记录
ArgoCD 持续执行:
Git(期望状态) vs 集群(当前状态)
发现:
版本不一致

👉 ArgoCD Diff 页面
ArgoCD 自动执行:
kubectl apply(内部执行)
触发:
kubectl get pods -w
观察:
NodePort / Ingress → Service → Pod

两种方案各有适用场景,不能简单说谁对谁错。下面从实际工程角度对比两种模式。
对比维度 | Jenkins + kubectl 模式 | GitOps 模式(当前方案) |
|---|---|---|
实现复杂度 | 简单直接,Jenkinsfile 中直接调用 kubectl apply | 需要额外部署 ArgoCD,维护 GitOps 仓库 |
部署速度 | 构建完成后立即部署,延迟低 | 依赖 ArgoCD 轮询周期(默认 3 分钟)或 Webhook |
可追溯性 | 依赖 Jenkins 构建历史,与 Git 代码关联弱 | 每次部署对应一次 Git 提交,天然关联 |
回滚操作 | 需要手动执行 kubectl rollout undo或重新构建旧版本 | git revert后自动同步,操作统一 |
集群状态一致性 | 人为手动修改集群后不会被纠正,容易漂移 | ArgoCD 持续调谐,自动修复偏离 |
多环境管理 | 需要 Jenkinsfile 中编写复杂逻辑区分环境 | 通过 Git 分支或目录天然隔离 |
故障恢复 | Jenkins 挂掉后无法部署,需人工介入 | ArgoCD 独立运行,Git 仓库在即可恢复 |
学习成本 | 低,团队熟悉 Jenkins 即可 | 中高,需理解 GitOps 理念和 ArgoCD 模型 |
适用团队规模 | 小型团队、快速验证阶段 | 中大型团队、生产环境、合规要求高 |
apply,几分钟内看到结果。但它也有明显的隐患:
kubectl edit修改了副本数,下次部署时可能被覆盖,也可能残留,状态不可预测。git revert,符合软件工程最佳实践。但它也有代价:
kubectl稍高(可通过 Webhook 优化)。CI/CD 只是执行工具
是否可控,取决于状态管理方式
两种模式并非互斥,部分团队采用混合模式:日常开发环境用 Jenkins 直接部署以追求速度,生产环境走 GitOps 以保证安全合规。
最终的选择取决于团队规模、业务要求和对稳定性的权衡。本文采用 GitOps 方案,是为了演示从“能用”到“可控”的进阶路径,帮助读者理解声明式运维的核心价值。
dev / test / prod
这套系统真正解决的不是“部署自动化”,而是:
让部署变得可控
从:
“我执行了部署”
到:
“系统根据 Git 自动完成部署”