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
相关推荐
万博智云OneProCloud6 小时前
GPU 资源池化最佳实践:规划、调度、监控与运营的五步方法
kubernetes·算力调度·ai基础设施·gpu池化·agione·powerone
分布式存储与RustFS9 小时前
纠删码到底吃掉了多少容量:EC:4、EC:8 的利用率与容错怎么算
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
念何架构之路12 小时前
zap日志SugaredLogger 剖析
云原生·golang
LBL122013 小时前
内网容器部署FTP日志监控服务
运维·服务器·容器
阿里云云原生13 小时前
云效智能评审:让团队规则持续生效
云原生
阿里云云原生14 小时前
智能聚类:从海量 Trace 中理解 Agent 的行为和表现
云原生·agent
阿里云云原生14 小时前
云栖丨AI 应用进入生产,开始拼「实时数据智能」
云原生
溜达的大象14 小时前
极空间部署Traggo时间追踪工具:Docker安装、标签管理与cpolar远程访问
运维·docker·容器
脏脏a15 小时前
极空间部署 Dashlet:Docker 搭建私人导航仪表盘,再配置固定公网访问
运维·docker·容器
运维开发王义杰15 小时前
跳出网络与文件系统:Linux CPU 与内存调优的“防假死”实战
云原生