ARTICLE DETAIL

资讯详情

深耕网站SEO优化与搜索引擎排名提升的一线实战洞察。

Kubernetes 上手实战(3):Pod 与 Deployment 编排实战

Kubernetes 上手实战(3):Pod 与 Deployment 编排实战 上一篇用 kind 建好了三节点学习集群并把 kubectl context 固定在lab。本篇继续编排 web从 Pod 的共享边界讲到 Deployment 的滚动升级、暂停与回滚让“两个副本”变成可验证的发布策略。一、痛点副本稳定不等于升级安全Pod 内容器共享网络命名空间所以它们通过 localhost 通信并共享端口空间挂载同一个 Volume 时也能交换文件。紧密协作的 sidecar 才适合与主容器同 Pod数据库和前端这类可独立扩缩、独立发布的组件不应硬塞进去。Pod 还是一次性身份重建后 UID、IP 和本地可写层都会变化。Deployment 的职责是管理 ReplicaSet并以声明方式替换旧 Pod。修改 Pod template 才会产生新修订单纯改变 replicas 不会。默认 RollingUpdate 同时受maxSurge和maxUnavailable约束。对于两个副本设置 surge1、unavailable0 意味着升级期间最多三个、至少两个可用但前提是新 Pod 真正通过 readiness。控制器只理解对象状态不理解业务是否正确。镜像能启动却返回错误页面时简单 TCP 探针仍可能判定健康。因此发布策略、探针语义和业务验收必须共同设计。第七篇会展开探针本篇先用 HTTP readiness 建立滚动升级门槛。二、原理模板哈希、修订与终止Deployment 为 Pod template 计算哈希并写入 ReplicaSet 名称和 Pod 标签。当 template 改变新 ReplicaSet 扩容旧 ReplicaSet 缩容历史 ReplicaSet 默认保留一定数量以便回滚。直接修改它们会与 Deployment 控制器争夺状态因此应始终修改顶层 Deployment。Pod 终止时API 先设置 deletionTimestampkubelet 执行 preStop 并向主进程发送 TERM宽限期后才强制 KILL。应用应停止接收新请求、完成在途工作并及时退出。terminationGracePeriodSeconds不是越长越安全过长会拖慢发布与节点维护应根据真实最长请求设置。下面保存为deployment.yaml。它包含稳定标签、显式发布策略、资源请求与限制、readiness以及限制修订数量。镜像固定版本便于复现生产应替换为自有镜像摘要。apiVersion:apps/v1kind:Deploymentmetadata:name:weblabels:app.kubernetes.io/name:webspec:replicas:2revisionHistoryLimit:5minReadySeconds:5strategy:type:RollingUpdaterollingUpdate:maxSurge:1maxUnavailable:0selector:matchLabels:app.kubernetes.io/name:webtemplate:metadata:labels:app.kubernetes.io/name:webspec:terminationGracePeriodSeconds:20containers:-name:webimage:nginx:1.27.3-alpineports:-name:httpcontainerPort:80resources:requests:cpu:20mmemory:32Milimits:memory:64MireadinessProbe:httpGet:path:/port:httpinitialDelaySeconds:2periodSeconds:3三、实现观察升级而非只看结果运行脚本前确认 context。脚本应用清单、记录第一版 ReplicaSet把镜像改为另一个有效版本并观察 rollout随后故意指定不存在的镜像触发失败查看事件再用 undo 回滚。故障演练必须在学习 namespace 进行。#!/usr/bin/env bashset-euopipefailexpected_contextkind-k8s-labtest$(kubectl config current-context)${expected_context}kubectl apply-fdeployment.yaml kubectl rollout status deployment/web--timeout120s kubectl get pods-lapp.kubernetes.io/nameweb-owide kubectl get replicasets-lapp.kubernetes.io/nameweb kubectlsetimage deployment/webwebnginx:1.27.4-alpine kubectl annotate deployment/web kubernetes.io/change-causeupgrade nginx to 1.27.4--overwritekubectl rollout status deployment/web--timeout120s kubectl rollouthistorydeployment/web kubectlsetimage deployment/webwebnginx:not-a-real-tagifkubectl rollout status deployment/web--timeout30s;thenechounexpected rollout successexit1elsekubectl get pods-lapp.kubernetes.io/nameweb kubectl get events --sort-by.metadata.creationTimestamp|tail-n12fikubectl rollout undo deployment/web kubectl rollout status deployment/web--timeout120s kubectl get deployment web-ojsonpath{.status.availableReplicas}{ available\n}预期现象是错误镜像对应的新 Pod 进入 ImagePullBackOff而旧版 Pod 因maxUnavailable: 0继续服务undo 后新失败 ReplicaSet 被缩容可用副本恢复为 2。若rollout status超时脚本会失败而不是把未完成发布当成功。发布前可执行kubectl diff -f deployment.yaml提交后用kubectl rollout history查看修订。change-cause annotation 只是说明不是完整审计Git 提交、镜像摘要、部署者与流水线运行号仍应关联记录。临时暂停 Deployment 可连续修改多个 template 字段后统一恢复但暂停期间不会发生新 rollout。四、踩坑命令成功与上线成功之间kubectl apply返回 configured 只说明 API 已接受变更。流水线必须继续等待 rollout并在失败时收集 describe、events 和容器日志。把超时设成无限会占死发布任务设得短于应用正常启动时间则制造假失败应以启动分布的高分位数加余量制定。CPU limit 可能对延迟敏感服务造成节流因此示例只设置 CPU request内存无法像 CPU 一样平滑限速超过 limit 会被 OOMKilled。配置值必须由观测得到而不是机械照抄。requests 太低会过度装箱太高则导致 Pending。资源配置与 HPA 的利用率计算还会互相影响。不要用kubectl delete pod当常规发布方式它只是触发同模板重建。不要用kubectl exec在容器里改文件重建后修改会消失并制造漂移。若需要新配置应更新 ConfigMap 或镜像并形成受控 rollout。五、验证把失败纳入发布流程最终验收至少包含正常升级时可用副本不低于 2错误镜像不会清空旧副本失败能在有限时间内被检测回滚后镜像和可用副本符合预期。再运行一次kubectl get deployment web -o yaml重点读 conditions 中 Progressing 与 Available而非只看 READY 列。真实业务还要做版本端点或关键路径冒烟测试因为 readiness 只能说明单 Pod 接受流量无法证明数据库迁移、外部依赖和核心功能都正确。可复用的方法是“部署条件 业务探测 自动回滚决策”三者各自保留证据。下一篇将把易变配置和敏感值从 Pod template 中拆出来用 ConfigMap、Secret、挂载与校验和触发器控制配置发布。可以进一步做并发观察在一个终端持续查看 Pod另一个终端发起升级第三个终端持续请求 Service 并记录状态码。把新副本创建、变为就绪、旧副本进入终止的时间线对齐便能直观看到发布策略如何兑现可用性承诺。若请求出现空窗要检查就绪探针是否过早成功、应用是否正确处理终止信号以及端点移除与进程退出之间是否留足排空时间。团队评审工作负载时可固定询问六项选择器是否稳定镜像是否唯一资源请求是否来自测量探针是否代表真实语义滚动参数能否容纳于配额失败是否在时限内可见。再为一次成功升级和一次失败回滚保存对象条件、事件及业务探测结果作为以后改动的基线。这样发布能力不依赖某位工程师现场盯屏而能被流水线重复执行。完成这些观察后下一篇会把同样的可审查发布方法延伸到配置与密钥让环境差异不再藏在镜像和临时命令中。滚动发布的风险来自容量瞬态而不是最终副本数。下面程序逐步模拟replicas4、maxSurge1、maxUnavailable1每一步先创建新版再下线一个旧版并断言可用副本从不跌破 3。desired4max_surge1max_unavailable1old_ready4new_ready0step0whileold_ready0:step1totalold_readynew_readyiftotaldesiredmax_surge:new_ready1availableold_readynew_readyifold_ready0andavailable-1desired-max_unavailable:old_ready-1availableold_readynew_readyifavailabledesired-max_unavailable:raiseRuntimeError(availability budget violated)print(fstep{step}old{old_ready}new{new_ready}ready{available})print(rolloutcomplete)运行输出step1 old3 new1 ready4 step2 old2 new2 ready4 step3 old1 new3 ready4 step4 old0 new4 ready4 rolloutcomplete第二个程序实现一个最小发布门禁只有 revision、可用副本、失败副本和观测窗口同时满足要求才推进。它说明“rollout 命令返回”为什么不能替代业务验收。observations[{revision:8,available:3,failed:0,error_rate:0.004},{revision:9,available:4,failed:0,error_rate:0.008},{revision:9,available:4,failed:0,error_rate:0.006},]target_revision9required_replicas4error_budget0.01defaccepted(item:dict[str,int|float])-bool:return(item[revision]target_revisionanditem[available]required_replicasanditem[failed]0anditem[error_rate]error_budget)target_samples[itemforiteminobservationsifitem[revision]target_revision]forindex,iteminenumerate(target_samples,start1):print(fwindow{index}accepted{accepted(item)})print(decision(PROMOTEifall(map(accepted,target_samples))elseROLLBACK))运行输出window1 acceptedTrue window2 acceptedTrue decisionPROMOTE参考来源PodsDeploymentsPod LifecycleResource Management for Pods and Containers 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《Kubernetes 上手实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。
返回列表