单裸金属Kubernetes节点实现动态存储供应可行吗?
当然可以实现!我之前在单节点裸金属K8s环境里给StatefulSet做过动态存储供应,刚好能解决你的问题。你提到的GlusterFS、NFS、hostPath的局限确实存在,但有几个专门适配单节点场景的方案:
1. Local Persistent Volume + 官方Local Storage Provisioner
Local PV本身是绑定到特定节点的静态存储,但配合Kubernetes官方维护的Local Storage Provisioner就能实现动态供应。核心逻辑是:你在单节点上预先划分好多个存储目录/磁盘分区,Provisioner会监控这些路径,当StatefulSet的PVC请求过来时,自动在这些路径下创建子目录作为PV并绑定给PVC,每个副本能拿到独立的存储卷。
配置步骤:
- 第一步,在单节点上创建存储池目录(数量按需,对应StatefulSet的副本数上限):
mkdir -p /mnt/local-storage/pool-{1,2,3,4} # 示例创建4个目录,支持最多4个副本 - 第二步,部署Local Storage Provisioner:
apiVersion: apps/v1 kind: Deployment metadata: name: local-storage-provisioner namespace: kube-system spec: replicas: 1 selector: matchLabels: app: local-storage-provisioner template: metadata: labels: app: local-storage-provisioner spec: nodeSelector: kubernetes.io/hostname: your-single-node-name # 替换为你的节点名称 containers: - name: provisioner image: k8s.gcr.io/sig-storage/local-volume-provisioner:v2.4.0 volumeMounts: - name: provisioner-config mountPath: /etc/provisioner/config - name: storage-pool mountPath: /mnt/local-storage mountPropagation: HostToContainer env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumes: - name: provisioner-config configMap: name: local-storage-config - name: storage-pool hostPath: path: /mnt/local-storage - 第三步,创建对应的ConfigMap和StorageClass:
ConfigMap:
StorageClass:apiVersion: v1 kind: ConfigMap metadata: name: local-storage-config namespace: kube-system data: storageClassMap: | local-storage: hostDir: /mnt/local-storage mountDir: /mnt/local-storage blockCleanerCommand: - "/scripts/shred.sh" - "2" volumeMode: Filesystem fsType: ext4apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer - 第四步,在StatefulSet中配置
volumeClaimTemplates:
注意:需要给StatefulSet加上volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi storageClassName: "local-storage"nodeSelector,确保所有副本都调度到这个单节点上,才能绑定到本地PV。
2. OpenEBS LocalPV Provisioner
OpenEBS是容器原生的存储解决方案,它的LocalPV方案比官方的更灵活,支持直接使用节点上的磁盘、分区或者目录,动态供应的配置也更简洁,适合生产环境。
配置要点:
- 先部署OpenEBS(单节点环境用默认配置即可):
kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml - 创建针对目录的StorageClass(也可以直接用默认的
openebs-localpv):apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: openebs-local-directory provisioner: local.csi.openebs.io parameters: storageType: "directory" basePath: "/mnt/openebs-storage" # 替换为你在单节点上创建的基础目录 volumeBindingMode: WaitForFirstConsumer reclaimPolicy: Delete - 之后StatefulSet的
volumeClaimTemplates直接引用这个StorageClass即可,和上面的配置逻辑一致。
3. 单节点Rook Ceph(仅测试环境)
如果你需要块存储的高级特性(比如快照、克隆),可以尝试单节点Rook Ceph,但绝对不建议用于生产环境——单节点没有数据冗余,节点故障会直接丢失所有数据。
配置流程很简单:按照Rook官方文档部署单节点Ceph集群,创建对应的块存储StorageClass,就能动态供应PV给StatefulSet使用。
总结
- 生产环境优先选OpenEBS LocalPV或官方Local Storage Provisioner,两者都能满足单节点动态供应+多副本StatefulSet的需求,每个副本拥有独立的本地存储。
- 测试环境可以尝试单节点Rook Ceph,但要做好数据丢失的心理准备。
内容的提问来源于stack exchange,提问作者zub0r
相关产品推荐
相关产品推荐

