第十一章:自动化部署到 Kubernetes:Helm 与 kubectl 集成

📅 2026/7/1 18:51:48
第十一章:自动化部署到 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 / Helm2.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:latestvariables: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-kubectlv4-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预校验在正式部署前检查配置是否正确yamlkubectl apply -f k8s/ --dry-runclient -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 文件管理多环境textchart/├── 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 模式声明式部署与 ArgoCDGitOps 将部署从“推”变为“拉”CI 流水线只负责构建镜像并更新 Git 仓库中的部署清单而 ArgoCD 持续监控 Git 仓库的变化自动将集群状态同步到期望状态。3.1 架构对比text【直接式部署】CI → kubectl/helm → K8s 集群CI 直接操作集群【GitOps 部署】CI → 更新 Git 仓库镜像 tag→ ArgoCD 监听 → 自动同步到 K8s 集群3.2 在 CI 中更新 Git 仓库触发 ArgoCDCI 流水线的最后一步不再是调用 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 cigitlab.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_TOKENgitlab.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:-CreateNamespacetrue开启 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 改回 blue4.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 并提交 GitArgo Rollouts 自动执行金丝雀步骤。五、安全最佳实践最小权限原则为 CI 使用的 ServiceAccount 只授予必要的 K8s 权限如只允许更新特定 Deployment。使用短期凭证优先使用 OIDC 或 GitLab Agent避免长期有效的 kubeconfig 泄露。预校验配置在 CI 中执行 kubectl apply --dry-runclient 提前发现 YAML 语法错误。敏感信息隔离数据库密码等敏感配置使用 Kubernetes Secret 或 Vault不写入 values.yaml。审计与追溯GitOps 模式下所有变更都有 Git 提交记录便于审计。六、小结本章介绍了 Kubernetes 自动化部署的两种核心模式直接式部署CI 直接调用 kubectl 或 helm 命令简单直接适合快速迭代声明式部署GitOps CI 只更新 Git 仓库由 ArgoCD 同步集群安全可控适合生产环境实际项目中可根据团队规模和风险偏好选择合适的方式。对于生产环境强烈推荐 GitOps 模式——它让 Git 成为唯一的变更入口所有操作可追溯、可回滚。