在配额内完成更新

KubernetesBeginner
立即练习

介绍

Aster Supply 正在提供日常商品目录,但冬季更新被阻塞了。其命名空间的 CPU 请求量配额足以支持正常运行,却容纳不下滚动更新期间请求的额外 Pod。你将选择一个适合固定资源分配的滚动更新预算,让参考店铺持续运行,并交付更新后的商品目录。

你应当已经了解基本终端路径、简单的 YAML、Pod、Deployment、Service 和标签。本实验将介绍 CPU 请求量单位、ResourceQuota 和更新预算的计算方法。真实的单节点集群、应用、健康检查和商品目录数据均已准备就绪;无需安装集群、构建镜像或编写应用程序。预计时长包括阅读和处理普通错误的时间,由作者估计。

让更新符合固定资源预算

在这一步中,你将在不增加 CPU 资源分配、不停止参考店铺的情况下,完成 Aster Supply 的冬季商品目录更新。

Shop Tab 显示正常工作的商品目录。打开 Stoneware tray,记下价格,再使用 Back to collection 返回。当前的 Everyday essentials 系列有三件商品;要求发布的 The winter edit 新增了 Amber cup 并调整价格。打开 Reference Tab:Fern Stationery 是独立的受保护服务,必须保留现有商品目录。保持其 Deployment、Service 和原始 Pod 不变。然后切换到 Workspace Tab。

准备好的集群是真实的单节点 Kubernetes。命名空间将本课的资源归为一组。ResourceQuota 限制该命名空间中获准创建的资源总量。这里仅核算 CPU requests(CPU 请求量):为调度预留的 CPU,并非费用额度,也不是实际 CPU 使用量的上限。1000m 表示一个 CPU 核心;40m 表示 0.04 个核心。内存已准备好,不是本任务的配额瓶颈。

先读取配额。--context=labex-v135 选择准备好的集群,-n shop-quota 选择本课的命名空间,describe 显示对象详情:

kubectl --context=labex-v135 -n shop-quota describe resourcequota shop-budget

预期看到 requests.cpu 的 Used 140m 和 Hard 140m。这是预留的 CPU,并非当前利用率。原始店铺仍可使用,但尝试中的更新需要再创建一个 Pod。可用副本必须已通过就绪检查,并满足准备好的三秒最短就绪期;仅创建 Pod 并不代表它已可用。读取 Deployment 及其 ReplicaSet。ReplicaSet 为一种 Deployment 模板维护 Pod;rs 是这种资源的简称:

kubectl --context=labex-v135 -n shop-quota get deployments,rs,pods

当前有三个可用的店铺副本和一个参考副本。新的店铺 ReplicaSet 无法创建其 Pod。查看两个店铺 ReplicaSet 的详情;-l app=shop 通过它们的标签进行选择:

kubectl --context=labex-v135 -n shop-quota describe rs -l app=shop

查找 FailedCreate 或 ReplicaFailure,以及 exceeded quota: shop-budget、requested: requests.cpu=40m、used: requests.cpu=140m 和 limited: requests.cpu=140m。这是准入拒绝:那个新 Pod 没有被创建。这与已经存在、但调度器无法安排的 Pending Pod 不同。不要修改配额或移除参考工作负载。

已批准的新商品目录和候选清单均已提供。明确进入工作区。pwd 打印当前目录;ls 列出其中的条目:

cd /home/labex/project/shop-update
pwd
ls

你应看到 approved、starter 和 tools。cat 打印已批准的商品目录:

cat approved/catalogue.json

使用 sed -n '1,180p' 读取整个候选清单:-n 禁止普通输出,p 打印第 1 至 180 行。带引号的范围是一个参数:

sed -n '1,180p' starter/shop.yaml

店铺需要三个副本,每个请求 40m。受保护的参考服务请求 20m。仅允许修改 spec.strategy.rollingUpdate;提供的新应用模板、副本数、资源、选择器和健康检查必须保持完整。

预算项 CPU 请求量
三个店铺副本 3 × 40m = 120m
受保护的参考服务 20m
稳态 140m
更新期间额外的一个店铺 Pod 总计 180m:超出 140m

滚动更新需要平衡两个值。maxSurge 允许 Pod 数量超出期望副本数。maxUnavailable 允许部分期望副本不可用。这里要求在所观察的更新期间至少有两个可用的店铺副本。期望副本数为三,因此允许一个副本暂时不可用,但资源无法容纳额外 Pod。选择 maxSurge: 0 和 maxUnavailable: 1。这两个值不能同时为零。使用 Recreate、删除 Deployment、降低请求量、缩减期望副本数或增加配额,都不属于本任务允许的范围。

创建可编辑的发布目录,复制提供的候选清单。mkdir 创建目录;cp 复制文件。提供的原始文件是只读的。chmod u+w 为副本增加当前用户的写权限:

mkdir release
cp starter/shop.yaml release/shop.yaml
chmod u+w release/shop.yaml

如果 release 已因之前的尝试而存在,请保留它,继续使用正在编辑的副本。如果路径拼写有误,先使用上面的 pwd、ls 和绝对路径 cd 命令,再重复失败的命令;路径不存在并不需要重置 VM。

sed -i 直接编辑文件。每个 s/old/new/ 表达式替换所示文本。单引号将空格和标点保留在同一个参数中。仅修改副本中的两个滚动更新值:

sed -i 's/maxSurge: 1/maxSurge: 0/' release/shop.yaml
sed -i 's/maxUnavailable: 0/maxUnavailable: 1/' release/shop.yaml

应用之前读取保存的清单开头:

sed -n '1,35p' release/shop.yaml

预期看到 replicas: 3、type: "RollingUpdate"、maxSurge: 0 和 maxUnavailable: 1。apply -f 使现有 Deployment 与此文件保持一致,保留 Deployment 的身份。rollout status 等待新副本,使用有限的 --timeout:

kubectl --context=labex-v135 apply -f release/shop.yaml
kubectl --context=labex-v135 -n shop-quota rollout status deployment/shop --timeout=180s

预期输出为 deployment "shop" successfully rolled out。控制器可以移除一个旧副本,准入一个新副本,等待其可用,再继续。正在终止的 Pod 可能短暂地仍计入配额,因此临时新增的 FailedCreate 事件可以自然恢复,并不构成修改配额的理由。滚动更新预算不是所有正在终止进程的绝对数量上限,也不保证持续可用。

如果错误的编辑导致无法完成,请检查保存的文件并修正两个策略值。若要从不成功的尝试或观察窗口失败中恢复,请重新应用原始的已批准基线,等待其完成,再重试修正后的发布配置:

kubectl --context=labex-v135 apply -f approved/shop.yaml
kubectl --context=labex-v135 -n shop-quota rollout status deployment/shop --timeout=180s

提供的状态工具的 --wait-baseline 选项会等待近期一次健康的旧商品目录观测,再开始新的尝试。它只读取已记录的事实:

./tools/update-status --wait-baseline
kubectl --context=labex-v135 apply -f release/shop.yaml
kubectl --context=labex-v135 -n shop-quota rollout status deployment/shop --timeout=180s

这些恢复命令只在尝试不成功时才需要使用。保持提供的基线不变。只读观察器会保留各次尝试,并识别新的、从基线到更新的完整尝试;恢复不会清除先前的证据。

最后,再次读取实际工作负载和配额:

kubectl --context=labex-v135 -n shop-quota get deployments
kubectl --context=labex-v135 -n shop-quota describe resourcequota shop-budget

两个 Deployment 都应可用:店铺为 3/3,参考服务为 1/1。旧 Pod 终止后,配额使用量恢复为 140m,硬限制保持不变。下一步检查人们实际收到的商品目录。

交付更新后的商品目录

在这一步中,你将检查新的顾客体验,并将真实的商品目录下载文件与保存的发布清单放在一起。

从 Workspace 开始,位于 /home/labex/project/shop-update。提供的 tools/update-status 命令汇总只读观察器记录的实际 API 和 HTTP 采样。开头的 ./ 表示运行相对于当前目录的程序:

./tools/update-status

它会报告要求的最低可用副本数、采样数、采样中最少的可用副本数和最新更新状态。预期最低值至少为二,完成时有三个已更新且可用的副本。观察器大约每半秒采样一次,另加 API 耗时,检查原始配额和参考服务并记录失败。请让这个提供的观察器持续运行。它不能证明采样之间发生的情况,不保证生产环境持续可用,也不会修复集群。滚动更新完成后立即进行检查时,可能需要稍等片刻,才能得到两次完成后的采样。如果某次尝试低于要求的最低值或存在过长的观察间隔,请使用上一步教过的基线恢复流程,再进行修正后的尝试。

切换到 Shop,重新加载页面。预期看到 The winter edit、四件商品,以及 Stoneware tray $20.00、Linen cloth $14.00、Bud vase $24.00 和 Amber cup $16.00。打开 Amber cup,确认价格和 Available in store 状态,再使用 Back to collection 返回。这是商品目录,不提供在线结账。

完成后的系列有四张真实的商品卡片。将系列标题和价格与这个运行中的示例比较:

更新后的 Aster Supply 商品系列

使用 Download catalogue。打开浏览器下载的 catalogue.csv;其中四行应与网站上的系列、名称、以分为单位的价格和供应状态一致。浏览器下载位置与终端工作区是不同位置。接下来,将相同的真实 Service 下载文件保存到工作区,作为交付文件。

切换回 Workspace。curl 获取 URL。--fail 报告 HTTP 错误,--silent --show-error 隐藏进度条但保留错误信息,--output 将响应字节写入指定文件。127.0.0.1:8081 是准备好的本地入口,会转发到原始店铺 Service:

curl --fail --silent --show-error http://127.0.0.1:8081/catalogue.csv --output catalogue.csv
cat catalogue.csv

预期输出:

id,name,price_cents,available,collection
stone-tray,Stoneware tray,2000,true,The winter edit
linen-cloth,Linen cloth,1400,true,The winter edit
bud-vase,Bud vase,2400,true,The winter edit
amber-cup,Amber cup,1600,true,The winter edit

连接错误意味着无法访问本地入口;HTTP 错误则是服务器返回的响应。使用已教过的工作负载和滚动更新命令检查当前状态;不要用静态文件替代,也不要修改准备好的转发服务。如果下载不完整或被意外覆盖,请在正确商品目录可用后,重复相同的 curl 命令。

再次打开 Reference 并重新加载。Fern Stationery 必须仍显示 Desk essentials、Field notebook $9.00 和 Clay pencil cup $14.00。打开一件商品并返回,确认其真实链接仍能正常使用。

你的交付文件是 release/shop.yaml 和实际的 catalogue.csv,其依据是完整的新发布版本、未改变的配额、原始参考服务和有效的已观察更新尝试。保留提供的原始文件、应用、Service 和只读观察器。

总结

你将真实的 ReplicaSet 配额拒绝与滚动更新的临时资源需求联系起来,计算出合适的额外 Pod/不可用副本预算,并在不扩大资源分配的情况下完成了新商品目录。你还保留了受保护的参考服务,并交付了实际 CSV 和可复用的发布清单。

CPU 请求量描述的是资源核算,并非实测利用率或性能承诺。原生的有限观测支持本课的可用性检查,但不能证明生产环境始终不间断可用。在其他命名空间中,应重新计算剩余资源分配和最低可用副本数,再选择策略。