【自动化部署】CI/CD 实战(三):让 Argo CD 接管 CD,Jenkins 镜像自动同步到集群

【自动化部署】CI/CD 实战(三):让 Argo CD 接管 CD,Jenkins 镜像自动同步到集群

    • 一、整体架构与演进思路
      • [整体数据流(GitOps 模式)](#整体数据流(GitOps 模式))
    • 二、环境准备:基础设施与工具部署
      • [2.1 代码仓库结构规划](#2.1 代码仓库结构规划)
      • [2.2 配置 K3s 访问私有镜像仓库](#2.2 配置 K3s 访问私有镜像仓库)
      • [2.3 构建自定义 Jenkins 镜像并启动](#2.3 构建自定义 Jenkins 镜像并启动)
      • [2.4 部署 Argo CD 至 Kubernetes](#2.4 部署 Argo CD 至 Kubernetes)
    • [三、配置 Argo CD:连接部署仓库](#三、配置 Argo CD:连接部署仓库)
    • [四、配置 Jenkins:驱动 CI 与 Git 更新](#四、配置 Jenkins:驱动 CI 与 Git 更新)
      • [4.1 凭据管理](#4.1 凭据管理)
      • [4.2 编写 Pipeline 脚本](#4.2 编写 Pipeline 脚本)
      • [4.3 配置 Webhook 全自动触发](#4.3 配置 Webhook 全自动触发)
    • [五、验证与回滚:GitOps 的核心优势](#五、验证与回滚:GitOps 的核心优势)
      • [5.1 一键回滚与版本历史](#5.1 一键回滚与版本历史)
      • [5.2 自愈能力](#5.2 自愈能力)
    • 六、总结

在前两篇文章中,我们已经搭建了基础的 CI/CD 流水线。但在实际生产环境中,仍面临版本管理困难、无法快速回滚、服务故障无法自愈、多环境管理混乱等痛点。本次迭代,我们将引入 Argo CD ,通过 GitOps 模式完美解决上述问题,让 CD 流程更加稳定和自动化。


一、整体架构与演进思路

本次升级的核心思路是 职责分离:Jenkins 继续专注于 CI(持续集成),即代码拉取、构建、镜像推送;而 CD(持续部署)则完全交由 Argo CD 接管。

Argo CD 遵循 GitOps 理念,将 Git 仓库视为应用状态的唯一真实来源。它会持续监控 Git 仓库中声明的期望状态,并自动将 Kubernetes 集群状态同步至此。由此带来的升级非常直观:

  • 版本管理:Git 提交记录就是部署历史。
  • 快速回滚:一键回到 Git 历史中的任意版本。
  • 故障自愈:自动修正集群中任何与 Git 声明不符的变更。
  • 多环境一致性:通过 Git 分支或目录结构轻松管理开发、测试、生产环境。

整体数据流(GitOps 模式)

整个自动化流程如下图所示,后续所有操作都将围绕此流程展开:
提交代码
Jenkins 构建
构建镜像并推送到 Harbor
Jenkins 更新 Git 仓库中的 K8s 清单文件(修改镜像 tag)
Argo CD 检测到 Git 仓库变化
Argo CD 自动同步到 Kubernetes 集群
K8s 滚动更新

前置环境说明:宿主机需已准备 Docker 环境、Harbor 私有镜像仓库及 K3s 集群。


二、环境准备:基础设施与工具部署

根据上述数据流,我们首先需要准备好代码仓库、镜像仓库、Jenkins 构建节点以及目标 Kubernetes 集群上的 Argo CD。

2.1 代码仓库结构规划

遵循 GitOps 最佳实践,我们将应用源码与部署配置分离,存放在两个独立的 Git 仓库中。

1. 业务代码仓库(app-repo)

包含应用源码、Dockerfile 以及 Jenkins 流水线定义。

复制代码
app-repo/
├── src/                 # 源码目录
├── Dockerfile           # 镜像构建定义
└── README.md
yaml 复制代码
#Dockerfile           

FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
html 复制代码
#index.html

<!DOCTYPE html>
<html>
<head><title>Argo CI/CD</title></head>
<body>
  <h1>Hello from Argo CI/CD!</h1>
  <p>Version 1.0</p>
</body>
</html>

2. K8s 部署配置仓库(k8s-manifests-repo)

存放 Kubernetes 资源的声明式 YAML 文件,支持多环境管理。

复制代码
k8s-manifests-repo/
├── base/                # 基础配置(共享)
│   └── deployment.yaml
│   └── service.yaml
├── overlays/            # 多环境差异化配置
│   ├── dev/
│   │   └── kustomization.yaml
│   │   └── deployment-patch.yaml
│   ├── staging/
│   └── prod/
└── README.md
yaml 复制代码
#deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx
        image: xxxx:TAGNAME
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-demo-service
  namespace: default
spec:
  type: NodePort
  selector:
    app: nginx-demo
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080

2.2 配置 K3s 访问私有镜像仓库

为了让 K3s 集群能顺利从 Harbor 拉取镜像,需在所有 K3s 节点上配置私有仓库信息。编辑 /etc/rancher/k3s/registries.yaml

yaml 复制代码
mirrors:
  47.242.60.127:8081:
    endpoint:
      - "http://47.242.60.127:8081"
configs:
  "47.242.60.127:8081":
    tls:
      insecure_skip_verify: true

配置完成后需重启 K3s 服务以生效。

2.3 构建自定义 Jenkins 镜像并启动

Jenkins 在 CI 环节需要执行 docker buildkubectl 命令,因此我们需在官方镜像基础上内置 Docker CLI 和 kubectl 工具。

步骤 1:编写 Dockerfile

bash 复制代码
mkdir ~/jenkins-custom && cd ~/jenkins-custom
vim Dockerfile
dockerfile 复制代码
FROM jenkins/jenkins:lts

USER root

# 安装 Docker CLI
RUN apt-get update && \
    apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release && \
    curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \
    echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \
    apt-get update && \
    apt-get install -y docker-ce-cli

# 安装 kubectl
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && \
    chmod +x kubectl && \
    mv kubectl /usr/local/bin/

# 确保 Git 可用
RUN apt-get install -y git

# 将 jenkins 用户加入 docker 组
RUN groupadd -f docker && usermod -aG docker jenkins

USER jenkins

步骤 2:构建并推送至 Harbor

bash 复制代码
# 构建镜像
docker build -t [你的镜像名:tagname] .

# 登录 Harbor 并推送
docker login [你的 Harbor 地址] -u [用户名] -p [密码]
docker tag [你的镜像名:tagname] [你的 Harbor 地址]/[项目名]/[镜像名]:[tagname]
docker push [你的 Harbor 地址]/[项目名]/[镜像名]:[tagname]

步骤 3:编写 Docker Compose 文件启动 Jenkins

创建 ~/jenkins-argocd/docker-compose.yaml,注意将 group_add 的 GID 替换为宿主机 docker 组 ID(通过 getent group docker | cut -d: -f3 获取)。

yaml 复制代码
services:
  jenkins:
    image: [上一步推送到 Harbor 的镜像]
    container_name: jenkins
    ports:
      - "8080:8080"
      - "50001:50000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - jenkins_home:/var/jenkins_home
    networks:
      - devops-net
    restart: unless-stopped
    group_add:
      - "999"   # 替换为宿主机 docker 组 GID

networks:
  devops-net:
    driver: bridge

volumes:
  jenkins_home:

启动 Jenkins:

bash 复制代码
docker compose up -d
# 获取初始密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

2.4 部署 Argo CD 至 Kubernetes

Argo CD 负责监控部署配置仓库并同步至集群。

bash 复制代码
# 创建命名空间并安装
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 等待 Pod 就绪
kubectl get pods -n argocd -w

暴露服务并获取登录信息:

bash 复制代码
# 改为 NodePort 模式便于访问
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'

# 获取初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# 查看分配的端口
kubectl get svc -n argocd argocd-server

随后通过浏览器访问 https://<IP>:<分配端口> 即可进入 Argo CD 界面。


三、配置 Argo CD:连接部署仓库

在 Argo CD 侧,我们需要创建 Application 资源,告诉它去监控哪个 Git 仓库的哪个目录。

  1. 登录 Argo CD UI。
  2. 点击 New App ,填写关键信息:
    • Application Namenginx-demo
    • Sync PolicyAutomatic(开启自动同步与自愈)
    • Repository URL :填写前面创建的 K8s 清单 Git 仓库 地址。
    • Path:YAML 文件所在目录(例如 .)。
    • Cluster URLhttps://kubernetes.default.svc(指向当前集群)。
    • Namespacedefault

创建完成后,Argo CD 会立即扫描目标仓库。若仓库内已有正确的 YAML 文件,应用状态将变为 SyncedHealthy


四、配置 Jenkins:驱动 CI 与 Git 更新

最后一步是配置 Jenkins 流水线,串联代码提交到 Git 仓库更新的全过程。

4.1 凭据管理

Dashboard > Manage Jenkins > Credentials 中添加以下凭据:

凭据用途 类型 凭据 ID(后续脚本引用)
拉取业务源码 Username with password gitee-source
推送镜像至 Harbor Username with password harbor
推送更新到 K8s 清单仓库 Username with password gitee-manifests

同时,在 系统管理 > Gitee 配置 中配置源码仓库地址并测试连接成功。

4.2 编写 Pipeline 脚本

新建流水线任务,将以下 Groovy 脚本粘贴至 Pipeline 定义中。此脚本实现了数据流中的 B -> C -> D 环节。

groovy 复制代码
pipeline {
    agent any
    environment {
        // Harbor 配置
        HARBOR_URL = 'harbor.example.com'
        HARBOR_PROJECT = 'devops'
        APP_IMAGE_NAME = "${HARBOR_URL}/${HARBOR_PROJECT}/【应用镜像名】"

        // K8s 清单 Git 仓库配置
        MANIFEST_REPO = '【存放 K8s 清单的 Git 仓库地址】'
        MANIFEST_BRANCH = 'main'
        K8S_MANIFEST_PATH = 'deployment.yaml'
    }
    stages {
        stage('Checkout Source Code') {
            steps {
                git branch: '【源码分支】', credentialsId: 'gitee-source', url: '【源码仓库地址】'
            }
        }
        stage('Build and Push Image') {
            steps {
                script {
                    def IMAGE_TAG = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
                    echo "构建镜像标签: ${IMAGE_TAG}"
                    
                    withCredentials([usernamePassword(credentialsId: 'harbor', usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS')]) {
                         sh "echo ${HARBOR_PASS} | docker login ${HARBOR_URL} -u ${HARBOR_USER} --password-stdin"
                    }
                    
                    sh "docker build -t ${APP_IMAGE_NAME}:${IMAGE_TAG} ."
                    sh "docker push ${APP_IMAGE_NAME}:${IMAGE_TAG}"
                    env.IMAGE_TAG = IMAGE_TAG
                }
            }
        }
        stage('Update K8s Manifests in Git') {
            steps {
                script {
                    dir('k8s-manifests') {
                        git branch: MANIFEST_BRANCH, credentialsId: 'gitee-manifests', url: MANIFEST_REPO
                        
                        // 修改 YAML 中的镜像标签
                        sh "sed -i 's|image: .*|image: ${APP_IMAGE_NAME}:${env.IMAGE_TAG}|' ${K8S_MANIFEST_PATH}"
                        
                        // 提交变更并推送
                        sh """
                            git config user.email "jenkins@devops.com"
                            git config user.name "Jenkins CI"
                            git add ${K8S_MANIFEST_PATH}
                            git commit -m "Update image tag to ${env.IMAGE_TAG} [skip ci]" || echo "No changes to commit"
                            git push origin ${MANIFEST_BRANCH}
                        """
                    }
                }
            }
        }
    }
    post {
        success {
            echo "✅ CI 阶段完成!Argo CD 将自动检测到 Git 变更并同步到集群。"
        }
    }
}

4.3 配置 Webhook 全自动触发

  1. 在 Jenkins 任务配置的 构建触发器 中勾选 Gitee webhook ,生成密码。
  2. 登录 Gitee 源码仓库,进入 管理 > WebHooks ,添加 URL 并填入上一步生成的密码,测试返回 200 即为成功。

至此,完整的自动化闭环已经形成:提交代码 -> Jenkins 构建推送 -> 更新清单仓库 -> Argo CD 自动部署


五、验证与回滚:GitOps 的核心优势

5.1 一键回滚与版本历史

当新版本出现问题时,无需重新跑 Jenkins 流水线。只需在 Argo CD UI 进入应用详情,点击 History and Rollback,即可查看由 Git 提交记录生成的部署历史,点击任意版本回滚。


5.2 自愈能力

开启了 Auto-Sync 后,如果有人直接手动修改了集群中的副本数,Argo CD 会立即检测到集群状态偏离了 Git 仓库定义,并在几秒内自动将其修正回来,保障生产环境的稳定性。


六、总结

通过本次迭代,我们成功将 Argo CD 集成到了 CI/CD 流程中。Jenkins 与 Argo CD 各司其职:

  • Jenkins 负责从源码到镜像的构建流水线。
  • Argo CD 负责从 Git 到集群的同步。

至此,改造完成!

相关推荐
ZC跨境爬虫2 小时前
UI前端美化技能提升日志day1:矢量图片规范与自适应控制栏实战
前端·css·ui·状态模式
朱穆朗2 小时前
Cmder创建npm等项目中,使用CLI的BUG
前端·npm·bug
Z_Wonderful2 小时前
实现图片拖动、鼠标中心点缩放、文字层跟随功能
前端·javascript·计算机外设
dualven_in_csdn2 小时前
【docker】docker下如何使用宿主主机的GPU
运维·docker·容器
|晴 天|2 小时前
前端项目多平台部署:GitHub Pages + Vercel + Cloudflare Pages 实战教程
前端·javascript·vue.js
cyber_两只龙宝2 小时前
【Oracle】Oracle之SQL的集合运算符
linux·运维·数据库·sql·云原生·oracle
ZC跨境爬虫2 小时前
UI前端美化技能提升日志day2:图片优化、字体本地化与设计美感解析
前端·javascript·ui·状态模式
yivifu2 小时前
接近完善的HTML双行夹批显示方案
前端·javascript·html·html双行夹批
M ? A2 小时前
Vue转React终极指南:VuReact全特性语义对照
前端·javascript·vue.js·react.js·面试·开源·vureact