NFS Subdir Provisioner 实现K8S动态PV供应

0 阅读5分钟

本文转载自:mp.weixin.qq.com/s/9w_PN7dLQ…

原生 NFS + NFS Subdir External Provisioner,这是 K8S 社区最主流的方案 ——原生 NFS 服务器提供存储能力,NFS Subdir Provisioner 实现 K8S 动态 PV 供应,能自动为每个 PVC 创建专属 NFS 子目录(避免多 PVC 数据混叠),部署简单、维护成本低,适合 90% 的中小规模 K8S 集群,部署以Ubuntu24为例。

搭建K8S后端存储的NFS服务器流程

首先了解当前服务器的存储情况和环境配置。

第一步:检查存储设备情况

  1. 查看磁盘列表:
lsblk

识别到新设备(如/dev/sdb),未分区、未格式化。

  1. 确认磁盘详情:
sudo fdisk -l /dev/sdb

确认/dev/sdb是未分区的新磁盘。

第二步:准备数据盘

(步骤:创建分区 → 格式化文件系统 → 创建挂载点并挂载)

  1. 创建磁盘分区:
echo -"n\np\n1\n\n\nw" | sudo fdisk /dev/sdb
  1. 格式化文件系统(ext4):
sudo mkfs.ext4 /dev/sdb1
  1. 创建挂载点:
sudo mkdir /nfs-storage
  1. 挂载分区到挂载点:
sudo mount /dev/sdb1 /nfs-storage
  1. 配置开机自动挂载:
sudo tee -a /etc/fstab <<EOF
/dev/sdb1 /nfs-storage ext4 defaults 0 0
EOF
  1. 验证挂载情况:
df -h /nfs-storage

显示/dev/sdb1已挂载到/nfs-storage即成功。

第三步:安装NFS服务器

sudo apt update && sudo apt install -y nfs-kernel-server

第四步:配置NFS共享

  1. 创建NFS共享目录结构:
sudo mkdir -p /nfs-storage/k8s-pvs
  1. 修改共享目录权限:
sudo chown nobody:nogroup /nfs-storage/k8s-pvs && sudo chmod 777 /nfs-storage/k8s-pvs
  1. 配置/etc/exports(NFS共享规则): (注:原直接编辑文件失败,改用tee命令)
sudo tee /etc/exports <<'EOF'
# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
/nfs-storage/k8s-pvs *(rw,sync,no_subtree_check,no_root_squash,fsid=0)
EOF

第五步:启动和配置NFS服务

  1. 重启NFS服务:
sudo systemctl restart nfs-kernel-server
  1. 设置NFS服务开机自启:
sudo systemctl enable nfs-kernel-server
  1. 验证NFS共享配置:
sudo exportfs -v

第六步:配置防火墙(如果需要)

  1. 检查防火墙状态:
sudo ufw status

若防火墙未启用,则无需额外配置。

第七步:测试NFS共享

  1. 本地创建测试挂载点并挂载NFS:
sudo mkdir -p /tmp/test-nfs && sudo mount -t nfs localhost:/nfs-storage/k8s-pvs /tmp/test-nfs
  1. 写入测试文件验证:
df -h /tmp/test-nfs && echo "NFS测试成功" | sudo tee /tmp/test-nfs/test.txt
  1. 卸载测试挂载点并清理:
sudo umount /tmp/test-nfs && sudo rmdir /tmp/test-nfs

第八步:创建NFS Subdir Provisioner所需目录

sudo mkdir -p /nfs-storage/k8s-pvs/.nfs-provisioner && sudo chown nobody:nogroup /nfs-storage/k8s-pvs/.nfs-provisioner

第九步:验证最终配置

(示例:检查共享目录权限)

ls -ld /nfs-storage/k8s-pvs

第十步:生成K8S部署配置文件(nfs-provisioner-deployment.yaml

# NFS Subdir External Provisioner Deployment for K8S
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: default
---
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"]
---
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
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: default
rules:
  - apiGroups: ["coordination.k8s.io"]
    resources: ["leases"]
    verbs: ["get""list""watch""create""update""patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: leader-locking-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.9.2  # 替换为你的NFS服务器IP
            - name: NFS_PATH
              value: /nfs-storage/k8s-pvs
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.9.2  # 替换为你的NFS服务器IP
            path: /nfs-storage/k8s-pvs
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true

完成总结

已完成的核心配置

  1. 存储准备

    • 识别并分区格式化新磁盘(/dev/sdb
    • 格式化为ext4文件系统
    • 创建/nfs-storage挂载目录
    • 配置开机自动挂载
  2. NFS服务器

    • 安装nfs-kernel-server服务
    • 创建NFS共享目录(/nfs-storage/k8s-pvs
    • 配置/etc/exports允许所有客户端访问(权限:rw,sync,no_subtree_check,no_root_squash,fsid=0
    • 启动并设置NFS服务开机自启
    • 本地挂载测试验证

NFS服务器信息

  • 服务器IP:192.168.9.2
  • 共享路径:/nfs-storage/k8s-pvs
  • 访问权限:所有客户端可读写

K8S部署准备

  • 已生成nfs-provisioner-deployment.yaml文件,包含:

    • ServiceAccount和RBAC权限配置
    • NFS Provisioner Deployment
    • NFS StorageClass

下一步操作

  1. 在K8S集群中部署Provisioner:
kubectl apply -f nfs-provisioner-deployment.yaml
  1. 创建测试PVC验证:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs-storage

PVC创建后会自动绑定PV,PV实际路径对应/nfs-storage/k8s-pvs/default-test-nfs-pvc-xxx

安全建议(可选)

  1. 限制NFS访问来源为K8S节点网段(替换/etc/exports中的*
  2. 启用NFS的Kerberos认证
  3. 定期备份NFS存储数据

本文转载自:mp.weixin.qq.com/s/9w_PN7dLQ…