Jenkins到ArgoCD------GitOps持续交付实践
用了几年Jenkins之后,很多人会有一种说不出的疲惫感。Job配置散落在各处, pipeline脚本越写越长,环境之间的差异靠人肉复制粘贴。部署出问题了,第一反应是"到底部署了哪个版本",而不是"代码有什么Bug"。这不是Jenkins的问题,是Push模式的天然缺陷。ArgoCD用GitOps理念重新定义了持续交付,截至2026年8月,最新版本v3.5已经把内部mTLS和ApplicationSet管理都做成了标配。
Push模式哪里不对
Jenkins的工作方式是Push:CI跑完构建,然后主动把制品推到目标环境。听起来合理,但实际操作中问题一大堆。
首先是配置漂移。有人在服务器上手动改了个配置文件,有人kubectl patch了一下,时间一长,集群里的实际状态和Jenkins里记录的部署配置就对不上了。出了问题根本不知道线上跑的是什么。
其次是环境一致性差。dev、staging、prod三套环境,配置文件各维护一份。改了一个忘了改另外两个,或者改的地方不一致,导致"在我电脑上能跑"的经典场景升级成了"在staging能跑prod不能跑"。
最后是权限问题。Jenkins需要目标环境的写入权限,权限范围往往给得很大。一旦Jenkins被攻破,所有环境都暴露了。
GitOps的四个原则
GitOps的核心思想很简单:把Git仓库当作系统状态的唯一真相来源。具体来说有四条原则。
声明式描述。系统的期望状态用声明式配置描述,不是用脚本描述"怎么做",而是描述"想要什么样子"。
版本控制。所有配置存在Git里,每次变更都有提交记录,谁改的、改了什么、什么时候改的,全可追溯。回滚就是git revert。
自动同步。有个组件持续对比Git里的期望状态和集群里的实际状态,发现差异就自动拉齐。不需要人去触发部署。
持续协调。不只是部署时同步,而是持续监听。有人手动改了集群资源,自动纠正回来。配置漂移从根本上被杜绝。
ArgoCD的Pull模式
ArgoCD跑在Kubernetes集群内部,主动从Git仓库拉取配置,然后应用到集群。和Jenkins的Push模式相反,这是Pull模式。
Pull模式的好处是安全性。ArgoCD只需要集群内的权限,不需要CI系统能访问集群。CI负责构建和测试,CD负责部署,职责清晰分离。Git仓库是唯一的写入入口,审计变得简单------看git log就知道所有变更。
ArgoCD的架构不复杂。三个核心组件:API Server提供UI和API接口,Repository Server负责拉取和缓存Git仓库内容,Application Controller负责对比期望状态和实际状态并执行同步。v3.5版本给这三个组件之间的通信加了内部mTLS,以前内部流量是明文的,现在默认加密,安全姿态提升了一大截。
Application资源怎么定义
ArgoCD的核心抽象是Application。一个Application描述了"把Git仓库里的哪部分配置同步到哪个集群的哪个namespace":
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app namespace: argocd spec: source: repoURL: https://github.com/myorg/my-app-config targetRevision: main path: manifests/production destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: true
syncPolicy.automated开启自动同步。prune: true表示Git里删了资源集群里也删。selfHeal: true是关键------有人手动改了集群资源,ArgoCD会自动恢复成Git里定义的状态。这就是防配置漂移的核心机制。
不想全自动也行。关掉automated,改成手动同步,在UI上点按钮触发。适合对变更敏感的生产环境。
多环境管理怎么搞
环境一多,管理就复杂。dev、staging、prod每个环境一套Application定义,复制粘贴不说,维护起来痛苦。
App of Apps模式是个解法。建一个"父Application",它的source指向一个包含多个子Application定义的目录。同步父Application时,子Application会被自动创建。环境多了只需要管理父Application,子Application由目录结构自动组织。
Kustomize是另一个利器。一个base目录放通用配置,每个环境一个overlay只写差异部分:
config-repo/ ├── base/ │ ├── deployment.yaml │ ├── service.yaml │ └── kustomization.yaml ├── overlays/ │ ├── dev/ │ │ ├── patch.yaml │ │ └── kustomization.yaml │ └── prod/ │ ├── patch.yaml │ └── kustomization.yaml
dev和prod共享base里的配置,各自只改需要差异化的部分。环境一致性有了保障,维护成本也低。v3.5版本对Helm 4也做了支持,用Helm管理多环境的团队也能无缝接入。
和CI流水线怎么配合
ArgoCD只管CD,不管CI。构建、测试、打镜像这些还是靠Jenkins、GitHub Actions或GitLab CI。关键在于两者怎么衔接。
做法很简单:CI流水线跑完后,更新配置仓库里的镜像版本号,推一个commit到Git。ArgoCD检测到Git变化,自动同步到集群。整个流程是:代码提交 → CI构建测试 → 更新配置仓库镜像tag → ArgoCD自动部署。
更新配置仓库可以手动git push,也可以用ArgoCD Image Updater自动做。Image Updater监听镜像仓库,发现新tag后自动更新Git仓库里的配置。这样就实现了从代码提交到部署的全自动流程,中间不需要任何人干预。
这个链路里Git仓库是唯一的衔接点。CI系统不需要知道集群在哪、怎么部署,只要能push到Git就行。ArgoCD不需要知道代码怎么构建、镜像怎么打,只要盯着Git仓库变化。职责分离干净利落。
滚动更新和回滚
ArgoCD本身不负责滚动策略,那是Kubernetes Deployment的活。ArgoCD只负责把配置同步过去,具体的发布策略由Kubernetes控制器执行。
但ArgoCD有个利器:Argo Rollouts。这是单独的组件,用Rollout资源替代Deployment,支持蓝绿部署、金丝雀发布等高级发布策略。可以定义"先放10%流量到新版本,观察5分钟,指标没问题再逐步放大"这种渐进式发布。
回滚在GitOps模式下特别简单。线上出了问题,git revert回上一个commit,ArgoCD自动把集群状态恢复回去。不用翻部署日志找上一个镜像tag,不用手动kubectl apply。Git的提交历史就是完整的部署历史,每个变更都可追溯、可回滚。
v3.5还带来了Git提交签名验证功能,供应链安全又多了一层保障。只有签名验证通过的commit才会被同步,防止有人往配置仓库里塞恶意配置。对安全要求高的团队,这个功能值得开启。
从Jenkins迁移过来
别想着一步到位。先拿一个非核心服务试水,把它的部署配置搬到Git仓库,用ArgoCD管理。跑通流程、团队熟悉了再逐步迁移其他服务。
Jenkins不用急着拆。CI流水线暂时留在Jenkins,只把CD部分切到ArgoCD。等团队完全适应GitOps模式后,再考虑CI是否也迁移到更现代的工具。
迁移过程中最大的挑战不是技术,是习惯。团队习惯了手动部署、手动审批,改成自动同步会有不安感。先在dev环境完全自动化,staging加审批按钮,prod保留手动同步。逐步建立信心。
ArgoCD的UI做得不错,能直观看到每个Application的同步状态、健康状态、历史记录。v3.5把ApplicationSet管理也搬到了UI里,以前只能用命令行或YAML管理ApplicationSet,现在在界面上就能操作。对不熟悉命令行的团队成员,这降低了上手门槛。
GitOps不是银弹,但它确实解决了传统持续交付里最让人头疼的几个问题:配置漂移、环境不一致、审计困难。从Jenkins迁到ArgoCD,本质上是把部署从"脚本驱动"转向"状态驱动"。思维方式变了,很多以前需要人盯着的环节就不需要了。