k8s创建基于nfs的pv、pvc

手动创建挂载目录和pv的方式创建pvc

编辑yaml文件

bash 复制代码
vi pvc.yaml

写入以下内容

bash 复制代码
kind: PersistentVolume
metadata:
    name: test-data-pv
spec:
    capacity:
      storage: 2Gi
    accessModes:
      - ReadWriteMany
    persistentVolumeReclaimPolicy: Recycle
    storageClassName: "test-data-pv"
    nfs:
      path: "/data/nfs/test/data" # 注意该目录必须是在nfs目录下创建的子目录
      server: 192.168.1.1  # nfs ip
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-data-pvc
  namespace: test-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  storageClassName: test-data-pv

执行yaml文件

bash 复制代码
# 创建服务
kubectl create -f pvc.yaml
# 卸载服务
kubectl delete -f pvc.yaml

自动创建挂载目录和pv的方式创建pvc

NFS Subdir Provisioner本质上是一个实现了Kubernetes CSI规范的控制器。其架构设计遵循了Kubernetes的声明式API原则,主要包含三个关键组件:

Provisioner Controller :持续监听API Server的PVC变更事件

NFS Client :与指定NFS服务器建立稳定连接

Subdir Manager :负责目录创建/删除和权限管理

当用户创建PVC时,完整的工作流程如下:

Provisioner检测到新的PVC对象

根据StorageClass配置生成唯一子目录路径(格式通常是 -- )

通过NFS协议在服务器端创建对应子目录

自动生成PV对象并绑定到PVC

在Pod挂载阶段通过kubelet完成NFS挂载

创建yaml文件

bash 复制代码
vim storage.yaml

内容如下:

需要替换的内容看注释

镜像包

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"]
  - apiGroups: [""]
    resources: ["endpoints"]
    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: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 198.1.1.1  # 替换为你的NFS服务器IP
            - name: NFS_PATH
              value: /data/k8s-nfs/k8s_storage # 替换为你的NFS目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 198.1.1.1  # 替换为你的NFS服务器IP
            path: /data/k8s-nfs/k8s_storage # 替换为你的NFS目录
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "true"
reclaimPolicy: Delete # Delete:删除PVC时自动删除底层存储资源 Retain:保留底层存储资源,需要手动清理
allowVolumeExpansion: true

创建服务

bash 复制代码
kubectl apply -f storage.yaml

测试:

bash 复制代码
# 创建测试pvc
vi pvc-test.yaml
# 内容如下
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-nfs-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs-storage

# 创建pvc
kubectl apply -f pvc-test.yaml
# 查看pvc
kubectl get pvc -A
# 应有如下内容
default               test-nfs-pvc               Bound    pvc-4e14de0e-1de9-42be-b764-21197de1bb8f   1Gi        RWX            nfs-storage               12s
相关推荐
闲云自留地6 小时前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
weirong9 小时前
Operator 上生产前补的 6 件事,和 5 件我明确不做的
kubernetes
孙克旭_10 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_11 小时前
云原生基础之Containerd容器运行时
运维·云原生
分布式存储与RustFS11 小时前
RustFS 自建对象存储实战目录:110 篇按场景分类(持续更新)
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
java_logo1 天前
Docker 部署 EmulatorJS:轻松搭建浏览器复古游戏平台
游戏·docker·容器·复古游戏·轩辕镜像·emulatorjs·红白机
吴声子夜歌1 天前
Kubernetes权威指南——网络原理(一)
网络·容器·kubernetes
方便面不加香菜1 天前
Docker Container --容器及容器的操作案例详解
运维·docker·容器
无言听风雨丶1 天前
Kubernetes Service Mesh 与 mTLS 实战:从网络可达走向零信任服务通信
网络·kubernetes·service_mesh
weirong1 天前
跟原生 HPA 做对照压测:五轮里前四轮全废,最后一个结论也被我自己降级
kubernetes