
Kubernetes 集群为有状态应用提供稳定、可靠且易于管理的持久化存储是核心挑战之一。NFS (Network File System) 作为一种成熟、成本低廉且支持跨节点共享的网络文件系统,成为许多场景下的优选存储后端。而 nfs-client-provisioner 正是连接 Kubernetes 动态存储体系与 NFS 服务的关键桥梁,它实现了存储资源的按需、自动创建与管理。
nfs-client-provisioner 是一个 Kubernetes 的外部存储供应器 (External Provisioner)。它以一个 Pod 的形式运行在集群中,监听用户创建的 PVC 请求,并自动地在指定的 NFS 服务器上创建子目录,同时动态地创建与之绑定的 PV。这实现了从静态存储配置到动态存储供应的转变。
Kubernetes 原生手动管理 NFS PV/PVC 的方式存在以下痛点:
nfs-client-provisioner 通过实现 Dynamic Volume Provisioning 机制,完美解决了上述问题,使 NFS 存储能够像云厂商的块存储一样被动态、自动化地管理。
nfs-client-provisioner 特别适用于以下场景:
1、有状态服务部署:这是最主要的使用场景。当使用 StatefulSet 部署数据库(如 MySQL、PostgreSQL)、消息队列(如 Kafka、RabbitMQ)或缓存系统(如 Redis)时,每个 Pod 实例都需要一个独立且持久化的存储卷,并且 Pod 的生命周期(如重启、调度)不应影响其数据。通过 nfs-client-provisioner 和 StorageClass ,可以轻松实现为 StatefulSet 的每个 Pod 动态创建唯一的 PVC 和 PV。
2、开发测试环境:在需要快速搭建和销毁的临时环境中,动态存储供应能极大提升环境准备效率。
3、混合云/本地化部署:当集群运行在本地数据中心或无法使用云平台原生存储服务时,利用现有的 NFS 服务器构建动态存储层是一个经济高效的方案。
4、多节点读写共享存储:需要多个 Pod 同时读写同一份数据的应用,例如内容管理系统、文件服务器等。
以下是一个完整的部署示例,将 nfs-client-provisioner 部署到 default 命名空间。
前提条件:
创建名为 nfs-provisioner-deployment.yaml 的文件,内容如下:
---
# 1. 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: default
---
# 2. 创建 ClusterRole,定义所需权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
# 3. 将 ClusterRole 绑定到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
# 4. 创建 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: example.com/nfs # 此名称需与下面 Deployment 中的 PROVISIONER_NAME 一致
parameters:
archiveOnDelete: "false" # 删除 PVC 时,是否归档(重命名)NFS 上的目录而非删除
---
# 5. 部署 nfs-client-provisioner
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: default
spec:
replicas: 1
strategy:
type: Recreate # 使用 Recreate 策略,确保单实例
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: provisioner
# 可以使用社区维护的镜像,如 `k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.0`
image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
env:
- name: NFS_SERVER
value: 192.168.1.100
- name: NFS_PATH
value: /data/nfs/k8s
- name: PROVISIONER_NAME
value: example.com/nfs
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
volumes:
- name: nfs-client-root
nfs:
server: 192.168.1.100
path: /data/nfs/k8s# 应用 YAML 文件创建所有资源
kubectl apply -f nfs-provisioner-deployment.yaml
# 查看 Pod 运行状态
kubectl get pods -l app=nfs-client-provisioner -n default
# 查看 StorageClass
kubectl get storageclass如果希望新创建的 PVC 在不指定 storageClassName 时自动使用此 NFS 存储,可以将其设为默认。
kubectl patch storageclass nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'创建一个 PVC 进行测试:
# test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-nfs-pvc
spec:
storageClassName: nfs-storage # 指定我们创建的 StorageClass
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gikubectl apply -f test-pvc.yaml
kubectl get pvc test-nfs-pvc如果状态显示为 Bound ,则说明动态供应成功。同时,在 NFS 服务器的 /data/nfs/k8s/default-test-nfs-pvc-pvc-<随机ID> 目录下会自动创建对应的子目录。
nfs-client-provisioner 将 Kubernetes 强大的动态存储供应能力与 NFS 的简单、共享特性相结合,为在混合云或本地环境中运行有状态工作负载提供了优雅的解决方案。它显著提升了存储管理的自动化水平和运维效率,降低了管理成本,并能够很好地适配 StatefulSet 等复杂控制器,是构建生产级 Kubernetes 存储层的重要工具之一。实际使用中,为确保生产环境的高可用性,可以考虑对 NFS 服务端本身做高可用部署,并对 nfs-client-provisioner 进行适当的监控和告警配置。
“无他,惟手熟尔”!有需要的用起来!
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!