用控制器把工作负载跑起来
目标
亲手确认 Deployment、ReplicaSet、DaemonSet、StatefulSet 四种控制器之间的差异,调整滚动更新参数,并实际执行 rollout 与 rollback。
为什么这很重要
考试中经常出现“升级镜像,发生问题后回滚”这类题目。如果不了解回滚为何能够实现,就容易掉进陷阱。rollout undo 并不是魔法,它只是将保留为 0 个副本的旧 ReplicaSet 再次扩容。因此,如果将 revisionHistoryLimit 设为 0,就无法回滚;如果手动把镜像改回旧版本,那也不是回滚,而是又新增了一个 revision。
四种控制器的选择标准也很明确:如果副本之间无需区分,使用 Deployment;如果每个节点必须恰好一个,使用 DaemonSet;如果名称、顺序和卷必须固定,使用 StatefulSet。StatefulSet 要求 headless Service,是为了给每个 Pod 提供独立的 DNS 名称。
步骤
- 创建 namespace
cka-workloads和 Deploymentweb。镜像为nginx:1.25,副本数为 2。 - 将
web扩容到 4 个副本,并确认 4/4 Ready。 - 将
web的策略设为RollingUpdate,并配置maxSurge: 2、maxUnavailable: 0、revisionHistoryLimit: 3。 - 创建 Deployment
api(镜像nginx:1.25,副本数 3)。然后将镜像替换为nginx:1.27,并等待 rollout 完成。 - 将
api的 rollout 历史保存到/root/cka-workloads/history.txt。其中应显示至少两个 revision。 - 将
api回滚到上一个 revision。回滚后镜像应再次为nginx:1.25。 - 在
cka-workloads中创建 DaemonSetnode-agent。镜像为busybox:1.36,为容器设置一个长时间运行的命令,避免其立即退出。每个节点上都应有一个 Ready 实例。 - 创建 headless Service
db-headless(clusterIP None、端口 5432、选择器app=db),再创建 StatefulSetdb。serviceName 为db-headless,副本数为 2,镜像为nginx:1.27,updateStrategy 为RollingUpdate且partition: 1。确认 2/2 Ready。
参考
- 可以使用
kubectl rollout status deployment/api -n cka-workloads等待完成。 - 请通过
kubectl get rs -n cka-workloads直观看到每个 revision 对应的 ReplicaSet 都会保留。 - 常见错误 1:第 6 步使用
set image再次设置旧标签。那不是 rollback,而是新建 revision。 - 常见错误 2:第 8 步让 StatefulSet 的 Pod 标签与 headless Service 选择器不一致。二者必须统一为
app=db。
创建 Deployment
创建 namespace cka-workloads 和 Deployment web。镜像为 nginx:1.25,副本数为 2。
使用 kubectl create deployment 生成骨架,再只修改必要值会更快。镜像标签也必须准确一致。
扩容并确认 Ready
将 web 扩容到 4 个副本,并确认 4/4 Ready。
scale 命令最快,但也可以修改清单后应用。status.readyReplicas 达到目标值需要一点时间。
调整滚动更新参数
将 web 的策略设为 RollingUpdate,并配置 maxSurge: 2、maxUnavailable: 0、revisionHistoryLimit: 3。
前两个值位于 strategy.rollingUpdate 下。虽然可以使用整数或百分比,但本次必须使用整数。revisionHistoryLimit 位于 strategy 外部、spec 的直接下级。
替换镜像并等待 rollout 完成
创建 Deployment api(镜像 nginx:1.25,副本数 3)。然后将镜像替换为 nginx:1.27,并等待 rollout 完成。
使用 set image 修改后会创建新的 ReplicaSet。请用 rollout status 等待完成。评分会检查新 revision 是否存在以及 observedGeneration。
检查并保存 revision 历史
将 api 的 rollout 历史保存到 /root/cka-workloads/history.txt。其中应显示至少两个 revision。
rollout history 会输出带有 REVISION 列的表格。至少显示两个 revision,才说明存在可回滚的版本。
回滚到上一个 revision
将 api 回滚到上一个 revision。回滚后镜像应再次为 nginx:1.25。
不要手动将镜像改回去。那不是回滚,而是又创建了一个新 revision,评分会区分二者。请使用 rollout 回滚命令。
部署 DaemonSet
在 cka-workloads 中创建 DaemonSet node-agent。镜像为 busybox:1.36,为容器设置一个长时间运行的命令,避免其立即退出。每个节点上都应有一个 Ready 实例。
DaemonSet 不使用 replicas。通过 status 中的 desiredNumberScheduled 和 numberReady,确认每个节点上都运行一个实例。请设置长时间运行的命令,避免容器立即退出。
连接 headless Service 与 StatefulSet
创建 headless Service db-headless(clusterIP None、端口 5432、选择器 app=db),再创建 StatefulSet db。serviceName 为 db-headless,副本数为 2,镜像为 nginx:1.27,updateStrategy 为 RollingUpdate 且 partition: 1。确认 2/2 Ready。
StatefulSet 的 serviceName 必须指向已存在的 headless Service。partition 位于 updateStrategy.rollingUpdate 下,表示只更新序号大于等于该值的实例。