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
相关推荐
To_OC21 小时前
跑了3个Docker容器后,我终于搞懂镜像和容器到底啥关系
后端·docker·容器
ltl1 天前
mTLS 工程实践:服务间双向认证怎么落地
kubernetes
tryCbest1 天前
Docker 从零到精通:知识与跨平台使用指南
docker·容器
开始学AI1 天前
Codex2API Docker 使用宿主机代理:OAuth Token 兑换 403 问题排查与解决方案
运维·docker·容器
做前端的娜娜子1 天前
Docker 常用命令全梳理:从镜像拉取到容器编排
docker·容器·掘金·金石计划
m0_579146651 天前
关于Docker Desktop导致C盘空间异常占用的排查与根治方案
运维·docker·容器
易番番ERP1 天前
品牌代理商SKU繁多,ERP如何高效处理新旧规格替换?
数据库·微服务·云原生·sku·易番番erp
栩栩云生1 天前
别再硬记 AWS 和 k8s 命令了!一行命令把十几个云平台的 CLI 全接进 AI
kubernetes·agent·mcp
对象存储与RustFS1 天前
给 Kubernetes 找一个对象存储后端:RustFS Helm 部署 + 应用接入实录
后端·云原生·kubernetes
郝开1 天前
Docker Compose 本地环境搭建:kkFileView
运维·docker·容器