You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes中Cassandra StatefulSet重启后Pod固定调度方案咨询

解决Cassandra StatefulSet Pod固定调度至原节点的方案

核心前提纠正

首先停止用Deployment调度StatefulSet——StatefulSet是K8s专为有状态服务设计的独立控制器,直接部署即可,Deployment包裹会破坏其身份标识(如statefulset.kubernetes.io/pod-name标签),导致亲和性规则失效。


方案1:利用LocalPV节点绑定(推荐,适配Cassandra本地存储场景)

Cassandra通常依赖本地存储获得性能优势,利用LocalPV的节点绑定特性,可让Pod重启后自动调度回原节点:

  1. 为每个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。

  1. 创建匹配的StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
  1. 在StatefulSet的volumeClaimTemplates中使用该StorageClass:
volumeClaimTemplates:
- metadata:
    name: cassandra-data
  spec:
    accessModes: ["ReadWriteOnce"]
    storageClassName: "local-storage"
    resources:
      requests:
        storage: 100Gi

Pod重启时,会因绑定的PVC关联到对应节点的PV,强制调度回原节点。


方案2:修正NodeAffinity配置(无本地存储场景)

通过节点标签+Pod亲和性规则实现固定绑定:

  1. 为每个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
  1. 配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:00:19