Jenkins 遇见 Argo CD:构建可靠 GitOps 流水线的实战指南

Jenkins 遇见 Argo CD:构建可靠 GitOps 流水线的实战指南

Jenkins 可以说是 CI 领域的老牌 "瑞士军刀",无数团队用它构建、测试、打包应用。但当部署环节还停留在 kubectl apply 脚本或 SSH 到服务器时,版本不可追踪、配置漂移、回滚困难这些痛点就会接踵而至。这时候,引入 Argo CD 实践 GitOps,让 Jenkins 与 Argo CD 各司其职,往往能让交付流水线瞬间变得优雅且可靠。本文将带你一步步拆解它们如何协同工作。

重新划分职责:CI 与 CD 彻底解耦

传统 Jenkins 流水线通常一头扎到底:拉代码 → 测试 → 构建镜像 → 直接部署到 Kubernetes。部署步骤里塞满了复杂的 Shell 命令和 if-else 判断,久而久之,流水线变成了难以维护的"面条代码"。

GitOps 的理念则要求我们有一个 "声明式的单一事实来源"------Git 仓库。集群的期望状态全部用 YAML 描述,并由控制器自动同步。于是 Jenkins 和 Argo CD 的职责变得异常清晰:

  • Jenkins 负责 CI(持续集成) :编译、测试、构建容器镜像、推送镜像,以及最关键的一步------把新镜像的标签写回 GitOps 仓库

  • Argo CD 负责 CD(持续部署):监视 GitOps 仓库中的声明变更,自动(或手动批准后)将集群的实际状态调和为期望状态。

这种分工让每一环都专注本行:Jenkins 确保代码和镜像质量;Argo CD 确保集群与 Git 声明一致。部署逻辑不再深埋在流水线脚本里,而是透明地记录在 Git 提交历史中。

实战:构建一条 Jenkins → Argo CD 流水线

以下是一个典型的 GitOps 流水线设计,以微服务 user-service 为例。

仓库结构

我们使用 两个独立的 Git 仓库(也可以合并在一个仓库不同目录,但分开更利于权限和职责隔离):

  • 应用仓库 (app-user-service):存放服务源码、Dockerfile、Jenkinsfile。

  • GitOps 仓库 (gitops-deployments):存放所有服务的 Kubernetes 部署清单,例如 deployments/user-service/ 下包含 Deployment、Service 等 YAML,使用 Kustomize 或 Helm 编排。

Jenkins Pipeline:三步到位

Jenkins 在完成测试构建后,重点是优雅地更新 GitOps 仓库。下面是一段简化但完整的 Jenkinsfile 片段:

groovy

复制代码
pipeline {
    agent any
    environment {
        IMAGE_TAG = "v${BUILD_NUMBER}"
        REGISTRY = "myregistry.io"
        APP_NAME = "user-service"
        GITOPS_REPO = "github.com/team/gitops-deployments.git"
    }
    stages {
        stage('Build & Push Image') {
            steps {
                sh "docker build -t ${REGISTRY}/${APP_NAME}:${IMAGE_TAG} ."
                sh "docker push ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}"
            }
        }
        stage('Update GitOps Repo') {
            steps {
                // 检出 GitOps 仓库
                git branch: 'main', url: "https://${GIT_CREDENTIALS}@${GITOPS_REPO}"
                // 用 Kustomize 修改镜像标签(也可以用 sed/yq 修改普通 YAML)
                dir("deployments/${APP_NAME}") {
                    sh "kustomize edit set image ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}"
                }
                // 提交变更并推送
                sh '''
                    git config user.email "jenkins@team.com"
                    git config user.name "Jenkins CI"
                    git add .
                    git commit -m "Update ${APP_NAME} image tag to ${IMAGE_TAG}"
                    git push origin main
                '''
            }
        }
    }
}

要点

  • 尽量使用 KustomizeHelm 这类结构化工具修改清单,而不是粗暴的 sed 替换,这能避免格式破坏。

  • GitOps 仓库的 push 应设置严格的分支保护:要求 PR、代码审查、CI 检查,但这条流水线推送通常是自动的;如果要求审批,可以让 Jenkins 只创建一个 PR 分支,由人工合并,而不是直接推送 main。

Argo CD:自动同步集群

在集群中,我们为 user-service 定义一个 Argo CD Application:

yaml

复制代码
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/team/gitops-deployments.git
    targetRevision: main
    path: deployments/user-service
  destination:
    server: https://kubernetes.default.svc
    namespace: user-service
  syncPolicy:
    automated:
      prune: false      # 谨慎开启 prune
      selfHeal: true    # 自动修复手动修改

当 Jenkins 推送新镜像标签后,Argo CD 检测到 Git 仓库中 Kustomize 描述的 Deployment 镜像字段发生变化,如果开启了 automated 策略,它将自动执行 kubectl apply,滚动更新 Pod。

如果你需要手动审批,可以关闭 automated,只使用 Argo CD 的 UI/CLI 点击 "Sync" 按钮,或者通过 Webhook 触发特定审批流。

多环境管理:同样的流水线,不同的目标

很多团队需要管理开发、预发、生产环境。同样一套 Jenkins + Argo CD 组合可以灵活应对。

  • GitOps 仓库分支/路径策略

    例如,GitOps 仓库维护 stagingproduction 分支,或使用目录 overlays/stagingoverlays/production 存放 Kustomize overlays。

    Jenkins 根据构建分支或参数,更新对应环境的清单。例如,main 分支构建触发更新 staging 目录,release 分支触发更新 production 目录。

  • Argo CD ApplicationSet

    利用 ApplicationSet 根据目录或集群自动为每个环境生成 Application,无需重复配置。

密钥处理:别把密码放在 Git 里

这是 Jenkins + Argo CD 协作中极易疏忽的一环。Secret 绝不能以明文形式保存在 GitOps 仓库中。推荐两种方案:

  1. External Secrets Operator:存储密文在 Vault 或云密钥管理服务中,通过 ExternalSecret 资源从集群内同步,该资源可以安全地存放在 GitOps 仓库。

  2. Sealed Secrets:Jenkins 或开发者在本地将 Secret 加密成 SealedSecret 后提交,集群控制器解密生成真正的 Secret。

无论如何,Jenkins 都不要在更新清单时写入明文密码,这是安全底线。

回滚:比以往任何时候都简单

过去你可能要跑另一个 Jenkins Job 执行一堆 kubectl 命令回滚。有了 GitOps,回滚变成了纯粹的 Git 操作

  • 方案一 :在 GitOps 仓库中 git revert 那个更新镜像标签的 commit,并推送。Argo CD 检测到变更后自动(或手动)同步回旧版本。这符合完整的审计记录。

  • 方案二:直接在 Argo CD UI 中使用 "History and Rollback" 功能,退回到之前的同步版本。但注意这是绕过 Git 的临时操作,应配合后续 Git 修正。

常见误区提醒(来自实践者的血泪)

  1. 把 Argo CD 当 CI 用:不要试图让 Argo CD 执行镜像构建,那个世界属于 Jenkins。

  2. 开启自动修剪 (prune: true) 而不加思索:一旦 Git 目录误删,集群资源会被瞬间清除,生产环境可能迎来灾难。建议谨慎开启,或配合 Sync Windows 限制。

  3. Jenkins 直接推送 GitOps 仓库的 main 分支无保护:至少要求 CI 流水线自身通过后可合并,或使用 Git 钩子做基本校验。

  4. 忘记监控 Argo CD 自身:Argo CD 控制器宕机会让自动同步失效,务必对其健康状态进行监控。

  5. Jenkins 触发 Argo CD 同步打破 Git 事实来源:有时团队喜欢在 Jenkins 更新完 Git 后立即调用 Argo CD API 强制同步,这并非不可,但会掩盖 Argo CD 自身的自动同步能力,并可能造成状态混乱。更纯粹的 GitOps 方式是让 Argo CD 按自己的节奏同步(或 webhook 触发)。

结语

Jenkins 与 Argo CD 的组合,不是对旧工具的抛弃,而是一次优雅的能力重新划分。Jenkins 继续擅长它最拿手的持续集成和自动化管道,而部署的"最后一公里"则交给 Argo CD,让它以声明式的方式守护集群的终态。这样一来,你的交付流水线既保留了 Jenkins 生态的灵活性,又获得了 GitOps 带来的可审计性、一致性和极速回滚能力。

现在,不妨检查一下你现有的 Jenkins 流水线,把那些复杂的部署脚本,迁移到 Git 仓库里,让 Argo CD 开始倾听 Git 的声音吧。这条融合之路,值得一试。

相关推荐
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第214题】【10_网络协议篇】第5题:说一下 TCP 协议的三次握手和四次挥手
java·网络协议·tcp·三次握手·四次挥手
我叫唧唧波1 小时前
【Java】Java 基础系统学习笔记
java·笔记·学习
好好沉淀1 小时前
Spring @Validated和Validation注解 校验机制完全指南
java·数据库·后端
唐青枫1 小时前
Java RxJava 实战指南:从 Observable、Flowable 到线程切换和背压处理
java
IT小盘2 小时前
16-Prompt版本管理-从手工修改到可追踪配置系统
开发语言·人工智能·python·prompt
Cx330❀2 小时前
【Linux网络】深入 HTTP 协议(五):从 Cookie/Session 原理到 C++ 源码实战
linux·运维·服务器·开发语言·网络·c++·http
北冥you鱼2 小时前
Go语言四则运算实战:从基础类型到big包的深度解析
开发语言·后端·golang
凤山老林2 小时前
SpringBoot + Configuration2 实现配置的实时双向更新
java·spring boot·后端
2601_963869954 小时前
【计算机毕业设计】基于 Spring Boot+Vue的手工体验馆管理系统的设计与实现
java·spring boot·后端