6.1 StatefulSet:果树区的编号规矩


6.1 StatefulSet:果树区的编号规矩

本节摘要:StatefulSet 为每株 Pod 提供稳定身份:按序编号的名字、按序的起停、与编号绑定的独立存储,从而适合数据库、消息队列等有状态应用。它与 Deployment 的核心差别是"株可互换"变成"株即身份"。本节为书屋种下 PostgreSQL 果树组,验证编号与稳定域名的行为,并给出有状态上集群的审慎建议。

先看一个翻车案例

有位心急的同事听说"上了集群自动补苗",就把数据库当普通 Deployment 种了,replicas 设为二。结果两株"数据库苗"同时起盆,各自认了一套空白目录,互相不知道对方存在:主从复制没建立、数据各写各的,半小时后两边数据已经无法合并。补苗机制反而补出了第二棵"平行宇宙的果树"。

翻车根源是拿叶菜的农具种果树。叶菜的要义是株可互换——名字随机后缀、地址随起随变、谁替代谁都行,Deployment 的全部设计都围绕"互换"展开。果树的要义恰恰相反:株即身份——零号就是主库、一号就是从库,名字不能变(复制关系认名字)、存储不能串(各浇各的地)、起停要有顺序(先主后从)。StatefulSet 就是把这三条规矩写进机制的农具。

图:果树区与叶菜区的身份差异

图:果树区与叶菜区的身份差异

种一排果树

书屋的 PostgreSQL 果树组清单(节选了最有信息量的部位):

# 果树区清单:主从两棵 各有编号与地块 apiVersion: apps/v1 kind: StatefulSet metadata: name: shelf-db namespace: greenlib-prod spec: serviceName: db-headless # 配套的无闸服务名(见下文) replicas: 2 selector: matchLabels: app: shelf-db template: metadata: labels: app: shelf-db spec: containers: - name: postgres image: postgres:15 envFrom: - secretRef: name: api-db-cred # 口令来自第 5 章农药柜 ports: - containerPort: 5432 volumeClaimTemplates: # 每株果树自动配一块专属地(6.2 细讲) - metadata: name: db-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 20Gi
kubectl apply -f db-statefulset.yaml -n greenlib-prod # statefulset.apps/shelf-db created kubectl get pods -n greenlib-prod -l app=shelf-db -w # 按序出生的现场:零号先完全就绪 一号才开工 # NAME READY STATUS AGE # shelf-db-0 0/1 ContainerCreating 2s # shelf-db-0 1/1 Running 25s # shelf-db-1 0/1 ContainerCreating 26s # shelf-db-1 1/1 Running 48s

对比 3.2 的 Deployment:那时几株苗一拥而上同时造盆,这里却严格排队。有序起停是果树区的第二条规矩:扩容从零号往大编号推进,缩容从大编号往零号收回——先主后从、先活后死,数据库世界的礼数。

编号带来的三样实惠

稳定名字。 苗名从随机后缀变成固定编号,shelf-db-0 重建后还叫 shelf-db-0。复制配置里写"从零号同步",永远不用改。

稳定域名。 StatefulSet 必须配一个 headless Service(无闸服务:没有虚拟 IP,DNS 直接返回各株苗的地址)。于是每株果树有一个直达域名:

# 在集群内验证直达域名 kubectl run dns-probe --rm -it --image=busybox:1.36 --restart=Never -n greenlib-prod -- sh nslookup shelf-db-0.db-headless # Address 1: 10.24.3.7 shelf-db-0.db-headless.greenlib-prod.svc.cluster.local # 域名直达具体某株果树 而不是笼统一群 nslookup db-headless # Address 1: 10.24.3.7 ... 两行:两株各自的地址都返回 # Address 2: 10.24.4.12 ... exit

普通 Service(有闸)把一群苗模糊成一个地址,headless Service 把每株苗亮出来供点名——前者给调用方,后者给"需要互相认亲"的集群化软件。

稳定存储。 volumeClaimTemplates 让每株果树自动领到专属地块:shelf-db-0 的数据盘永远跟着零号,苗死了补种,新苗接过同一块地接着长。地块怎么租、怎么还,是下一节正题。

⚠️ 审慎提醒:StatefulSet 只提供"身份与地块"的机制,不自动配置主从复制——谁当主、怎么同步,是软件层的事,通常交给专门的 Operator 或手工脚本完成。把数据库种进集群前,先问自己一句:我真的需要自己种吗?托管数据库服务往往是更省心的选择。自己种的理由应当是明确的:成本、数据主权或学习。

果树的更新与缩容

StatefulSet 默认的更新策略与 Deployment 的滚动类似,但严格按编号倒序进行:先动一号从库,确认健康,再动零号主库。主从结构的数据库尤其受益——从库先试新版本,等于自带灰度。缩容同样倒序,且被收株的地块默认保留只解绑,防误缩丢数据;真要缩,先确认数据已安全迁移。求稳还可以把策略改为 OnDelete:不自动滚动,手动删一株才更新一株,节奏完全握在自己手里。

本节要点回顾

  • 翻车根源:拿"株可互换"的 Deployment 种"株即身份"的数据库
  • StatefulSet 三规矩:稳定名字、有序起停、按编号绑定存储
  • headless Service 提供直达每株的域名,供集群化软件认亲
  • volumeClaimTemplates 自动给每株发专属地块,苗换代地不换
  • StatefulSet 只管身份不管复制逻辑,上生产前先想清楚要不要自己种

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U