LabHub
学习 学习路径 课程

CKAD — Kubernetes 应用开发者

部署不是「改」,是「改得能撤回来」

在 LabHub 中继续学习

一句话总结

Deployment、Helm、Kustomize 都在解决同一个问题:变更期间不让服务死亡,并在出错时回到先前状态。因此三种工具都有“revision”概念。

概念图: 变更期间不让服务死亡,并在出错时回到先前状态 · Deployment 管理多个 ReplicaSet。 · 如果没有 Readiness Probe,所有安全保障都会失效。 · selector 收窄到共同标签

为什么需要它

直接创建 Pod 运营时,一改镜像就会停机,因为删除与重建之间无人提供服务。ReplicaSet 能维持数量,却没有“修改镜像”的概念。

Deployment 在其上再加一层:**Deployment 管理多个 ReplicaSet。**修改镜像后创建新 ReplicaSet,一边扩大新副本,一边缩小旧副本。旧 ReplicaSet 以副本数 0 保留,收到回退命令时只需反向执行。这就是 rollout undo 很快的原因——无需重新拉取镜像。

速度由两个数字控制。maxSurge 表示允许超出 desired 多少,maxUnavailable 表示允许低于 desired 多少。设为 maxUnavailable: 0 时始终保留原数量的存活实例,但必须等待新 Pod Ready,因此部署更慢。这里**如果没有 Readiness Probe,所有安全保障都会失效。**没有 probe,容器一启动便视为 Ready,流量会进入仍在初始化的 Pod。

replicas 为 4、maxSurge 为 1、maxUnavailable 为 0 时,rolling update 在两个 ReplicaSet 间交替——先增加一个新副本,瞬间达到 5 个;之后每增加一个就减少一个,始终至少有 4 个存活,最后只剩 4 个新副本。旧 ReplicaSet 以副本数 0 保留,等待 rollout undo

它如何运作

部署策略整理如下。

策略 实现 回退速度 资源
rolling update 一个 Deployment,maxSurge/maxUnavailable 中等(再次 rolling) +maxSurge
blue-green 两个 Deployment + 切换 Service selector 立即(切回 selector) 2 倍
canary 两个 Deployment + 相同 Service selector,按副本比例 立即(canary 归零) 略多

blue-green 是标签游戏。checkout-blueversion: bluecheckout-greenversion: green;把 Service selector 改为 version: green,流量便瞬间全部切换。canary 则把selector 收窄到共同标签,让两个 Deployment 的 Pod 都进入 endpoint,通过副本数量决定流量比例,9:1 大约就是 10%。

kubectl rollout history 中的 CHANGE-CAUSE 不是魔法,而是 kubernetes.io/change-cause annotation。旧的 --record flag 已废弃,应使用 kubectl annotate deployment web kubernetes.io/change-cause="..." 手动添加。没有它,rollout history 只列 revision 编号,无法知道变更内容。

Helm 把相同理念提升到 package 级。release 的每个 revision 都保存为 namespace 中的 Secret(sh.helm.release.v1.<이름>.v<번호>),其中完整包含渲染后的 manifest 和 values。helm rollback 会用该 revision 的 chart 与 values 创建新 revision——不是倒转时间,而是向前推进并重新应用旧内容。helm upgrade 使用 3-way merge:比较上一 revision manifest、新渲染 manifest 与集群当前实际状态,只应用所需变化,因此不会随意覆盖其他工具的修改。

Kustomize 不用 template 完成相同工作。把公共 manifest 放在 base,在 overlays/<환경> 中附加 namePrefix、label 和 patch。它理解 YAML 结构后再 merge,而非字符串替换,因此结果始终是有效 YAML。用 kubectl kustomize <경로> 只查看渲染结果,用 kubectl apply -k <경로> 应用。

在实际工作中会遇到的情况

家庭实验室安装 GPU Operator 时,最初用 toolkit.enabled=false 安装,后来发现判断错误,只需修改这个值。

helm upgrade gpu-operator nvidia/gpu-operator --version v26.3.3 \
  -n gpu-operator --reuse-values --set toolkit.enabled=true

如果没有 --reuse-values,上一 revision 的值会全部丢失,并重置为 chart 默认值。这样 driver.enabled=false 会恢复为默认 true,Operator 将尝试重新安装 driver,与已经安装 570.195.03 的主机冲突,使节点失去 GPU。一个 flag 避免了事故。

升级后的 history 如下。

REVISION  STATUS      CHART                 DESCRIPTION
1         superseded  gpu-operator-v26.3.3  Install complete
2         deployed    gpu-operator-v26.3.3  Upgrade complete

关键是 revision 1 没有删除,而是以 superseded 保留,表示仍可用 helm rollback gpu-operator 1 回退。

还要注意,Helm 没有直接创建 DaemonSet。它只把 ClusterPolicy 自定义资源的 toolkit.enabled 从 false 改为 true,检测到变化的 Operator 控制器才创建 DaemonSet。Helm 负责声明,控制器负责组装,这展示了部署工具的责任边界。

后续实验要做什么

ckad-deploy namespace 调整 rolling update 参数,两次升级镜像后用 --to-revision 回到特定 revision,并通过标签与副本比例亲手构建 blue-green 和 canary。随后用 helm create 创建本地 chart,修改 values,执行 helm template/install/upgrade;再创建 Kustomize base 与 overlay,通过 kubectl kustomizeapply -k 应用。本环境没有互联网,不能使用 helm repo add,必须只使用本地路径。