一、CI/CD 到底是什么?
CI/CD 是「代码 → 容器镜像 → 部署到 K8s 运行」的完整流程,分 3 个核心阶段:
1. CI(持续集成,Continuous Integration):代码 → 容器镜像
- 做的事:
- 从 Git 仓库拉取最新的源代码
- 编译 / 打包代码(比如 Java 项目
mvn package、Go 项目go build) - 编写 Dockerfile,把编译好的程序打包成容器镜像
- 把镜像推送到镜像仓库(比如 Harbor、Docker Hub、阿里云镜像服务)
- 常用工具:Jenkins、GitLab CI、GitHub Actions、GitLab Runner、Argo Workflows 等
2. CD(持续交付 / 部署,Continuous Delivery/Deployment):镜像 → 部署到 K8s
- 做的事:
- 从镜像仓库拉取最新的镜像
- 更新 K8s 的 Deployment/StatefulSet 等资源的镜像版本
- 触发 K8s 滚动更新,把旧 Pod 替换成新镜像的 Pod
- 验证服务正常运行
二、K8s 在这个流程里,管什么、不管什么?
K8s 只负责:最终的「部署运行」环节
K8s 的核心工作,是运行已经打包好的容器镜像:
- 你给 K8s 一个 Deployment YAML,里面写了
image: nginx:1.25.3,K8s 就会:- 拉取这个镜像
- 创建 Pod 运行容器
- 维护 Pod 的状态(挂了自动重启、数量不够自动扩容)
- 完成滚动更新、回滚等操作
- 简单说:K8s 只认「容器镜像」,不认「源代码」。
K8s 完全不管:「代码 → 镜像」的 CI 过程
K8s 不会参与、也不会干涉代码变成镜像的任何步骤:
- 不管你用什么工具做 CI:Jenkins、GitLab CI、GitHub Actions、甚至手动
docker build,K8s 都不关心 - 不管你用什么构建流程:是每次提交代码自动构建,还是手动触发构建,K8s 都不干涉
- 不管你用什么镜像仓库:Harbor、Docker Hub、私有仓库,K8s 只负责拉取,不负责镜像的构建和推送
- 不管你用什么语言 / 框架:Java、Go、Python、Node.js,K8s 都不参与编译打包,只运行最终的容器
三、实际例子
场景:把一个 Java Web 项目部署到 K8s
1. CI 阶段(K8s 完全不参与,企业自己做)
- 开发提交代码到 GitLab
- GitLab CI 自动触发流水线:
- 拉取代码 →
mvn clean package编译打包成 jar 包 - 编写 Dockerfile,把 jar 包打包成镜像
my-app:v1.0.0 - 把镜像推送到 Harbor 私有仓库
- 拉取代码 →
- 这个过程和 K8s 没有任何关系,K8s 完全不知道代码的存在。
2. CD 阶段(K8s 只负责最后一步)
- CD 工具(比如 Argo CD、Jenkins)从 Harbor 拉取
my-app:v1.0.0 - 更新 K8s 的 Deployment YAML,把镜像版本改成
my-app:v1.0.0 - K8s 收到更新请求后,执行滚动更新 :
- 拉取新镜像
- 创建新 Pod,启动容器
- 销毁旧 Pod
- 确保最终运行的 Pod 数量符合期望
- 这里 K8s 只做「运行容器」的事,完全不关心镜像怎么来的。
四、为什么 K8s 要这么设计?
- 解耦:把「构建流程」和「运行平台」彻底分开,企业可以自由选择适合自己的 CI/CD 工具和流程,不用被 K8s 绑定。
- 通用性:K8s 只需要支持容器运行,就能适配所有语言、所有构建流程的应用,不用为不同语言做适配。
- 职责清晰:K8s 专注做「容器编排」,CI/CD 工具专注做「代码构建」,各司其职,系统更稳定、更易维护。
五、常见误区纠正
- 误区:K8s 可以直接部署源代码 纠正:K8s 不能直接运行源代码,必须先把代码打包成容器镜像,K8s 才能运行。
- 误区:K8s 自带 CI/CD 功能 纠正:K8s 本身没有 CI/CD 能力,需要配合 Jenkins、GitLab CI 等工具使用,K8s 只负责最终的部署环节。
- 误区:K8s 会干涉 CI/CD 流程 纠正:K8s 完全不干涉 CI/CD 的流程设计,企业可以根据自己的需求自定义流程,K8s 只执行最终的部署操作。
六、总结
K8s 是「容器的运行平台」,不是「代码的构建平台」。它只负责运行已经打包好的容器,不负责把代码变成容器的过程。