Kubernetes中Cassandra StatefulSet重启后Pod固定调度方案咨询
解决Cassandra StatefulSet Pod固定调度至原节点的方案
核心前提纠正
首先停止用Deployment调度StatefulSet——StatefulSet是K8s专为有状态服务设计的独立控制器,直接部署即可,Deployment包裹会破坏其身份标识(如statefulset.kubernetes.io/pod-name标签),导致亲和性规则失效。
方案1:利用LocalPV节点绑定(推荐,适配Cassandra本地存储场景)
Cassandra通常依赖本地存储获得性能优势,利用LocalPV的节点绑定特性,可让Pod重启后自动调度回原节点:
- 为每个Worker Node创建绑定到自身的LocalPV:
apiVersion: v1 kind: PersistentVolume metadata: name: cassandra-pv-0 spec: capacity: storage: 100Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /mnt/disks/cassandra-0 # 节点上的本地存储路径 nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - worker-node-0 # 替换为实际节点名称
按此模板为20个节点创建对应PV。
- 创建匹配的StorageClass:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer
- 在StatefulSet的
volumeClaimTemplates中使用该StorageClass:
volumeClaimTemplates: - metadata: name: cassandra-data spec: accessModes: ["ReadWriteOnce"] storageClassName: "local-storage" resources: requests: storage: 100Gi
Pod重启时,会因绑定的PVC关联到对应节点的PV,强制调度回原节点。
方案2:修正NodeAffinity配置(无本地存储场景)
通过节点标签+Pod亲和性规则实现固定绑定:
- 为每个Worker Node打专属标签:
# 为20个节点依次打标签,示例: kubectl label nodes worker-node-0 cassandra-target=0 kubectl label nodes worker-node-1 cassandra-target=1 ... kubectl label nodes worker-node-19 cassandra-target=19
- 配置StatefulSet的亲和性规则(需用Helm/Kustomize等模板工具生成):
apiVersion: apps/v1 kind: StatefulSet metadata: name: cassandra spec: replicas: 20 template: spec: affinity: # 硬亲和性:强制Pod调度到对应标签的节点 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cassandra-target operator: Equals values: - {{ index (splitList "-" .Pod.Name) 1 }} # 提取Pod名称后缀数字(如cassandra-0的0) # 反亲和性:确保单节点仅运行一个Cassandra Pod podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - cassandra topologyKey: kubernetes.io/hostname containers: - name: cassandra image: cassandra:latest ...
若不使用模板工具,可编写脚本生成每个副本的专属亲和性规则,或用Kustomize的patchesJson6902批量配置。
方案3:静态绑定NodeName(不推荐)
仅适用于Worker Node绝对稳定的场景,直接指定Pod运行节点:
# 需用模板工具生成每个副本的nodeName spec: template: spec: nodeName: worker-node-{{ .Pod.Index }} ...
缺点:节点故障时Pod无法调度到其他节点,会长期处于Pending状态。
常见失效排查
- 检查节点标签:用
kubectl get nodes --show-labels确认标签正确添加 - 查看Pod调度事件:
kubectl describe pod <pod-name>获取调度失败原因,调整亲和性规则 - 确认StatefulSet身份标识:检查Pod是否存在
statefulset.kubernetes.io/pod-name标签
内容的提问来源于stack exchange,提问作者Nilay Tiwari
相关产品推荐
相关产品推荐

