StatefulSet部署遇PVC未绑定问题求助:0/1节点可用
根据Kubernetes官方文档,StatefulSet的VolumeClaimTemplate若未指定StorageClass会使用默认存储类。我按下方配置创建了StatefulSet,已提前创建密钥、镜像拉取密钥并完成节点标签设置,但部署后Pod处于Pending状态,执行kubectl describe pod ches-0 -n ches报错:
0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims。
请问我遗漏了什么配置?
配置文件
apiVersion: apps/v1 kind: StatefulSet metadata: namespace: ches name: ches spec: serviceName: ches replicas: 1 selector: matchLabels: app: ches template: metadata: labels: app: ches spec: serviceAccountName: ches-serviceaccount nodeSelector: ches-worker: "true" volumes: - name: data hostPath: path: /data/test containers: - name: ches image: [here I have the repo] imagePullPolicy: Always securityContext: privileged: true args: - server - --console-address - :9011 - /data env: - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: name: ches-keys key: access-key - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: name: ches-keys key: secret-key ports: - containerPort: 9000 hostPort: 9011 resources: limits: cpu: 100m memory: 200Mi volumeMounts: - name: data mountPath: /data imagePullSecrets: - name: edge-storage-token volumeClaimTemplates: - metadata: name: data spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
问题分析与解决方案
你遇到的核心问题是存储配置冲突,同时存在两个同名的存储定义,且集群可能未正确配置默认存储类,具体如下:
1. 存储配置冲突
你的StatefulSet配置里同时定义了:
- Pod模板中的
volumes(hostPath类型,名称为data) - StatefulSet顶层的
volumeClaimTemplates(名称也为data)
当StatefulSet存在volumeClaimTemplates时,Kubernetes会自动为每个Pod生成对应的PVC(比如ches-data-0),并优先使用该PVC作为存储,而非Pod模板里的hostPath卷。但这个自动生成的PVC因无法绑定到PV,导致Pod处于Pending状态。
2. 可选解决方案
根据你的实际存储需求二选一:
方案一:使用hostPath存储(无需PVC)
删除StatefulSpec中的volumeClaimTemplates字段,保留Pod模板里的hostPath配置。此时Pod会直接使用节点上的/data/test路径作为存储,无需创建PVC,也就不会出现PVC未绑定的问题。
修改后的核心配置片段:
spec: # 移除volumeClaimTemplates字段 template: spec: volumes: - name: data hostPath: path: /data/test containers: - name: ches volumeMounts: - name: data mountPath: /data
方案二:使用动态PVC存储(依赖StorageClass)
删除Pod模板中的volumes字段(hostPath部分),保留volumeClaimTemplates,同时确保集群存在默认StorageClass:
- 执行
kubectl get storageclass查看集群中的存储类,确认有带(default)标记的存储类。 - 若没有默认存储类,要么将现有存储类设置为默认,要么在
volumeClaimTemplates的spec中添加storageClassName: <你的存储类名称>字段,指定要使用的存储类。
修改后的核心配置片段:
spec: volumeClaimTemplates: - metadata: name: data spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi # 可选:如果没有默认存储类,指定存储类名称 # storageClassName: "your-storage-class-name" template: spec: # 移除volumes字段 containers: - name: ches volumeMounts: - name: data mountPath: /data
额外检查
- 若选择方案一,需确保目标节点的
/data/test路径已创建,且Pod运行的用户(容器内)对该路径有读写权限。 - 若选择方案二,需确认默认存储类具备动态创建PV的能力(比如云厂商存储类、NFS provisioner等)。
内容的提问来源于stack exchange,提问作者e7lT2P

