逐浪笔记 GitOps 实战:Jenkins 构建、Argo CD 同步与 Git 回滚

文章目录

  • [逐浪笔记 GitOps 实战:Jenkins 构建、Argo CD 同步与 Git 回滚](#逐浪笔记 GitOps 实战:Jenkins 构建、Argo CD 同步与 Git 回滚)
    • 一、实践背景与目标
      • [1.1 实践目标](#1.1 实践目标)
      • [1.2 最终实现效果](#1.2 最终实现效果)
    • 二、实验架构与职责划分
      • [2.1 整体架构](#2.1 整体架构)
      • [2.2 实验资源](#2.2 实验资源)
    • [三、GitOps 配置文件与 Jenkins Pipeline](#三、GitOps 配置文件与 Jenkins Pipeline)
      • [3.1 关键目录结构](#3.1 关键目录结构)
      • [3.2 Deployment 中的镜像版本](#3.2 Deployment 中的镜像版本)
      • [3.3 Jenkins Pipeline 的核心步骤](#3.3 Jenkins Pipeline 的核心步骤)
    • [四、第一次版本恢复:将实验基线固定到 build-3](#四、第一次版本恢复:将实验基线固定到 build-3)
    • [五、Jenkins 构建并发布 build-5](#五、Jenkins 构建并发布 build-5)
      • [5.1 触发 Jenkins Pipeline](#5.1 触发 Jenkins Pipeline)
      • [5.2 检查 Git 提交与 Diff](#5.2 检查 Git 提交与 Diff)
      • [5.3 检查远程仓库的期望镜像](#5.3 检查远程仓库的期望镜像)
      • [5.4 Argo CD 检测到变更](#5.4 Argo CD 检测到变更)
    • [六、通过 Argo CD 将 build-5 同步到 Kubernetes](#六、通过 Argo CD 将 build-5 同步到 Kubernetes)
      • [6.1 手动执行 Sync](#6.1 手动执行 Sync)
      • [6.2 验证 Deployment 镜像](#6.2 验证 Deployment 镜像)
      • [6.3 验证滚动更新和 Pod](#6.3 验证滚动更新和 Pod)
      • [6.4 观察 Argo CD 最终状态](#6.4 观察 Argo CD 最终状态)
    • [七、核心演练:通过 Git revert 回滚到 build-3](#七、核心演练:通过 Git revert 回滚到 build-3)
      • [7.1 确认当前 Git 历史](#7.1 确认当前 Git 历史)
      • [7.2 为什么先检查远程仓库](#7.2 为什么先检查远程仓库)
      • [7.3 同步工作副本并执行 revert](#7.3 同步工作副本并执行 revert)
      • [7.4 验证回滚提交](#7.4 验证回滚提交)
    • [八、通过 Argo CD 将 Kubernetes 恢复到 build-3](#八、通过 Argo CD 将 Kubernetes 恢复到 build-3)
      • [8.1 理解 Git 回滚与集群回滚的区别](#8.1 理解 Git 回滚与集群回滚的区别)
      • [8.2 在 Argo CD 中执行 Sync](#8.2 在 Argo CD 中执行 Sync)
      • [8.3 验证 Kubernetes 中的镜像](#8.3 验证 Kubernetes 中的镜像)
      • [8.4 验证滚动更新与 Pod](#8.4 验证滚动更新与 Pod)
    • [九、最终验证:通过 HTTP 请求检查服务](#九、最终验证:通过 HTTP 请求检查服务)
      • [9.1 启动端口转发](#9.1 启动端口转发)
      • [9.2 执行 HTTP 请求](#9.2 执行 HTTP 请求)
      • [9.3 HTTP 验证说明](#9.3 HTTP 验证说明)
    • 十、问题排查与实践经验
      • [10.1 Git 中的版本与 Kubernetes 中的版本不一致](#10.1 Git 中的版本与 Kubernetes 中的版本不一致)
      • [10.2 Git 回滚后应用没有立即回退](#10.2 Git 回滚后应用没有立即回退)
      • [10.3 本地端口 18081 被占用](#10.3 本地端口 18081 被占用)
      • [10.4 为什么不直接使用 kubectl 修改镜像回滚?](#10.4 为什么不直接使用 kubectl 修改镜像回滚?)
      • [10.5 为什么使用 git revert,而不是 git reset?](#10.5 为什么使用 git revert,而不是 git reset?)
    • 十一、实践成果与能力总结
      • [11.1 技术成果](#11.1 技术成果)
      • [11.2 对 CI/CD 与 GitOps 的理解](#11.2 对 CI/CD 与 GitOps 的理解)
      • [11.3 后续可以继续完善的方向](#11.3 后续可以继续完善的方向)
    • [十二、DevOps 面试参考回答](#十二、DevOps 面试参考回答)
    • 十三、截图清单
    • 十四、总结

逐浪笔记 GitOps 实战:Jenkins 构建、Argo CD 同步与 Git 回滚

实践日期: 2026-10-20 至 2026-10-21

实践主题: Jenkins CI、GitOps、Argo CD、Kubernetes 应用发布与版本回滚

实践环境: 阿里云 ECS、K3s、Docker、Jenkins、Gitee、Argo CD

实验应用: nginx-demo

实验命名空间: argocd-lab


一、实践背景与目标

在 DevOps 工作中,完成一次应用部署并不意味着交付流程已经完善。除了构建和发布,我们还需要解决几个实际问题:

  1. 如何让 Jenkins 构建出来的镜像版本与 Kubernetes 部署版本保持一致?
  2. 如何避免 Jenkins 直接修改集群,使应用部署过程可追溯、可审计?
  3. 当新版本发布后出现问题,如何恢复到之前已知的版本?
  4. 如何证明回滚真正生效,而不只是 Git 仓库里的配置恢复了?
  5. 如何通过日志、Git 提交记录、Argo CD 状态和 HTTP 请求形成完整的验证证据?

为了回答这些问题,我基于逐浪笔记项目的独立实验环境,搭建并验证了一条 Jenkins + Gitee + Argo CD + K3s 的 GitOps 交付链路。

本次没有直接改动博客生产服务,而是使用独立的 Nginx 实验应用演练镜像构建、配置提交、集群同步和版本回滚,降低对现有业务的影响。

1.1 实践目标

  • 使用 Jenkins 自动构建 Docker 镜像。
  • 将镜像推送到实验环境的 Docker Registry。
  • 由 Jenkins 更新 Git 仓库中的 Kubernetes Deployment Manifest。
  • 通过 Argo CD 检测 Git 变更并手动执行同步。
  • 验证应用从 build-3 更新到 build-5。
  • 使用 git revert 撤销镜像版本更新提交。
  • 再次通过 Argo CD 同步,将应用恢复到 build-3。
  • 通过 Deployment 镜像、Pod 状态、Argo CD 状态和 HTTP 请求验证回滚结果。

1.2 最终实现效果

本次实践完成了以下过程:

build-3 → build-5 → Git revert → build-3

最终验证结果:

验证项目 最终结果
Git 回滚提交 406fa38
Git 声明的镜像 nginx-gitops-lab:build-3
Argo CD 同步状态 Synced
Argo CD 健康状态 Healthy
Kubernetes Deployment 镜像 build-3
HTTP 请求 200 OK
页面内容 逐浪笔记 GitOps Lab

截图 01:实验最终效果

建议将以下内容放在同一组截图中:

  • Gitee 中的最终回滚提交。
  • Argo CD 的 Synced、Healthy 状态。
  • Kubernetes Deployment 当前镜像。
  • HTTP 请求返回的 200 OK。

截图要证明的是:Git 版本、集群实际运行配置和服务访问结果相互一致。


二、实验架构与职责划分

2.1 整体架构

text 复制代码
开发者
  |
  | 提交代码 / 触发构建
  v
Gitee Git 仓库
  |
  | Jenkins 拉取代码
  v
Jenkins Pipeline
  |
  | 构建 Docker 镜像
  | nginx-gitops-lab:build-N
  v
Docker Registry
  |
  | Jenkins 更新 Deployment Manifest
  | Git commit + push
  v
Gitee GitOps 配置仓库
  |
  | Argo CD 检测到 Git 变更
  v
Argo CD
  |
  | 人工执行 Sync
  v
K3s / Kubernetes
  |
  | Deployment 滚动更新
  v
nginx-demo Pod
  |
  | HTTP 验证
  v
HTTP 200 OK

这里的 GitOps 配置与应用运行状态存在明确的分工:

  • Jenkins:负责持续集成、镜像构建、镜像推送和更新 Git 中的部署版本。
  • Gitee:保存版本化的 Kubernetes 配置,作为应用期望状态的记录来源。
  • Argo CD:持续监测 Git 中的配置与集群状态,并根据配置执行同步。
  • K3s / Kubernetes:负责运行 Deployment、管理 Pod 和完成滚动更新。
  • Docker Registry:保存构建出来的镜像,供 Kubernetes 拉取。
  • HTTP 验证:从服务访问层面检查应用是否可以正常响应。

本次 Argo CD 使用的是手动同步模式 。检测到 Git 变更后,先呈现 OutOfSync,再由我手动点击 Sync。不能将本次实践描述成已经启用了自动同步。

2.2 实验资源

资源 名称 / 配置
Git 仓库 https://gitee.com/flytalei/my-blog.git
Git 分支 master
独立工作副本 /opt/devops/gitops-work/my-blog
Argo CD Application nginx-gitops-lab
Kubernetes Namespace argocd-lab
Deployment nginx-demo
Service nginx-demo
Registry 127.0.0.1:5000
镜像仓库名 nginx-gitops-lab

127.0.0.1:5000 是本次实验中使用的镜像地址。该地址能否被 Kubernetes 节点访问,取决于节点及容器运行时的 Registry 配置;不能简单地将它当作所有 Kubernetes 环境通用的镜像地址。

截图 02:实验架构及资源信息

建议截图展示:

  1. Jenkins 中的 Pipeline Job。
  2. Argo CD 的 Application nginx-gitops-lab。
  3. Kubernetes 中 argocd-lab 命名空间的 Deployment、Service 和 Pod。

注意不要在截图中暴露 Jenkins 凭据、访问令牌、密码或其他敏感配置。


三、GitOps 配置文件与 Jenkins Pipeline

3.1 关键目录结构

本次实验使用以下文件:

text 复制代码
my-blog/
├── gitops/
│   ├── labs/
│   │   └── nginx-demo/
│   │       ├── namespace.yaml
│   │       ├── deployment.yaml
│   │       ├── service.yaml
│   │       └── image/
│   │           └── Dockerfile
│   └── jenkins/
│       └── nginx-gitops-lab.Jenkinsfile

其中:

  • namespace.yaml:定义实验命名空间。
  • deployment.yaml:定义应用副本、容器镜像等运行配置。
  • service.yaml:提供集群内访问入口。
  • image/Dockerfile:用于构建 Nginx 实验镜像。
  • nginx-gitops-lab.Jenkinsfile:定义 Jenkins 的自动化流水线。

截图 03:Git 仓库目录结构

建议使用终端 tree 输出、IDE 文件树或者 Gitee 文件列表截图,突出应用配置与 Jenkins Pipeline 的分离。

3.2 Deployment 中的镜像版本

本次回滚的关键配置位于:

gitops/labs/nginx-demo/deployment.yaml

通过以下命令查看镜像声明:

bash 复制代码
grep -n 'image:' gitops/labs/nginx-demo/deployment.yaml

发布 build-5 时,配置中的镜像是:

yaml 复制代码
image: 127.0.0.1:5000/nginx-gitops-lab:build-5

回滚完成后,恢复为:

yaml 复制代码
image: 127.0.0.1:5000/nginx-gitops-lab:build-3

这个字段是整个 GitOps 版本变更的核心:Git 中声明的镜像标签决定了 Kubernetes 应当运行哪个版本的应用。

实际使用中,固定版本标签比 latest 更容易追踪发布记录。不过,标签本身并不能保证镜像内容不可变;生产环境还可以进一步使用镜像摘要(digest)锁定具体镜像。

3.3 Jenkins Pipeline 的核心步骤

本次 Pipeline 包含以下主要阶段:

  1. Checkout:从 Gitee 拉取代码。
  2. Validate:检查必要的文件与配置。
  3. Build Image:构建带有版本标签的 Docker 镜像。
  4. Check Registry Tag:检查 Registry 中的目标标签。
  5. Push Image:推送镜像。
  6. Update GitOps Manifest:更新 Deployment 中的镜像标签,并提交、推送 Git 变更。

本次构建产物的命名形式为:

text 复制代码
127.0.0.1:5000/nginx-gitops-lab:build-N

其中 N 对应流水线生成的版本标签,例如 build-5。

在该流程中,Jenkins 并不直接负责最终的 Kubernetes 部署。它通过更新 Git 中的期望状态,将部署配置交给 Argo CD 处理。

截图 04:Jenkins 构建与更新配置日志

建议截取 Jenkins Console Output 中以下阶段:

  • Docker 镜像构建成功。
  • 镜像推送成功。
  • Update GitOps Manifest 阶段成功。
  • Git 提交成功。

截图应保留阶段名称和关键结果,避免只截取一个绿色的 SUCCESS,否则无法体现实际做了哪些工作。


四、第一次版本恢复:将实验基线固定到 build-3

在 build-5 发布之前,我先将实验 Deployment 的镜像版本恢复到 build-3,建立一个明确的回滚基线。

当时的 Git 提交为:

text 复制代码
ab8e7b0 rollback: restore nginx demo image to build-3

对应的配置:

yaml 复制代码
image: 127.0.0.1:5000/nginx-gitops-lab:build-3

随后检查 Argo CD 和 Kubernetes 状态,确认应用处于正常运行状态。

这一步的意义是:在演练新版本发布和回滚之前,先确认已有版本可以正常运行,避免把一个本身就存在问题的状态当作回滚目标。

需要注意,这次恢复基线的提交 ab8e7b0 与后续撤销 build-5 的提交 406fa38 是两次不同的 Git 操作,不应混为同一个回滚提交。

截图 05:回滚基线 build-3

建议包括:

  • ab8e7b0 提交记录。
  • Git 中的 build-3 镜像配置。
  • Argo CD Synced、Healthy 状态。
  • Deployment 和 Pod 运行状态。

五、Jenkins 构建并发布 build-5

5.1 触发 Jenkins Pipeline

在确认 build-3 作为实验基线后,我手动触发了 Jenkins Job:

nginx-gitops-lab-ci

流水线执行镜像构建、推送和 GitOps Manifest 更新。

本次 Jenkins 成功更新了:

gitops/labs/nginx-demo/deployment.yaml

提交记录为:

text 复制代码
5fec7e6 ci: update nginx image to build-5

5.2 检查 Git 提交与 Diff

通过 Git 历史检查新提交:

bash 复制代码
git log --oneline -5

检查提交具体修改了什么:

bash 复制代码
git show --stat --oneline 5fec7e6
git show --format=fuller 5fec7e6 -- \
  gitops/labs/nginx-demo/deployment.yaml

本次提交的核心变化只有一项:Deployment 的镜像标签由 build-3 更新为 build-5。

diff 复制代码
- image: 127.0.0.1:5000/nginx-gitops-lab:build-3
+ image: 127.0.0.1:5000/nginx-gitops-lab:build-5

这说明 Jenkins 更新的是版本化的部署配置,而不是直接在 Kubernetes 中执行一次不可追踪的临时修改。

5.3 检查远程仓库的期望镜像

bash 复制代码
git fetch origin master

git show origin/master:gitops/labs/nginx-demo/deployment.yaml \
  | grep -n 'image:'

此时远程 Git 仓库中的期望镜像为:

text 复制代码
127.0.0.1:5000/nginx-gitops-lab:build-5

5.4 Argo CD 检测到变更

在 Jenkins 成功更新 Git 仓库后,Argo CD 检测到 Git 期望状态与集群当前状态不一致。

当时的状态为:

项目 状态
Git 期望镜像 build-5
Kubernetes Deployment 镜像 build-3
Argo CD Sync OutOfSync
Argo CD Health Healthy

这里最值得注意的是:OutOfSync 并不等于应用已经发生故障。它表示 Git 中的目标配置与集群实际配置存在差异。

而 Healthy 表示 Argo CD 对当前资源健康状况的判断,两种状态关注的维度不同。

截图 06:build-5 发布前后的差异

建议组合展示:

  1. Jenkins Job 成功记录。
  2. Gitee 的 5fec7e6 提交。
  3. Git Diff 中 build-3 到 build-5 的变化。
  4. Argo CD 中 OutOfSync、Healthy 的状态。

六、通过 Argo CD 将 build-5 同步到 Kubernetes

6.1 手动执行 Sync

本次实验没有启用自动同步,而是通过 Argo CD 页面手动执行 Sync。

操作步骤:

  1. 打开 Argo CD。
  2. 找到 Application nginx-gitops-lab。
  3. 检查当前 Git Revision 与待同步配置。
  4. 点击 Sync。
  5. 确认同步操作。
  6. 等待资源同步和健康状态更新。

执行前应确认 Application 对应的是实验资源,而不是现有博客服务。

6.2 验证 Deployment 镜像

同步后,执行:

bash 复制代码
sudo k3s kubectl -n argocd-lab get deployment nginx-demo \
  -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

当时的输出:

text 复制代码
127.0.0.1:5000/nginx-gitops-lab:build-5

6.3 验证滚动更新和 Pod

bash 复制代码
sudo k3s kubectl -n argocd-lab rollout status \
  deployment/nginx-demo --timeout=60s

sudo k3s kubectl -n argocd-lab get pods -o wide

当时 Deployment 已完成滚动更新,Pod 为 1/1 Running,运行的镜像为 build-5。

这一步验证了 Kubernetes 已按照更新后的 Deployment 配置完成版本切换。

需要区分:Deployment 镜像正确、Pod 正常运行和业务 HTTP 请求成功是不同层面的验证。本次 build-5 阶段已验证 Deployment 与 Pod 状态;最终回滚阶段另外进行了 HTTP 验证。

6.4 观察 Argo CD 最终状态

同步完成后,Argo CD 显示:

text 复制代码
Sync: Synced
Health: Healthy

这说明 Git 配置已被同步,Argo CD 判断应用资源健康。

截图 07:build-5 同步完成

建议展示:

  • Argo CD Application 的 Synced、Healthy 状态。
  • Deployment 的镜像为 build-5。
  • Pod 为 Running。
  • 滚动更新成功的终端输出。

七、核心演练:通过 Git revert 回滚到 build-3

本次实践最重要的部分是:新版本发布后,如何在不直接修改 Kubernetes 资源的情况下,将应用恢复到之前的版本。

7.1 确认当前 Git 历史

发布 build-5 后,Git 历史中存在:

text 复制代码
5fec7e6 ci: update nginx image to build-5
ab8e7b0 rollback: restore nginx demo image to build-3

其中 5fec7e6 是 Jenkins 自动生成的镜像版本更新提交。

我选择使用 git revert 撤销这次提交,而不是使用 git reset 改写历史。

这样做有几个好处:

  • 保留原始发布记录。
  • 明确记录回滚动作。
  • 适合团队协作和审计。
  • 可以清楚区分发布提交与回滚提交。

7.2 为什么先检查远程仓库

在执行回滚前,我先获取远程 master 的最新记录:

bash 复制代码
git fetch origin master

git log --oneline --decorate -5

并检查待撤销提交:

bash 复制代码
git show --stat --oneline 5fec7e6

git show 5fec7e6 -- \
  gitops/labs/nginx-demo/deployment.yaml

确认该提交只修改了实验 Deployment 中的镜像标签,避免撤销其他不相关的业务改动。

这一步体现的是变更管理意识:回滚之前先确定回滚对象和影响范围。

7.3 同步工作副本并执行 revert

在独立工作副本 /opt/devops/gitops-work/my-blog 中执行。

先检查工作区:

bash 复制代码
git status --short

只有在确认不存在需要保留的未提交修改后,才继续操作。

随后:

bash 复制代码
git switch master
git pull --ff-only origin master
git revert --no-edit 5fec7e6

这里使用 --ff-only,是为了避免拉取远程更新时意外创建额外的合并提交。

git revert --no-edit 5fec7e6 则会生成一个新的提交,用反向补丁撤销 5fec7e6 的变更。

7.4 验证回滚提交

本次生成的回滚提交为:

text 复制代码
406fa38 Revert "ci: update nginx image to build-5"

检查回滚后的镜像:

bash 复制代码
grep -n 'image:' gitops/labs/nginx-demo/deployment.yaml

预期结果:

text 复制代码
image: 127.0.0.1:5000/nginx-gitops-lab:build-3

检查本次回滚提交的差异:

bash 复制代码
git show --stat --oneline HEAD
git diff --check HEAD^

确认没有空白错误后,将回滚提交推送到远程仓库:

bash 复制代码
git push origin master

再检查远程分支:

bash 复制代码
git fetch origin master

git log -1 --oneline origin/master

git show origin/master:gitops/labs/nginx-demo/deployment.yaml \
  | grep -n 'image:'

本次远程仓库最终记录为:

text 复制代码
406fa38 Revert "ci: update nginx image to build-5"

Git 中的镜像期望状态恢复为 build-3。

截图 08:Git revert 回滚过程

建议包含:

  1. 5fec7e6 原始发布提交。
  2. 406fa38 新生成的 revert 提交。
  3. 回滚提交的 Diff。
  4. 远程 master 上的最新提交。
  5. 最终 Manifest 中的 build-3。

重点应放在两个提交之间的关系:原始提交没有被删除,而是通过新提交撤销其修改。


八、通过 Argo CD 将 Kubernetes 恢复到 build-3

8.1 理解 Git 回滚与集群回滚的区别

执行 git revert 后,Git 中的期望状态已经恢复为 build-3,但这并不意味着 Kubernetes 会因为 Git 提交本身而立即完成回滚。

本次 Argo CD 使用手动同步模式,因此仍需要执行 Sync。

这也是 GitOps 与直接执行 kubectl set image 的重要区别之一:先恢复声明式配置,再让负责协调的工具将配置应用到集群。

8.2 在 Argo CD 中执行 Sync

操作步骤:

  1. 打开 Application nginx-gitops-lab。
  2. 确认最新 Revision 对应提交 406fa38。
  3. 确认 Git 配置中的镜像为 build-3。
  4. 点击 Sync。
  5. 等待同步结束。
  6. 检查 Application 状态。

同步后,Argo CD 状态为:

text 复制代码
Sync: Synced
Health: Healthy
Revision: 406fa3865c4638c6c936a70a1091218392d5f855

8.3 验证 Kubernetes 中的镜像

执行:

bash 复制代码
sudo k3s kubectl -n argocd-lab get deployment nginx-demo \
  -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

本次验证输出:

text 复制代码
127.0.0.1:5000/nginx-gitops-lab:build-3

这证明 Kubernetes Deployment 中声明的当前容器镜像已恢复到 build-3。

8.4 验证滚动更新与 Pod

bash 复制代码
sudo k3s kubectl -n argocd-lab rollout status \
  deployment/nginx-demo --timeout=60s

sudo k3s kubectl -n argocd-lab get pods \
  -o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[*].ready,IMAGE:.spec.containers[*].image,PHASE:.status.phase'

需要确认:

  • Deployment 滚动更新成功。
  • Pod 为 Running。
  • 容器处于 Ready 状态。
  • Pod 使用 build-3 镜像。

如果同步后仍显示旧版本,应先检查 Argo CD 是否完成同步、Deployment 是否完成滚动更新,以及新 Pod 是否正常启动,不要立即通过手动修改 Deployment 来掩盖问题。

截图 09:Argo CD 回滚同步成功

建议截图展示:

  • Application Revision 对应 406fa38。
  • Synced、Healthy 状态。
  • Deployment 当前镜像为 build-3。
  • rollout status 成功结果。
  • 新 Pod 的 Ready、Running 状态。

九、最终验证:通过 HTTP 请求检查服务

仅仅确认 Git 配置和 Deployment 镜像正确,还不足以完整证明应用可以正常访问。因此,我又进行了一次 HTTP 验证。

9.1 启动端口转发

最初使用的本地端口 18081 已被占用,命令返回:

text 复制代码
Unable to listen on port 18081:
bind: address already in use

这个错误属于本机端口绑定冲突,不代表 Kubernetes 中的 Nginx 服务发生故障。

为了避免影响其他进程,我没有直接杀掉占用端口的程序,而是改用另一个本地端口 18082。

执行:

bash 复制代码
sudo k3s kubectl -n argocd-lab \
  port-forward svc/nginx-demo 18082:80

端口转发成功后,保持当前终端运行,再打开另一个终端进行访问。

9.2 执行 HTTP 请求

bash 复制代码
curl -sS -i --max-time 10 http://127.0.0.1:18082/

本次实际返回:

http 复制代码
HTTP/1.1 200 OK
Server: nginx/1.27.5
Content-Type: text/html

响应正文:

html 复制代码
<h1>逐浪笔记 GitOps Lab</h1>
<p>Built by Jenkins CI</p>

9.3 HTTP 验证说明

HTTP 200 OK 说明这次通过本地端口转发访问 Service 的请求得到了成功响应,页面内容也正常返回。

结合此前已经确认的 Git 回滚提交、Argo CD Revision、Deployment 镜像和 Pod 状态,可以形成比较完整的回滚验证证据链。

但需要说明,HTTP 200 并不能独立证明所有业务功能都正常。本次实验的验证范围是 Nginx GitOps 实验应用,不代表已经完成了逐浪笔记后端、数据库及所有业务接口的回归测试。

截图 10:HTTP 回滚验证

请保留以下真实终端截图:

  • 端口转发成功的输出。
  • curl -i 请求命令。
  • HTTP/1.1 200 OK。
  • Nginx Server 信息及返回正文。

这张截图是整个实践的最终访问验证证据。


十、问题排查与实践经验

10.1 Git 中的版本与 Kubernetes 中的版本不一致

现象: Git 中已经修改了镜像标签,但集群仍运行旧版本。

排查思路:

  1. 检查远程 Git 中的 Manifest。
  2. 检查 Argo CD 的 Sync 状态和 Revision。
  3. 确认是否执行了手动 Sync。
  4. 检查 Deployment 镜像。
  5. 检查滚动更新状态和 Pod 镜像。

本次实践的结论: Git 提交只是更新了期望状态;在手动同步模式下,需要进一步执行 Argo CD Sync,集群才会应用新的配置。

10.2 Git 回滚后应用没有立即回退

现象: git revert 已经生成提交,但集群仍可能运行旧版本。

原因: Git 仓库中的声明式配置和 Kubernetes 的实际运行状态是两个不同层面。

解决方式:

  1. 确认 revert 提交已经推送到远程。
  2. 确认 Argo CD 已识别新 Revision。
  3. 手动 Sync。
  4. 检查 Deployment 和 Pod。
  5. 通过 HTTP 请求验证服务。

10.3 本地端口 18081 被占用

现象:

text 复制代码
bind: address already in use

原因: 本机已有其他进程监听该端口。

处理方式: 改用 18082 进行端口转发,避免影响原有进程。

这体现了一个简单但实用的运维原则:排查端口冲突时,先区分本机访问工具的问题与集群应用的问题,不要因为一个辅助命令失败就认定服务故障。

10.4 为什么不直接使用 kubectl 修改镜像回滚?

直接执行 kubectl set image 可以修改 Deployment,但如果 Git 中仍保留错误的新版本配置,Argo CD 后续同步时可能再次把配置改回去。

在 GitOps 流程中,更合理的做法是先恢复 Git 中的期望状态,再由 Argo CD 负责同步。

这有利于保持配置一致性,并保留可审计的变更历史。

10.5 为什么使用 git revert,而不是 git reset?

git revert 通过新增提交撤销旧提交,适合已经推送、需要保留历史的协作分支。

git reset 则可能移动分支指针;如果再强制推送,可能改写其他协作者依赖的提交历史。

本次发布提交已经推送到远程,因此使用 git revert 更符合可追溯的回滚实践。


十一、实践成果与能力总结

通过本次实践,我完成了从镜像构建到 GitOps 回滚的完整实验闭环。

11.1 技术成果

  • 搭建并验证 Jenkins 自动构建 Nginx 实验镜像的流水线。
  • 实现 Jenkins 更新 Git 中的 Kubernetes 镜像版本。
  • 理解 GitOps 中 Git 期望状态与集群实际状态的区别。
  • 验证 Argo CD 手动同步和 Kubernetes 滚动更新。
  • 使用 git revert 保留历史地撤销镜像版本更新。
  • 将应用从 build-5 恢复到 build-3。
  • 通过 Argo CD 状态、Deployment 镜像、Pod 状态和 HTTP 请求完成多层验证。
  • 在独立实验命名空间内进行操作,避免直接影响现有博客服务。

11.2 对 CI/CD 与 GitOps 的理解

本次实践进一步明确了各组件的职责:

  • CI: Jenkins 负责获取代码、构建镜像、推送制品及执行必要的构建检查。
  • GitOps: Git 仓库记录部署期望状态,Argo CD 监测并协调集群状态。
  • CD: 本次通过 Argo CD 手动 Sync 完成部署配置的应用。
  • Rollback: 通过 Git revert 恢复已知版本的配置,再由 Argo CD 同步回集群。

需要注意,当前实验使用手动同步,并未验证自动同步、自动回滚或自动故障恢复机制,因此不应将这些能力描述为本次已经实现的功能。

11.3 后续可以继续完善的方向

在本次闭环完成后,可以逐步补充:

  1. 将实验过程写入项目仓库,形成可复现的实践文档。
  2. 为 Jenkins Pipeline 增加构建失败和推送失败场景的演练。
  3. 对比 GitOps 回滚与 Kubernetes Deployment 历史回滚。
  4. 研究 Argo CD 自动同步、Prune、Self-Heal 的行为与风险。
  5. 在独立实验应用上验证发布失败后的恢复策略。
  6. 进一步学习镜像摘要、健康检查、可观测性和发布审批。

这些扩展都应在独立实验资源中逐步验证,避免直接影响现有博客服务及数据库。


十二、DevOps 面试参考回答

面试官:你有没有实践过 CI/CD 部署和版本回滚?

我在自己的逐浪笔记项目中搭建了 Jenkins、Gitee、Argo CD 和 K3s 的 GitOps 实验链路。

Jenkins 负责构建 Docker 镜像并推送到 Registry,然后更新 Git 仓库中的 Kubernetes Deployment Manifest。Argo CD 监测 Git 中的配置变化,由我手动执行 Sync,将期望状态同步到 K3s 集群。

在回滚演练中,我先发布了 build-5,并验证了 Deployment 和 Pod 的运行状态。之后使用 git revert 撤销镜像版本更新提交,将 Manifest 中的镜像恢复到 build-3,再通过 Argo CD Sync 完成集群回滚。

最后,我检查了 Argo CD 的 Synced、Healthy 状态,确认 Deployment 使用 build-3 镜像、Pod 正常运行,并通过 HTTP 请求获得 200 OK。

这次实践让我理解了 GitOps 的核心:Git 保存期望状态,Argo CD 负责将期望状态协调到集群,回滚不仅要恢复配置,还要验证集群和服务是否真正恢复。


十三、截图清单

正式发布到逐浪笔记之前,建议按以下顺序插入真实截图:

编号 截图内容 证明目标
01 最终回滚状态汇总 Git、Argo CD、Kubernetes 与 HTTP 结果一致
02 Jenkins、Argo CD、K3s 实验资源 说明整体架构与资源边界
03 GitOps 目录结构 展示配置文件组织方式
04 Jenkins 构建和推送日志 证明镜像构建与配置更新流程
05 build-3 基线状态 证明回滚前存在已知版本
06 build-5 提交 Diff 与 OutOfSync 证明新版本变更被 GitOps 检测到
07 build-5 同步成功 证明 Argo CD 与 Kubernetes 完成版本更新
08 406fa38 Git revert 记录 证明回滚通过新增 Git 提交完成
09 build-3 同步与 Pod 验证 证明 Kubernetes 恢复到目标版本
10 HTTP 200 返回正文 证明最终访问路径可以正常响应

建议图片命名统一使用:

text 复制代码
images/
├── 01-final-state.png
├── 02-architecture.png
├── 03-gitops-files.png
├── 04-jenkins-pipeline.png
├── 05-build-3-baseline.png
├── 06-build-5-git-diff.png
├── 07-argocd-build-5.png
├── 08-git-revert.png
├── 09-rollback-build-3.png
└── 10-http-200.png

以上为建议的图片文件名,并不表示这些图片已经生成或保存。正式整理时,应使用实际截图替换对应位置。


十四、总结

本次 GitOps 实战从 Jenkins 构建镜像开始,经过 Git 配置更新、Argo CD 同步、版本发布、Git revert 和再次同步,最终将实验应用恢复到 build-3,并通过 HTTP 请求完成验证。

这次实践的重点并不是简单地把镜像标签改回去,而是理解并验证完整的交付闭环:

构建有记录、配置有版本、发布可追踪、回滚有依据、结果可验证。

对于 DevOps 工程师而言,能够解释每个组件的职责、定位期望状态与实际状态之间的差异,并用真实命令和验证结果证明恢复成功,比单纯记住工具的概念更有价值。

相关推荐
叼烟扛炮1 小时前
Linux 学习笔记(八):GCC 编译器的四大阶段与链接原理
linux·笔记·学习
Z21-X1 小时前
云原生运维学习笔记:从云计算概念到服务器硬件的入门之旅
运维·笔记·学习·云原生
滴啦嘟啦哒1 小时前
【具身笔记】【Piper+PI0.5】一、基于键盘实现数据采集
笔记·vla·具身
叼烟扛炮2 小时前
Linux 学习笔记(十六):进程的调度与优先级——谁先抢到 CPU?
linux·笔记·学习
衫水2 小时前
Windows 端 OpenSSL 安装与自签证书生成笔记
windows·笔记
熊出没2 小时前
CommitLoom 使用教程:在 IntelliJ IDEA 中自动生成 Git 提交信息
java·git·intellij-idea
叼烟扛炮2 小时前
Linux 学习笔记(三):文件管理与文本查看
linux·笔记·学习
海绵宝宝转agent2 小时前
2026-10-21学习笔记
笔记·学习·算法
动词ing2 小时前
【学习笔记】51单片机 点亮一个LED灯
笔记·学习·51单片机