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
相关推荐
艾伦_耶格宇7 小时前
【DOCKER容器实战】-5 Docker容器镜像的构建
运维·docker·容器
分布式存储与RustFS8 小时前
RustFS 该跟 stable 还是 nightly?两条版本线的分工、风险与回退,一张表说清
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
ggaofeng10 小时前
k8s中的dns
云原生·容器·kubernetes
我不会起名字32221 小时前
K8s Ingress 返回 502 但后端日志正常:4 类上游断连与排查链
kubernetes·k8s·ingress·502·keepalive
姜鱼问生1 天前
每次开机手动检查 6 样东西?我写了个 2 秒自检脚本
运维·网络·nginx·docker·容器
wangqiaowq1 天前
PostgresSQL server Docker 安装部署
运维·docker·容器
程序员阿明1 天前
docker搭建视频流服务go2rtc,webRTC
docker·容器·webrtc
JavaPub-rodert1 天前
Docker 容器为什么 stop 半天停不下来?讲透 PID 1、SIGTERM、SIGKILL、僵尸进程与 tini
运维·docker·容器
我不会起名字3221 天前
Pod 一直 Pending:调度器 5 类失败原因与 kubectl describe 的正确读法
云原生·kubernetes·调度·排查
我不会起名字3221 天前
K8s 服务 DNS 解析偶发 5 秒超时:conntrack 与 ndots 的 3 个坑
kubernetes·k8s·dns·conntrack·coredns