Rancher、Docker、K8s、Jenkins、ArgoCD:五个工具,一条流水线
云原生后端的技术栈很长,但真正串起"从代码到上线"这条主线的,就五个工具:Docker、Jenkins、K8s、ArgoCD、Rancher。每个工具解决一个特定问题,环环相扣。
这篇文章不讲怎么安装,只讲清楚两件事:每个工具是什么、解决什么问题,以及它们怎么串成一条完整的交付流水线。
一、五个工具各自是什么
先逐个搞清楚定位,再看怎么协作。
Docker:解决环境一致性
一句话:把应用和它的所有依赖打包成一个不可变的镜像,到哪里都能跑。
没有 Docker 之前,"在我机器上能跑"是后端开发最常见的甩锅。开发用 Java 11,测试环境 Java 8,生产环境某个依赖库版本不同——环境不一致导致的 bug 极难排查。
Docker 的解法是:把代码、运行时、依赖库、配置文件全部打到一个镜像里。镜像是一个不可变的制品,开发、测试、生产用的是同一个镜像,环境差异从源头消除。
产出物:一个带版本号的 Docker 镜像(如user-service:v1.2.3)。
Jenkins:解决自动化构建
一句话:代码 push 之后自动触发编译、测试、打包、推镜像,全程不需要人干预。
Docker 解决了"怎么打包",但"谁来打包"还是问题。总不能每次合代码都手动跑mvn package、docker build、docker push。Jenkins 就是那个自动化的流水线引擎。
Jenkins 的核心是 Pipeline——一段声明式脚本,定义了从代码拉取到镜像推送的完整步骤:
pipeline{agent any stages{stage('编译'){steps{sh'mvn clean package -DskipTests'}}stage('测试'){steps{sh'mvn test'}}stage('打镜像'){steps{sh'docker build -t user-service:v1.2.3 .'}}stage('推镜像'){steps{sh'docker push registry.example.com/user-service:v1.2.3'}}}}代码合并到主分支 → Jenkins 自动触发 → 编译 → 测试 → 打镜像 → 推到镜像仓库。CI(持续集成)到这一步结束。
产出物:一个已推送到镜像仓库的 Docker 镜像。
K8s:解决容器编排和调度
一句话:管理一堆机器上的容器,负责自动部署、弹性伸缩、故障自愈、滚动更新。
镜像推到仓库了,但"在哪些机器上跑几个副本、挂了怎么办、流量怎么分过去"这些问题 Docker 自己解决不了。K8s 就是那个调度中枢。
K8s 里的几个核心概念:
- Pod:最小调度单位,里面跑一个或多个容器。
- Deployment:定义要跑几个副本、用什么镜像、怎么更新。
- Service:给一组 Pod 提供固定的访问入口(IP 和域名),Pod 挂了重建换 IP,Service 不变。
- Ingress:把集群内的 Service 暴露给公网,支持域名路由和 HTTPS。
- ConfigMap/Secret:配置和敏感信息管理,跟镜像解耦。
一份 K8s 部署文件大概长这样:
apiVersion:apps/v1kind:Deploymentmetadata:name:user-servicespec:replicas:3# 跑 3 个副本selector:matchLabels:app:user-servicetemplate:metadata:labels:app:user-servicespec:containers:-name:user-serviceimage:registry.example.com/user-service:v1.2.3ports:-containerPort:8080K8s 拿着这份 YAML,在集群里拉起 3 个 Pod,自动负载均衡,某个 Pod 挂了会自动重启。
产出物:一个在集群中稳定运行的应用实例。
ArgoCD:解决持续部署的配置漂移
一句话:监听 Git 仓库里的 K8s YAML 变化,自动同步到集群,保证集群状态和 Git 声明永远一致。
CD(持续部署)有两种模式:
| Push 模式 | Pull 模式 | |
|---|---|---|
| 代表 | Jenkins 做 CD | ArgoCD |
| 方式 | 主动kubectl apply推到集群 | 监听 Git 变化,自动拉取并同步 |
| 配置漂移 | 有人手动改集群,Jenkins 不知道 | 集群与 Git 不一致时自动修正回来 |
Push 模式的问题:有人在集群里手动改了配置(比如改了副本数),Jenkins 下次部署会覆盖掉,但中间这段时间集群状态和 Git 是不一致的——这叫"配置漂移"。
ArgoCD 用 Pull 模式 + GitOps 解决这个问题:
- 所有 K8s YAML 存在 Git 仓库里。
- ArgoCD 持续监听这个仓库。
- 有人改了 Git 里的 YAML,ArgoCD 自动同步到集群。
- 有人手动改了集群,ArgoCD 发现不一致,会强制同步回 Git 的声明。
Git 仓库成为唯一真实来源(Single Source of Truth)。不在集群里敲命令,在 Git 里改文件。
产出物:集群状态与 Git 声明始终一致的持续部署机制。
Rancher:解决多集群管理
一句话:统一纳管多个 K8s 集群,提供可视化界面、项目隔离、应用商店。
一个团队可能有多个 K8s 集群:开发集群、测试集群、生产集群,甚至多云多地域。每个集群都要kubectl连上去管理,切来切去很烦。
Rancher 把这些集群统一纳管到一个界面里:
- 多集群管理:一个页面看到所有集群的状态。
- 可视化操作:不用敲
kubectl,点按钮就能部署、扩缩容、看日志。 - 项目隔离:按项目/团队划分权限和资源。
- 应用商店:一键安装常用组件(监控、日志等)。
Rancher 不是 K8s 的替代品,是 K8s 的管理平台。底下跑的还是 K8s,Rancher 是上面那层"管理面板"。
产出物:一个统一的多集群管理入口。
二、五个工具怎么串成一条流水线
概念清楚了,下面看它们怎么协作。以一个 Spring Boot 服务的完整交付流程为例。
完整流程图
开发写代码 ↓ Git push 到 GitLab/GitHub ↓ Jenkins 自动触发 CI 流水线 ├→ mvn clean package (编译) ├→ mvn test (单元测试) ├→ docker build (打镜像) └→ docker push (推到 Harbor/ACR) ↓ 开发者修改 K8s YAML 仓库 (把镜像版本号改成 v1.2.3) ↓ ArgoCD 监听到 Git 仓库变化 ├→ 拉取最新 YAML └→ kubectl apply 到 K8s 集群(自动同步) ↓ K8s 拉起新版本 Pod ├→ 滚动更新(逐个替换旧 Pod) ├→ Service 流量自动切换 └─ 故障自愈(Pod 挂了自动重启) ↓ Rancher 界面查看部署状态 ├→ 看 Pod 日志 ├→ 看资源使用率 └→ 排障、扩缩容逐环节拆解
环节 1:开发提交代码
开发者写完 Spring Boot 代码,本地用 Docker Compose 跑起 MySQL + Redis 依赖,自测通过后推到 Git 仓库的功能分支,发起 MR/PR。代码审查通过后合并到主分支。
环节 2:Jenkins 做 CI
Jenkins 监听到主分支有新代码,自动触发流水线:编译 Java 代码 → 跑单元测试 →docker build打镜像 →docker push推到镜像仓库。
到这一步,CI 结束。产出物是registry.example.com/user-service:v1.2.3这个镜像。
关键点:Jenkins 只负责把代码变成镜像,不负责部署。很多团队让 Jenkins 直接kubectl apply做 CD,这其实混了职责。现代实践是 Jenkins 只管 CI。
环节 3:改 Git 里的 K8s YAML
有一个独立的 Git 仓库存放 K8s 部署文件(YAML)。CI 完成后,开发者(或自动化脚本)修改这个仓库里的镜像版本号:
# 从image:registry.example.com/user-service:v1.2.2# 改成image:registry.example.com/user-service:v1.2.3提交这个改动到 Git。
环节 4:ArgoCD 做 CD
ArgoCD 持续监听 YAML 仓库。发现 Git 里的镜像版本号变了,自动拉取最新 YAML,通过kubectl apply同步到 K8s 集群。
如果有运维手动在集群里改了配置,ArgoCD 会发现集群状态和 Git 不一致,强制同步回 Git 的声明。Git 是唯一真实来源。
环节 5:K8s 执行部署
K8s 收到新的 Deployment 声明,开始滚动更新:逐个创建新版本 Pod,就绪后替换旧 Pod,旧 Pod 优雅下线。Service 的流量自动切换到新 Pod。
如果新版本有问题(比如启动失败),K8s 的健康检查会阻止新 Pod 接入流量,旧版本继续服务,给排查争取时间。
环节 6:Rancher 监控和排障
部署完成后,开发或运维通过 Rancher 界面查看:
- 新版本 Pod 是否全部 Running
- Pod 日志有没有异常
- CPU/内存使用率是否正常
- 需要扩容时直接在 Rancher 界面改副本数
不用敲kubectl,不用切集群上下文,一个界面搞定。
三、职责边界:谁干什么
五个工具的职责很容易混淆,尤其 Jenkins 和 ArgoCD、K8s 和 Rancher。画个线:
| 工具 | 职责 | 不干什么 |
|---|---|---|
| Docker | 打包应用为镜像 | 不管部署、不管调度 |
| Jenkins | CI:编译→测试→打镜像→推仓库 | 不直接部署到 K8s(交给 ArgoCD) |
| ArgoCD | CD:监听 Git→同步到 K8s | 不管编译、不管打镜像 |
| K8s | 容器调度:部署、伸缩、自愈 | 不管多集群统一界面(交给 Rancher) |
| Rancher | 多集群管理:可视化、纳管 | 不替代 K8s,底下还是 K8s |
最容易踩的坑是让 Jenkins 同时做 CI 和 CD。Jenkins 做 CD(Push 模式)的问题是没有配置漂移修正能力,回滚也不优雅。让 Jenkins 和 ArgoCD 各干各的,职责清晰,问题好排查。
四、一个实际场景串一遍
假设要上线用户服务 v2.0,增加了新功能:手机号登录。
- 开发:本地写代码,用 Docker Compose 跑依赖,自测通过。
- 提交:代码推到 Git 功能分支,发起 MR,审查通过合并到主分支。
- CI:Jenkins 自动触发——编译 Java、跑测试、
docker build打镜像user-service:v2.0.0、推到 Harbor。 - 改 YAML:修改部署仓库的 Deployment YAML,镜像版本改成
v2.0.0,提交到 Git。 - CD:ArgoCD 监听到 YAML 变化,自动同步到 K8s 测试集群。先在测试集群验证。
- K8s 部署:滚动更新,3 个新 Pod 逐个替换旧 Pod,Service 流量自动切换。
- Rancher 查看:在 Rancher 界面看测试集群的 Pod 状态和日志,验证没问题。
- 推生产:把同一个 YAML 的目标集群改成生产集群,ArgoCD 自动同步到生产 K8s。同样的滚动更新流程。
- 监控:通过 Rancher 界面看生产集群的 CPU、内存、Pod 状态,确认服务稳定。
整个过程:代码到镜像是 Jenkins 的事,镜像到集群是 ArgoCD 的事,集群内调度是 K8s 的事,多集群看是 Rancher 的事。Docker 贯穿始终,提供不可变制品。
五、为什么是这五个
这五个工具不是随便选的,它们刚好覆盖了交付流水线的五个关键环节:
- 打包(Docker):代码怎么变成可部署的制品。
- 构建(Jenkins):怎么自动化地把代码变成镜像。
- 调度(K8s):镜像怎么在集群里跑起来、跑得稳。
- 部署(ArgoCD):怎么把镜像安全、可追溯地推到集群。
- 管理(Rancher):多个集群怎么统一看、统一管。
少一个就有缺口:没有 Docker,环境一致性没法保证;没有 Jenkins,手动打包效率低;没有 K8s,容器调度靠手动;没有 ArgoCD,部署配置容易漂移;没有 Rancher,多集群管理靠切命令行。