第十一章:自动化部署到 Kubernetes:Helm 与 kubectl 集成
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。
# GitLab CI 示例deploy:stage:deployimage:bitnami/kubectl:latestbefore_script:-mkdir-p $HOME/.kube-echo "$KUBECONFIG"|base64-d>$HOME/.kube/configscript:-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 命令。
# .gitlab-ci.ymlstages:-setup-deploycreate-registry-secret:stage:setupimage:"portainer/kubectl-shell:latest"variables:AGENT_KUBECONTEXT:my-group/my-project:productionscript:-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 productionAgent 会自动注入到 Runner 环境中,无需在 CI 中存储 kubeconfig。
方式三:GitHub Actions + OIDC(推荐 GitHub 用户)
使用 OpenID Connect 实现无长期凭证的认证:
-name:Configure kubectluses:azure/setup-kubectl@v4-name:Set up kubeconfigrun:|mkdir -p $HOME/.kube echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config更安全的做法是使用 OIDC 联邦认证,由云平台(AWS/Azure/GCP)动态颁发短期凭证。
2.2 使用 kubectl 直接部署
基础部署:更新镜像并等待状态
deploy:stage:deployimage:bitnami/kubectl:latestscript:-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
多环境部署:通过不同命名空间和环境变量区分
deploy-staging:stage:deployscript:-kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA-n staging-kubectl rollout status deployment/myapp-n stagingonly:-developdeploy-production:stage:deployscript:-kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA-n production-kubectl rollout status deployment/myapp-n productiononly:-mainwhen:manual2.3 使用 Helm 进行更灵活的部署
Helm 是 Kubernetes 的包管理工具,通过 Chart 将多个 K8s 资源打包管理。在 CI 中使用 Helm 部署是更推荐的方式。
在 CI 中安装 Helm 并执行部署:
deploy-helm:stage:deployimage:alpine/helm:3.14before_script:-mkdir-p $HOME/.kube-echo "$KUBECONFIG"|base64-d>$HOME/.kube/configscript:# 更新 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 # 生产环境覆盖
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 仓库的部署清单中:
# GitLab CI 示例update-gitops:stage:deployimage:alpine/git:latestscript:-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 仓库:
# Application 定义apiVersion:argoproj.io/v1alpha1kind:Applicationmetadata:name:myappnamespace:argocdspec:project:defaultsource:repoURL:https://gitlab.com/team/gitops-repo.gittargetRevision:mainpath:overlays/productiondestination:server:https://kubernetes.default.svcnamespace:productionsyncPolicy: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 切换流量:
# 部署绿色版本(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 的高级部署引擎,支持金丝雀和蓝绿部署:
apiVersion:argoproj.io/v1alpha1kind:Rolloutmetadata:name:myappspec:replicas:10strategy:canary:steps:-setWeight:10# 10% 流量到新版本-pause:{duration:5m}-setWeight:50# 50% 流量-pause:{duration:5m}-setWeight:100# 100% 流量selector:matchLabels:app:myapptemplate:metadata:labels:app:myappspec:containers:-name:appimage:myapp:$CI_COMMIT_SHORT_SHACI 只需更新镜像 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 成为唯一的变更入口,所有操作可追溯、可回滚。
