CI 流水线构建出 Docker 镜像后,下一步就是将其部署到 Kubernetes 集群。这是 CD(持续部署)的核心环节。本章介绍两种主流的自动化部署方式:直接式部署(CI 调用 kubectl/Helm 命令)和 声明式部署(GitOps) (CI 更新 Git 仓库,由 ArgoCD 同步集群)。你将学会如何安全地将 CI 与 K8s 集群集成,并实现多环境部署和自动回滚。
一、Kubernetes 部署的两种模式
在 CI/CD 体系中,部署到 Kubernetes 有两种主流模式:

GitOps 的核心原则是:Git 仓库是集群期望状态的唯一事实源,集群中的实际状态会持续与 Git 中的声明式配置进行比对和同步。这种方式已成为云原生环境下的部署标准。
二、直接式部署:CI 调用 kubectl / Helm
2.1 前置条件:CI 与 K8s 集群的认证
要让 CI 流水线操作 K8s 集群,需要建立认证通道。主要有两种方式:
方式一:Kubeconfig 注入(简单但不推荐生产)
将集群的 kubeconfig 文件内容存储在 CI/CD 变量中,在流水线中写入 ~/.kube/config。
yaml
# GitLab CI 示例
deploy:
stage: deploy
image: bitnami/kubectl:latest
before_script:
- mkdir -p $HOME/.kube
- echo "$KUBECONFIG" | base64 -d > $HOME/.kube/config
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production
- kubectl rollout status deployment/myapp -n production
⚠️ 风险:kubeconfig 包含集群管理员凭证,存储在 CI 变量中存在泄露风险。生产环境建议使用更安全的方式。
方式二:GitLab Kubernetes Agent(推荐 GitLab 用户)
GitLab 提供了 Kubernetes Agent,可在不暴露集群凭证的情况下,通过代理安全地执行 kubectl 和 helm 命令。
yaml
# .gitlab-ci.yml
stages:
- setup
- deploy
create-registry-secret:
stage: setup
image: "portainer/kubectl-shell:latest"
variables:
AGENT_KUBECONTEXT: my-group/my-project:production
script:
- kubectl config use-context $AGENT_KUBECONTEXT
- kubectl create secret docker-registry gitlab-registry-auth
--docker-server="${CI_REGISTRY}"
--docker-username="${CONTAINER_REGISTRY_ACCESS_USERNAME}"
--docker-password="${CONTAINER_REGISTRY_ACCESS_TOKEN}"
-n production
Agent 会自动注入到 Runner 环境中,无需在 CI 中存储 kubeconfig。
方式三:GitHub Actions + OIDC(推荐 GitHub 用户)
使用 OpenID Connect 实现无长期凭证的认证:
yaml
- name: Configure kubectl
uses: azure/setup-kubectl@v4
- name: Set up kubeconfig
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config
更安全的做法是使用 OIDC 联邦认证,由云平台(AWS/Azure/GCP)动态颁发短期凭证。
2.2 使用 kubectl 直接部署
基础部署:更新镜像并等待状态
yaml
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production
- kubectl rollout status deployment/myapp -n production
预校验:在正式部署前检查配置是否正确
yaml
- kubectl apply -f k8s/ --dry-run=client -o yaml
多环境部署:通过不同命名空间和环境变量区分
yaml
deploy-staging:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n staging
- kubectl rollout status deployment/myapp -n staging
only:
- develop
deploy-production:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production
- kubectl rollout status deployment/myapp -n production
only:
- main
when: manual
2.3 使用 Helm 进行更灵活的部署
Helm 是 Kubernetes 的包管理工具,通过 Chart 将多个 K8s 资源打包管理。在 CI 中使用 Helm 部署是更推荐的方式。
在 CI 中安装 Helm 并执行部署:
yaml
deploy-helm:
stage: deploy
image: alpine/helm:3.14
before_script:
- mkdir -p $HOME/.kube
- echo "$KUBECONFIG" | base64 -d > $HOME/.kube/config
script:
# 更新 Chart 依赖
- helm dependency build ./chart
# 语法检查
- helm lint ./chart
# 预渲染验证(干跑)
- helm upgrade --install myapp ./chart -f values/production.yaml --dry-run
# 正式部署
- helm upgrade --install myapp ./chart -f values/production.yaml \
--set image.tag=$CI_COMMIT_SHORT_SHA \
--namespace production \
--atomic
关键参数说明:
--install:如果 Release 不存在则创建,存在则升级
--atomic:如果升级失败,自动回滚到上一个版本
--dry-run:预览将要生成的 K8s 资源,不实际部署
-f:指定环境对应的 values 文件
使用 values 文件管理多环境:
text
chart/
├── values.yaml # 默认配置
├── values/
│ ├── dev.yaml # 开发环境覆盖
│ ├── staging.yaml # 预发布环境覆盖
│ └── production.yaml # 生产环境覆盖
yaml
deploy:
script:
- helm upgrade --install myapp ./chart \
-f values/${ENV}.yaml \
--set image.tag=$CI_COMMIT_SHORT_SHA
三、GitOps 模式:声明式部署与 ArgoCD
GitOps 将部署从"推"变为"拉":CI 流水线只负责构建镜像并更新 Git 仓库中的部署清单,而 ArgoCD 持续监控 Git 仓库的变化,自动将集群状态同步到期望状态。
3.1 架构对比
text
【直接式部署】
CI → kubectl/helm → K8s 集群(CI 直接操作集群)
【GitOps 部署】
CI → 更新 Git 仓库(镜像 tag)→ ArgoCD 监听 → 自动同步到 K8s 集群
3.2 在 CI 中更新 Git 仓库(触发 ArgoCD)
CI 流水线的最后一步不再是调用 kubectl,而是将新的镜像 tag 提交到 Git 仓库的部署清单中:
yaml
# GitLab CI 示例
update-gitops:
stage: deploy
image: alpine/git:latest
script:
- git clone https://gitlab.com/team/gitops-repo.git
- cd gitops-repo
- sed -i "s|image: myapp:.*|image: myapp:$CI_COMMIT_SHORT_SHA|g" overlays/production/deployment.yaml
- git config user.email "ci@gitlab.com"
- git config user.name "GitLab CI"
- git add .
- git commit -m "deploy: $CI_COMMIT_SHORT_SHA [skip ci]"
- git push https://$GITLAB_USER:$GITLAB_TOKEN@gitlab.com/team/gitops-repo.git main
💡 提示:skip ci 可避免 Git 仓库更新触发新的 CI 流水线,防止无限循环。
3.3 ArgoCD 自动同步
ArgoCD 部署在 K8s 集群中,持续监控 Git 仓库:
yaml
# Application 定义
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://gitlab.com/team/gitops-repo.git
targetRevision: main
path: overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # 自动删除不在 Git 中的资源
selfHeal: true # 自动修复手动修改
syncOptions:
- CreateNamespace=true
开启 automated 后,ArgoCD 每隔 3 分钟(默认)检查 Git 仓库变更,自动同步到集群。
3.4 使用 Argo CD Image Updater(全自动方案)
Argo CD Image Updater 可以自动检测镜像仓库中的新版本,并更新 Git 仓库中的镜像 tag,实现从代码提交到部署的全自动闭环。
四、部署策略:滚动更新、蓝绿部署与金丝雀发布
在 CI/CD 流水线中,选择合适的部署策略至关重要。

4.1 在 CI 中实现蓝绿部署
通过 Service 的 label selector 切换流量:
yaml
# 部署绿色版本(v2)
- kubectl apply -f deployment-green.yaml
# 验证绿色版本健康
- kubectl rollout status deployment/myapp-green -n production
# 切换流量到绿色版本(修改 Service selector)
- kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}' -n production
# 如需回滚,只需将 selector 改回 "blue"
4.2 使用 Argo Rollouts 实现金丝雀发布
Argo Rollouts 是 Kubernetes 的高级部署引擎,支持金丝雀和蓝绿部署:
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10 # 10% 流量到新版本
- pause: {duration: 5m}
- setWeight: 50 # 50% 流量
- pause: {duration: 5m}
- setWeight: 100 # 100% 流量
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:$CI_COMMIT_SHORT_SHA
CI 只需更新镜像 tag 并提交 Git,Argo Rollouts 自动执行金丝雀步骤。
五、安全最佳实践
最小权限原则:为 CI 使用的 ServiceAccount 只授予必要的 K8s 权限(如只允许更新特定 Deployment)。
使用短期凭证:优先使用 OIDC 或 GitLab Agent,避免长期有效的 kubeconfig 泄露。
预校验配置:在 CI 中执行 kubectl apply --dry-run=client 提前发现 YAML 语法错误。
敏感信息隔离:数据库密码等敏感配置使用 Kubernetes Secret 或 Vault,不写入 values.yaml。
审计与追溯:GitOps 模式下,所有变更都有 Git 提交记录,便于审计。
六、小结
本章介绍了 Kubernetes 自动化部署的两种核心模式:
直接式部署:CI 直接调用 kubectl 或 helm 命令,简单直接,适合快速迭代
声明式部署(GitOps) :CI 只更新 Git 仓库,由 ArgoCD 同步集群,安全可控,适合生产环境
实际项目中,可根据团队规模和风险偏好选择合适的方式。对于生产环境,强烈推荐 GitOps 模式------它让 Git 成为唯一的变更入口,所有操作可追溯、可回滚。