持续部署在kubernetes上需综合策略选择、更新机制与可观测性:kubectl set image适合临时验证但无回滚;argo cd践行gitops但依赖git提交与健康检查配置;keel专注镜像轮询但忽略配置兼容性;ci驱动灵活却易失控,关键在明确定义“成功部署”的业务级标准。

持续部署在 Kubernetes 上不是靠单个工具“一键开启”,而是由策略选择、更新机制和可观测性共同决定的。你得先明确:是想自动拉新镜像(如 Keel),还是靠 Git 作为唯一事实源(如 Argo CD),抑或走传统 CI 触发式(如 Jenkins + kubectl set image)。选错路径,后期维护成本会指数级上升。
用 kubectl set image 实现最简 CD,但只适合临时验证
这是最直白的命令式更新方式,适合调试或小规模手动触发:
- 它直接修改 Deployment 的
spec.template.spec.containers[*].image字段,触发滚动更新 - 不依赖外部系统,但无法回滚到历史 Git 提交,也不记录谁、何时、为何改了镜像
- 执行后需立刻跟
kubectl rollout status deployment/my-app确认 Pod 就绪,否则可能卡在旧版本 - 若镜像 tag 是
latest,Kubernetes 不会重新拉取——它只比对字段值是否变化,latest指向变了但字段没变,就不会触发更新
Argo CD 是 GitOps 模式的事实标准,但必须接受“声明即一切”
Argo CD 把 Kubernetes 集群状态和 Git 仓库中 YAML 的差异视为 drift,并持续 reconcile。这意味着:
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
- 所有变更必须提交到 Git:新镜像要改
deployment.yaml里的image:行,不能绕过 Git 直接操作集群 - 它默认不监听镜像仓库,所以需要配合
argocd-image-updater或外部脚本(如 cron job 调用git commit)来自动 bump tag - 应用健康检查靠
health.lua脚本定义,若没配,Argo CD 可能认为 CrashLoopBackOff 的 Pod “已就绪” - RBAC 权限要细粒度控制:Argo CD 的 ServiceAccount 至少需
get/watch/list对应 namespace 下的 deployments、pods、replicasets
Keel 专注镜像变更感知,但轮询有延迟且不处理配置漂移
Keel 的定位很清晰:只管“有没有新镜像”,不管“配置对不对”。它适合已有成熟 Helm Chart 或 Kustomize 流程,只想省掉人工拉镜像这步的团队:
- 它通过轮询 registry API 获取新 tag,默认间隔是 5 分钟,
pollInterval可调但太短会触发 rate limit - 更新逻辑依赖资源上的 annotation,比如
keel.sh/policy: semver+keel.sh/trigger: poll,漏标就静默失效 - 它不会校验新镜像是否兼容当前 ConfigMap/Secret,也不会阻止你把
v2.0.0推给还在用v1.x配置的应用 - 如果你用的是私有 registry,Keel 必须配置对应 secret 并挂载进 Pod,否则
401 Unauthorized错误不会报在 UI,只出现在 pod logs 里
CI 驱动型部署(Jenkins/GitHub Actions)最容易上手,也最容易失控
这类方案把部署逻辑写进 pipeline 脚本,自由度高,但责任全在脚本作者身上:
-
kubectl apply -f manifests/和kubectl set image混用会导致资源管理混乱:前者创建+更新,后者只改字段,冲突时后者赢,但历史不可追溯 - 务必在脚本里加
kubectl rollout status+ 超时退出,否则 pipeline 显示 success,实际 rollout 卡死 - 如果 pipeline 运行在集群外,
kubeconfig文件必须包含有效证书且权限最小化;若用 token,过期后整个流水线静默失败 - 多环境(dev/staging/prod)切勿共用同一套 manifest 目录——用
kustomize的base/overlays结构或 Helm--set参数隔离更安全
真正难的不是选哪个工具,而是定义清楚“什么才算一次成功的部署”:是 Pod Running,还是 readiness probe 返回 200,还是某条业务 SQL 查询返回预期结果?这个判断逻辑一旦写死在自动化链路里,就很难临时绕过。别等上线才发现健康检查阈值设得太松。










