Kubernetes 硬盘持久化之 PV 和 PVC

Kubernetes 硬盘持久化之 PV 和 PVC

Persistent Volume 定义

持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,拥有独立于任何使用 PV 的 Pod 的生命周期。

Persistent Volume 访问权限

权限 缩写 描述
ReadWriteOnce RWO 卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式仍然可以在同一节点上运行的多个 Pod 访问该卷。 对于单个 Pod 的访问,请参考 ReadWriteOncePod 访问模式。
ReadOnlyMany ROX 卷可以被多个节点以只读方式挂载。
ReadWriteMany RWX 卷可以被多个节点以读写方式挂载。

Persistent Volume 回收机制

机制
Retain 回收策略 Retain 使得用户可以手动回收资源。当 PersistentVolumeClaim 对象被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为"已释放(released)"。 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。
Delete 对于支持 Delete 回收策略的卷插件,删除动作会将 PersistentVolume 对象从 Kubernetes 中移除,同时也会从外部基础设施中移除所关联的存储资产。
Recycle(废弃) 如果下层的卷插件支持,回收策略 Recycle 会在卷上执行一些基本的擦除 (rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。

Persistent Volume Claim 定义

持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存)。同样 PVC 申领也可以请求特定的大小和访问模式。

PV 和 PVC 联合使用

  1. 申明 3 个 PV

    yaml 复制代码
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv1
      labels:
        app: pv1
    spec:
      nfs:
        server: 192.168.31.60
        path: /nfs-test/volume1
      accessModes: ["ReadWriteOnce"]
      persistentVolumeReclaimPolicy: Retain
      capacity:
        storage: 1Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv2
      labels:
        app: pv2
    spec:
      nfs:
        server: 192.168.31.60
        path: /nfs-test/volume2
      accessModes: ["ReadOnlyMany"]
      persistentVolumeReclaimPolicy: Delete
      capacity:
        storage: 1Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv3
      labels:
        app: pv3
    spec:
      nfs:
        server: 192.168.31.60
        path: /nfs-test/volume3
      accessModes: ["ReadWriteMany"]
      persistentVolumeReclaimPolicy: Delete
      capacity:
        storage: 1Gi
    复制代码
    root@k8s-master1:~# kubectl get pv
    NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
    pv1    1Gi        RWO            Retain           Available                          <unset>                          8s
    pv2    1Gi        ROX            Delete           Available                          <unset>                          8s
    pv3    1Gi        RWX            Delete           Available                          <unset>                          8s
  2. 声明 3 个 PVC

    yaml 复制代码
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc1
    spec:
      accessModes: ["ReadWriteOnce"]
      selector:
        matchLabels:
          app: pv1
      resources:
        requests:
          storage: 100Mi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc2
    spec:
      accessModes: ["ReadOnlyMany"]
      selector:
        matchLabels:
          app: pv2
      resources:
        requests:
          storage: 100Mi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc3
    spec:
      accessModes: ["ReadWriteMany"]
      selector:
        matchLabels:
          app: pv3
      resources:
        requests:
          storage: 100Mi
    复制代码
    root@k8s-master1:~# kubectl get pvc
    NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
    pvc1   Bound    pv1      1Gi        RWO                           <unset>                 2m35s
    pvc2   Bound    pv2      1Gi        ROX                           <unset>                 2m35s
    pvc3   Bound    pv3      1Gi        RWX                           <unset>                 2m35s
  3. 申明 3 个 Deployment 进行测试

    复制代码
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pv1-deploy
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: pv1-pod
      template:
        metadata:
          labels:
            app: pv1-pod
        spec:
          containers:
          - name: pv1-test
            image: busybox
            imagePullPolicy: IfNotPresent
            command: ["/bin/sh"]
            args: ["-c","sleep 3600"]
            volumeMounts:
            - name: pv1-test
              mountPath: /pv1-test
          volumes:
          - persistentVolumeClaim:
              claimName: pvc1
            name: pv1-test
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pv2-deploy
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: pv2-pod
      template:
        metadata:
          labels:
            app: pv2-pod
        spec:
          containers:
            - name: pv2-test
              image: busybox
              imagePullPolicy: IfNotPresent
              command: ["/bin/sh"]
              args: ["-c","sleep 3600"]
              volumeMounts:
                - name: pv2-test
                  mountPath: /pv2-test
          volumes:
            - persistentVolumeClaim:
                claimName: pvc2
              name: pv2-test
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pv3-deploy
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: pv3-pod
      template:
        metadata:
          labels:
            app: pv3-pod
        spec:
          containers:
            - name: pv3-test
              image: busybox
              imagePullPolicy: IfNotPresent
              command: ["/bin/sh"]
              args: ["-c","sleep 3600"]
              volumeMounts:
                - name: pv3-test
                  mountPath: /pv3-test
          volumes:
            - persistentVolumeClaim:
                claimName: pvc3
              name: pv3-test
    
    NAME                          READY   STATUS    RESTARTS   AGE   IP              NODE          NOMINATED NODE   READINESS GATES
    pv1-deploy-9b857996d-9mlwq    1/1     Running   0          5m    10.244.194.97   k8s-worker1   <none>           <none>
    pv1-deploy-9b857996d-gs95v    1/1     Running   0          5m    10.244.126.40   k8s-worker2   <none>           <none>
    pv2-deploy-6f76d7c88b-bgr8k   1/1     Running   0          5m    10.244.126.41   k8s-worker2   <none>           <none>
    pv2-deploy-6f76d7c88b-grq7q   1/1     Running   0          5m    10.244.194.95   k8s-worker1   <none>           <none>
    pv3-deploy-8696ff555b-hkwgm   1/1     Running   0          5m    10.244.194.96   k8s-worker1   <none>           <none>
    pv3-deploy-8696ff555b-z72pp   1/1     Running   0          5m    10.244.126.42   k8s-worker2   <none>           <none>

    测试过程中发现访问模式没有起到任何限制作用,可能 Kubernetes 对特定配置下 NFS 没有很好的支持。

相关推荐
伊成1 小时前
详解docker挂载目录常用方式
docker·容器·eureka
风清再凯1 小时前
docker镜像的构建image
运维·docker·容器
风清再凯1 小时前
docker 网络
网络·docker·容器
饭碗、碗碗香1 小时前
【开发常用命令】:docker常用命令
linux·运维·笔记·学习·docker·容器
郝同学的测开笔记2 小时前
一次业务投诉引发的思考:如何优雅地将K8s服务暴露给外部?
后端·kubernetes
rocksun3 小时前
云原生和开源助力扩展Agentic AI工作流
人工智能·云原生·开源
白露与泡影3 小时前
springboot + nacos + k8s 优雅停机
spring boot·后端·kubernetes
_板栗_3 小时前
k8s 中 cpu 核数的理解
云原生·容器·kubernetes
谷新龙0013 小时前
docker compose搭建elk 8.6.2
elk·docker·容器
程序员阿超的博客3 小时前
云原生核心技术 (12/12): 终章:使用 GitLab CI 将应用自动部署到 K8s (保姆级教程)
ci/cd·云原生·gitlab