Skip to content

Kubernetes:控制循环、Service 网络与持久存储 ​

先明确context、namespace、Secret 与 PVC,再对照配套示例理解Pod 条件、EndpointSlice 与持久数据。

Deployment 与控制循环 ​

Kubernetes Deployment 调谐不是依次执行清单的脚本。Deployment 根据 PodTemplate 管理 ReplicaSet,ReplicaSet 维持副本;删除一个受控 Pod 会被替代,但替代 Pod 的 UID/IP 会变化。修改模板才触发新的修订;Service 的 selector 应与 Pod 标签匹配,Deployment 自己的 selector 创建后不可随便改变。

RollingUpdate 的 maxSurge 决定额外副本,maxUnavailable 决定更新期间允许不可用的数量;这些参数不自动提供金丝雀流量路由或蓝绿切换。本例只有一个本地 SQLite 写入者并共用 RWO PVC,因此采用 Recreate,承认升级停机窗口;不能把它扩成多个写副本来假装高可用。

Service 与端点 ​

Kubernetes Service selector 根据标签关联 Pod,EndpointSlice 表达后端地址与条件;常规服务流量使用就绪端点,ClusterIP/DNS 不承诺应用业务正确。本例 Service port 80 指向容器命名端口 http,即 8080。containerPort 是声明,不自动让应用监听;程序须监听 0.0.0.0:8080。

同一 Pod 内容器共享 localhost,不同 Pod 不能靠 localhost 互访。Service DNS 正常但 EndpointSlice 没有可用后端时,应核对 selector、命名空间与 readiness;不要先删除 DNS 组件。kube-proxy、替代数据面或 CNI 的具体转发实现属于平台,不必假设一定是 iptables。

ConfigMap 与 Secret ​

Kubernetes ConfigMap 环境变量在容器创建时注入,不会因对象变化自动刷新;挂载文件通常会最终更新,但 subPath 挂载例外,应用也必须重新读取。本例 MESSAGE 作为环境变量、token 在进程启动时读入内存,两者更新后都需要受控重建才能生效。

Kubernetes Secret base64 是编码不是加密,stringData 是便利输入字段。Secret 存在 API/etcd 中,需静态加密、最小 RBAC、审计与可靠轮换;可以创建能挂载 Secret 的 Pod 的身份也可能间接读到内容。本例的 replace-before-use 是故意不能通过应用初始化的占位值,不是真凭据,读者必须自己替换,不能公开部署。

PVC 与存储生命周期 ​

Kubernetes PVC Pending 常与 StorageClass、容量、访问模式及拓扑有关。PVC 是命名空间内的存储请求,PV 是集群资源,CSI 实现实际卷;应用、PVC、PV 的生命周期不同。默认存储类省略了环境耦合的名称,但仍要求平台提供它,不是清单自己生成了云盘。

ReadWriteOnce 表示单节点可读写,不等于单 Pod 排他,也不保证数据库层面的单写锁。ReadWriteOncePod 才有更严格单 Pod 语义且受 CSI/版本条件约束。本例保留单副本和 Recreate,仍不是持久数据库集群。emptyDir 跨容器重启可保留,随 Pod 删除丢失;PVC 的后端数据则由 PV 回收策略与存储实现决定。

requests、limits 与探针 ​

Kubernetes requests limits 的分工是调度需求与运行约束:scheduler 依据 requests 和节点可分配量过滤,CPU limit 通常导致节流,memory limit 超限可能 OOM Kill。100m CPU 是 0.1 核,64Mi 是内存容量;内存的 m 后缀是千分之一字节,不能当 Mi。示例值是教学占位,未压测,不能作生产容量结论。

Kubernetes probes 中 startupProbe 给启动阶段预算,成功前不执行 liveness/readiness;readinessProbe 失败使 Pod 不再就绪,普通 Service 不再把它作为可用后端;livenessProbe 达阈值让 kubelet 重启容器。本例 /live 只反映 HTTP 处理进程存活,/ready 读数据库。下游暂时不可用不应变成全链路 liveness 故障,否则重启风暴会放大依赖事故。

调度与终止 ​

Kubernetes 调度 Pending 要同时看资源请求、污点容忍、节点亲和与卷拓扑。toleration 只允许容忍污点,不强制把 Pod 放到那个节点;nodeSelector 或 affinity 才限制选择范围。调度成功后仍可能因镜像和挂载失败无法启动。示例不强加 nodeSelector,以免假设不存在的标签。

终止时 Pod 端点状态与 kubelet 停止容器异步推进,应用接收 SIGTERM 后应停止接收新工作并完成在途请求;preStop 的耗时也占 terminationGracePeriodSeconds。超过预算会被强制终止,不能用无限等待阻塞发布。本例无 preStop,Python 信号处理只作为基本收尾示范。

练习、深入手册与来源 ​

问题:节点 CPU 使用率低,Pod 为什么仍 Pending?答案:requests 预留、污点、亲和、配额和卷拓扑都可能排除节点,实时利用率不代替调度资源账本。

问题:把 readiness 换成 liveness 能否修复 Service 无端点?答案:不能。前者控制就绪,后者控制重启;必须解释真正不就绪的原因。

原有配置、存储、网络、调度、资源健康继续提供完整查阅。核对 2026-10-17:Deployments 中文、Persistent Volumes、Pod probes、Resource management。

外部数据库与无 selector 的 Service ​

没有 selector 的 Service 如何表示外部 MySQL,能代替数据库运维吗? 旧对象笔记除了 Deployment,还用同名 Service 与手工 Endpoints 表达集群外 MySQL。其价值是把服务入口和后端生命周期拆开:没有 selector 的 Service 不会靠标签自动发现外部数据库;把地址写进端点对象也不会创建、认证、备份或监测 MySQL。应用使用 mysql-production.test 这样的命名空间地址,仅改变寻址方式,不能保证路由可达。

按当前 Service 文档,外部后端可通过与 Service 关联的 EndpointSlice 表达,需要明确关联标签、地址、端口与维护责任;旧 Endpoints 片段不能直接当作新清单。对静态阅读,先核对 Service 所在 namespace、port、端点的目标端口及网络策略,再检查连接凭据由谁提供。旧文“Pod 只能连接 Service、不能互相连接”的概括不成立;Service 解决稳定入口,是否可直连 Pod 仍由网络和策略决定。Service without selectors已于 2026-10-17 核对。本课计数服务仍使用 selector,不暗中新增外部数据库。

生命周期回调与探针的时序 ​

postStart、preStop 和健康探针在时序上有什么区别? postStart 与 preStop 是生命周期事件回调,readiness/liveness/startup 是反复观测条件的探针。postStart 与容器 ENTRYPOINT 并行触发,不能保证应用已经监听,也不能把它当作主进程之前完成的初始化步骤;有严格先后依赖时应先说明初始化合同。preStop 在停止信号前处理收尾,其耗时占整个终止宽限期,需要与主进程清理共同预算。回调应尽可能轻量,并考虑重复触发时的幂等性。生命周期回调已于 2026-10-17 核对。

旧草稿的全角冒号与缩进不构成有效清单,把 tcpSocket 与 hook 混列也不足以说明目标版本支持何种处理器;应核对目标 API 和弃用状态。保留其“启动时修改首页、停止前收尾”的意图时,还要问:命令存在吗、执行身份可写吗、失败事件怎样观察、超时后会怎样?本课应用通过信号处理收尾,没有加入新的 hook,也未执行旧配置。

继续阅读