【自动化部署】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 build 和 kubectl 命令,因此我们需在官方镜像基础上内置 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 仓库的哪个目录。
- 登录 Argo CD UI。
- 点击 New App ,填写关键信息:
- Application Name :
nginx-demo - Sync Policy :Automatic(开启自动同步与自愈)
- Repository URL :填写前面创建的 K8s 清单 Git 仓库 地址。
- Path:YAML 文件所在目录(例如 .)。
- Cluster URL :
https://kubernetes.default.svc(指向当前集群)。 - Namespace :
default。
- Application Name :

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

四、配置 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 全自动触发
- 在 Jenkins 任务配置的 构建触发器 中勾选 Gitee webhook ,生成密码。

- 登录 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 到集群的同步。
至此,改造完成!