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 联合使用
-
申明 3 个 PV
yamlapiVersion: 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
-
声明 3 个 PVC
yamlapiVersion: 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 个 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 没有很好的支持。