概述

与管理计算实例相比,管理存储是一个明显的问题。PersistentVolume子系统为用户和管理员提供了一个API,该API从如何使用存储中抽象出如何提供存储的详细信息。为此,我们引入了两个新的API资源:PersistentVolume和PersistentVolumeClaim

PV概述

PersistentVolume (PV)是集群中由管理员提供或使用存储类动态提供的一块存储。它是集群中的资源,就像节点是集群资源一样。

PV是与Volumes类似的卷插件,但其生命周期与使用PV的任何单个Pod无关。由此API对象捕获存储的实现细节,不管是NFS、iSCSI还是特定于云提供商的存储系统。

PVC概述

PersistentVolumeClaim (PVC) 是用户对存储的请求。它类似于Pod;Pods消耗节点资源,而PVC消耗PV资源。Pods可以请求特定级别的资源(CPU和内存)。Claim可以请求特定的存储大小和访问模式(例如,它们可以挂载一次读写或多次只读)。

虽然PersistentVolumeClaims (PVC) 允许用户使用抽象的存储资源,但是用户通常需要具有不同属性(比如性能)的PersistentVolumes (PV) 来解决不同的问题。集群管理员需要能够提供各种不同的PersistentVolumes,这些卷在大小和访问模式之外还有很多不同之处,也不向用户公开这些卷是如何实现的细节。对于这些需求,有一个StorageClass资源。

volume 和 claim的生命周期

PV是集群中的资源。PVC是对这些资源的请求,并且还充当对资源的声明检查。PV和PVC之间的交互遵循以下生命周期:

供应

有两种方式配置PV:静态的或动态的。

静态配置

集群管理员创建一些PV。它们带有可供集群用户使用的实际存储的详细信息。存在于Kubernetes API中,可供使用。

动态配置

当管理员创建的静态PV没有一个与用户的PersistentVolumeClaim匹配时,集群可能会尝试动态地为PVC提供一个卷。此配置基于StorageClasses:PVC必须请求存储类,并且管理员必须已经创建并配置了该类,才能进行动态配置。声明该类为 "",可以有效地禁用其动态配置。

要启用基于存储级别的动态存储配置,集群管理员需要启用API Server上的DefaultStorageClass[准入控制器]。例如,通过确保DefaultStorageClass位于API Server组件的 --enable-admission-plugins标志,使用逗号分隔的有序值列表中,可以完成此操作。

绑定

用户创建(或者在动态配置的情况下,已经创建)具有特定存储请求量(大小)和特定访问模式的PersistentVolumeClaim。主控制器中的控制循环监视新的PV,找到匹配的PV(如果可能的话),并将它们绑定在一起。如果PV为新的PVC动态配置,那么循环始终将该PV绑定到PVC。否则,用户始终至少得到他们所要求的,但是存储量可能会超过所要求的范围。

一旦绑定,无论是如何绑定的,PersistentVolumeClaim绑定都是互斥的。PVC到PV的绑定是一对一的映射,使用ClaimRef,它是PersistentVolume和PersistentVolumeClaim之间的双向绑定。

如果不存在匹配的卷,声明(Claims)将无限期保持未绑定。随着匹配量的增加,声明将受到约束。例如,配备有许多50Gi PV的群集将与请求100Gi的PVC不匹配。当将100Gi PV添加到群集时,可以绑定PVC。

注意:静态时PVC与PV绑定时会根据storageClassName(存储类名称)和accessModes(访问模式)判断哪些PV符合绑定需求。然后再根据存储量大小判断,首先存PV储量必须大于或等于PVC声明量;其次就是PV存储量越接近PVC声明量,那么优先级就越高(PV量越小优先级越高)。

使用

Pods使用声明(claims)作为卷。集群检查声明以找到绑定卷并为Pod挂载该卷。对于支持多种访问模式的卷,用户在其声明中作为Pod中卷使用时指定所需的模式。

一旦用户拥有一个声明并且该声明被绑定,则绑定的PV就属于该用户。用户通过在Pod的卷块中包含的persistentVolumeClaim部分来调度Pods并访问其声明的PV。

持久化声明保护

“使用中的存储对象保护” :该功能的目的是确保在Pod活动时使用的PersistentVolumeClaims (PVC)和绑定到PVC的PersistentVolume (PV)不会从系统中删除,因为这可能会导致数据丢失。

如果用户删除了Pod正在使用的PVC,则不会立即删除该PVC;PVC的清除被推迟,直到任何Pod不再主动使用PVC。另外,如果管理员删除绑定到PVC的PV,则不会立即删除该PV;PV的去除被推迟,直到PV不再与PVC结合。

回收策略

当用户处理完他们的卷时,他们可以从允许回收资源的API中删除PVC对象。PersistentVolume的回收策略告诉集群在释放卷的声明后该如何处理它。目前,卷可以被保留、回收或删除

Retain (保留)

保留回收策略允许手动回收资源。当PersistentVolumeClaim被删除时,PersistentVolume仍然存在,并且该卷被认为是“释放”的。但是,由于之前声明的数据仍然存在,因此另一个声明尚无法得到。管理员可以手动回收卷。

Delete (删除)

对于支持Delete回收策略的卷插件,删除操作会同时从Kubernetes中删除PersistentVolume对象以及外部基础架构中的关联存储资产,例如AWS EBS,GCE PD,Azure Disk或Cinder卷。动态配置的卷将继承其StorageClass的回收策略,默认为Delete。管理员应根据用户的期望配置StorageClass。

Recycle (回收)

如果基础卷插件支持,Recycle回收策略将rm -rf /thevolume/*对该卷执行基本的擦除并使其可用于新的声明。

Persistent Volumes类型

PersistentVolume类型作为插件实现。Kubernetes当前支持以下插件:

 1 GCEPersistentDisk
 2 AWSElasticBlockStore
 3 AzureFile
 4 AzureDisk
 5 CSI
 6 FC (Fibre Channel)
 7 FlexVolume
 8 Flocker
 9 NFS
10 iSCSI
11 RBD (Ceph Block Device)
12 CephFS
13 Cinder (OpenStack block storage)
14 Glusterfs
15 VsphereVolume
16 Quobyte Volumes
17 HostPath (仅用于单节点测试——本地存储不受任何方式的支持,也不能在多节点集群中工作)
18 Portworx Volumes
19 ScaleIO Volumes
20 StorageOS

PV示例与参数说明

PV示例

 1 apiVersion: v1
 2 kind: PersistentVolume
 3 metadata:
 4   name: pv0003
 5 spec:
 6   capacity:
 7     storage: 5Gi
 8   volumeMode: Filesystem
 9   accessModes:
10     - ReadWriteOnce
11   persistentVolumeReclaimPolicy: Recycle
12   storageClassName: slow
13   mountOptions:
14     - hard
15     - nfsvers=4.1
16   nfs:
17     path: /tmp
18     server: 172.17.0.2

Capacity:通常,PV将具有特定的存储容量设置。当前,存储大小是可以设置或请求的唯一资源。将来的属性可能包括IOPS,吞吐量等。

volumeMode:可选参数,为Filesystem或Block。Filesystem是volumeMode省略参数时使用的默认模式。

accessModes:PersistentVolume可以通过资源提供者支持的任何方式安装在主机上。如下文表中所示,提供商将具有不同的功能,并且每个PV的访问模式都将设置为该特定卷支持的特定模式。例如,NFS可以支持多个读/写客户端,但是特定的NFS PV可能以只读方式在服务器上导出。每个PV都有自己的一组访问模式,用于描述该特定PV的功能。

访问方式为:

1 ReadWriteOnce-该卷可以被单个节点以读写方式挂载
2 ReadOnlyMany-该卷可以被许多节点以只读方式挂载
3 ReadWriteMany-该卷可以被多个节点以读写方式挂载

在CLI命令行中,访问模式缩写为:

1 RWO-ReadWriteOnce
2 ROX-ReadOnlyMany
3 RWX-ReadWriteMany

说明:一个卷一次只能使用一种访问模式挂载,即使它支持多种访问模式。

storageClassName:PV可以有一个类,通过将storageClassName属性设置为一个StorageClass的名称来指定这个类。特定类的PV只能绑定到请求该类的PVC。没有storageClassName的PV没有类,只能绑定到不请求特定类的PVC。

persistentVolumeReclaimPolicy:当前的回收政策是:Retain (保留)-手动回收、Recycle (回收)-基本擦除(rm -rf /thevolume/*)、Delete (删除)-删除相关的存储资产 (例如AWS EBS,GCE PD,Azure Disk或OpenStack Cinder卷)。

备注:当前,仅NFS和HostPath支持回收。AWS EBS,GCE PD,Azure Disk和Cinder卷支持删除。

PV卷状态

卷将处于以下某种状态:

  • Available:尚未绑定到声明(claim)的空闲资源
  • Bound:卷已被声明绑定
  • Released:声明已被删除,但群集尚未回收该资源
  • Failed:该卷自动回收失败

CLI将显示绑定到PV的PVC的名称。

PV类型与支持的访问模式

PV-PVC示例

主机信息

存储使用NFS,在k8s-node03机器仅部署NFS服务,没有部署K8S

NFS服务部署

文章参考:「NFS 服务搭建与配置

所有机器操作

1 # 所需安装包
2 yum install nfs-utils rpcbind -y

NFS服务端k8s-node03机器操作

 1 [root@k8s-node03 ~]# mkdir -p /data/nfs1 /data/nfs2 /data/nfs3 /data/nfs4 /data/nfs5 /data/nfs6
 2 [root@k8s-node03 ~]# chown -R nfsnobody.nfsnobody /data/
 3 [root@k8s-node03 ~]#
 4 [root@k8s-node03 ~]# ll /data/
 5 total 0
 6 drwxr-xr-x 2 nfsnobody nfsnobody 6 Jun 14 16:30 nfs1
 7 drwxr-xr-x 2 nfsnobody nfsnobody 6 Jun 14 16:30 nfs2
 8 drwxr-xr-x 2 nfsnobody nfsnobody 6 Jun 14 16:30 nfs3
 9 drwxr-xr-x 2 nfsnobody nfsnobody 6 Jun 14 16:30 nfs4
10 drwxr-xr-x 2 nfsnobody nfsnobody 6 Jun 14 16:30 nfs5
11 drwxr-xr-x 2 nfsnobody nfsnobody 6 Aug 22 16:25 nfs6
12 [root@k8s-node03 ~]# vim /etc/exports
13 /data/nfs1  172.16.1.0/24(rw,sync,root_squash,all_squash)
14 /data/nfs2  172.16.1.0/24(rw,sync,root_squash,all_squash)
15 /data/nfs3  172.16.1.0/24(rw,sync,root_squash,all_squash)
16 /data/nfs4  172.16.1.0/24(rw,sync,root_squash,all_squash)
17 /data/nfs5  172.16.1.0/24(rw,sync,root_squash,all_squash)
18 /data/nfs6  172.16.1.0/24(rw,sync,root_squash,all_squash)
19 ### 启动NFS服务
20 [root@k8s-node03 ~]# systemctl start rpcbind.service
21 [root@k8s-node03 ~]# systemctl start nfs.service
22 ### 检查NFS服务 , 其中 172.16.1.113 为服务端IP
23 [root@k8s-node03 ~]# showmount -e 172.16.1.113
24 Export list for 172.16.1.113:
25 /data/nfs6 172.16.1.0/24
26 /data/nfs5 172.16.1.0/24
27 /data/nfs4 172.16.1.0/24
28 /data/nfs3 172.16.1.0/24
29 /data/nfs2 172.16.1.0/24
30 /data/nfs1 172.16.1.0/24
NFS客户端验证

在k8s-node02机器验证

1 # 查看rpcbind服务,默认是启动的,如果没有启动则启动并加入开机自启动
2 [root@k8s-node02 ~]# systemctl status rpcbind.service
3 # 查看NFS服务信息
4 [root@k8s-node02 ~]# showmount -e 172.16.1.113
5 ………………
6 # 挂载,并进行读写验证
7 [root@k8s-node02 ~]# mount -t nfs 172.16.1.113:/data/nfs1 /mnt
8 # 验证完毕,去掉NFS挂载
9 [root@k8s-node02 ~]# umount -lf 172.16.1.113:/data/nfs1

PV部署

yaml文件

 1 [root@k8s-master pv-pvc]# pwd
 2 /root/k8s_practice/pv-pvc
 3 [root@k8s-master pv-pvc]# cat pv.yaml
 4 apiVersion: v1
 5 kind: PersistentVolume
 6 metadata:
 7   name: pv-nfs1
 8 spec:
 9   capacity:
10     storage: 1Gi
11   accessModes:
12     - ReadWriteOnce
13   persistentVolumeReclaimPolicy: Recycle
14   storageClassName: nfs
15   nfs:
16     path: /data/nfs1
17     server: 172.16.1.113
18 ---
19 apiVersion: v1
20 kind: PersistentVolume
21 metadata:
22   name: pv-nfs2
23 spec:
24   capacity:
25     storage: 3Gi
26   accessModes:
27     - ReadWriteOnce
28   persistentVolumeReclaimPolicy: Recycle
29   storageClassName: nfs
30   nfs:
31     path: /data/nfs2
32     server: 172.16.1.113
33 ---
34 apiVersion: v1
35 kind: PersistentVolume
36 metadata:
37   name: pv-nfs3
38 spec:
39   capacity:
40     storage: 5Gi
41   accessModes:
42     - ReadWriteOnce
43   persistentVolumeReclaimPolicy: Recycle
44   storageClassName: slow
45   nfs:
46     path: /data/nfs3
47     server: 172.16.1.113
48 ---
49 apiVersion: v1
50 kind: PersistentVolume
51 metadata:
52   name: pv-nfs4
53 spec:
54   capacity:
55     storage: 10Gi
56   accessModes:
57     - ReadWriteOnce
58   persistentVolumeReclaimPolicy: Recycle
59   storageClassName: nfs
60   nfs:
61     path: /data/nfs4
62     server: 172.16.1.113
63 ---
64 apiVersion: v1
65 kind: PersistentVolume
66 metadata:
67   name: pv-nfs5
68 spec:
69   capacity:
70     storage: 5Gi
71   accessModes:
72     - ReadWriteMany
73   persistentVolumeReclaimPolicy: Recycle
74   storageClassName: nfs
75   nfs:
76     path: /data/nfs5
77     server: 172.16.1.113
78 ---
79 apiVersion: v1
80 kind: PersistentVolume
81 metadata:
82   name: pv-nfs6
83 spec:
84   capacity:
85     storage: 5Gi
86   accessModes:
87     - ReadWriteOnce
88   persistentVolumeReclaimPolicy: Recycle
89   storageClassName: nfs
90   nfs:
91     path: /data/nfs6
92     server: 172.16.1.113

启动PV,并查看状态

 1 [root@k8s-master pv-pvc]# kubectl apply -f pv.yaml
 2 persistentvolume/pv-nfs1 created
 3 persistentvolume/pv-nfs2 created
 4 persistentvolume/pv-nfs3 created
 5 persistentvolume/pv-nfs4 created
 6 persistentvolume/pv-nfs5 created
 7 persistentvolume/pv-nfs6 created
 8 [root@k8s-master pv-pvc]#
 9 [root@k8s-master pv-pvc]# kubectl get pv -o wide
10 NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
11 pv-nfs1   1Gi        RWO            Recycle          Available           nfs                     11s   Filesystem
12 pv-nfs2   3Gi        RWO            Recycle          Available           nfs                     11s   Filesystem
13 pv-nfs3   5Gi        RWO            Recycle          Available           slow                    11s   Filesystem
14 pv-nfs4   10Gi       RWO            Recycle          Available           nfs                     11s   Filesystem
15 pv-nfs5   5Gi        RWX            Recycle          Available           nfs                     11s   Filesystem
16 pv-nfs6   5Gi        RWO            Recycle          Available           nfs                     11s   Filesystem

StatefulSet创建并使用PVC

StatefulSet 需要 headless 服务 来负责 Pod 的网络标识,因此需要负责创建此服务。

yaml文件

 1 [root@k8s-master pv-pvc]# pwd
 2 /root/k8s_practice/pv-pvc
 3 [root@k8s-master pv-pvc]# cat sts-pod-pvc.yaml
 4 apiVersion: v1
 5 kind: Service
 6 metadata:
 7   name: nginx
 8   labels:
 9     app: nginx
10 spec:
11   ports:
12   - port: 80
13     name: web
14   clusterIP: None
15   selector:
16     app: nginx
17 ---
18 apiVersion: apps/v1
19 kind: StatefulSet
20 metadata:
21   name: web
22 spec:
23   selector:
24     matchLabels:
25       app: nginx # has to match .spec.template.metadata.labels
26   serviceName: "nginx"
27   replicas: 3 # by default is 1
28   template:
29     metadata:
30       labels:
31         app: nginx # has to match .spec.selector.matchLabels
32     spec:
33       terminationGracePeriodSeconds: 100
34       containers:
35       - name: nginx
36         image: registry.cn-beijing.aliyuncs.com/google_registry/nginx:1.17
37         ports:
38         - containerPort: 80
39           name: web
40         volumeMounts:
41         - name: www
42           mountPath: /usr/share/nginx/html
43   volumeClaimTemplates:
44   - metadata:
45       name: www
46     spec:
47       accessModes: [ "ReadWriteOnce" ]
48       storageClassName: "nfs"
49       resources:
50         requests:
51           storage: 3Gi

启动pod并查看状态

 1 [root@k8s-master pv-pvc]# kubectl apply -f sts-pod-pvc.yaml
 2 service/nginx created
 3 statefulset.apps/web created
 4 [root@k8s-master pv-pvc]#
 5 [root@k8s-master pv-pvc]# kubectl get svc -o wide
 6 NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
 7 kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   24d   <none>
 8 nginx        ClusterIP   None         <none>        80/TCP    17s   app=nginx
 9 [root@k8s-master pv-pvc]#
10 [root@k8s-master pv-pvc]# kubectl get sts -o wide
11 NAME   READY   AGE   CONTAINERS   IMAGES
12 web    3/3     82m   nginx        registry.cn-beijing.aliyuncs.com/google_registry/nginx:1.17
13 [root@k8s-master pv-pvc]#
14 [root@k8s-master pv-pvc]# kubectl get pod -o wide
15 NAME    READY   STATUS              RESTARTS   AGE   IP       NODE         NOMINATED NODE   READINESS GATES
16 web-0   0/1     ContainerCreating   0          3s    <none>   k8s-node01   <none>           <none>
17 [root@k8s-master pv-pvc]#
18 [root@k8s-master pv-pvc]# kubectl get pod -o wide
19 NAME    READY   STATUS              RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
20 web-0   1/1     Running             0          11s   10.244.4.135   k8s-node01   <none>           <none>
21 web-1   1/1     Running             0          6s    10.244.2.171   k8s-node02   <none>           <none>
22 web-2   0/1     ContainerCreating   0          3s    <none>         k8s-node01   <none>           <none>
23 [root@k8s-master pv-pvc]#
24 [root@k8s-master pv-pvc]# kubectl get pod -o wide
25 NAME    READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
26 web-0   1/1     Running   0          8m23s   10.244.2.174   k8s-node02   <none>           <none>
27 web-1   1/1     Running   0          8m20s   10.244.4.139   k8s-node01   <none>           <none>
28 web-2   1/1     Running   0          8m17s   10.244.2.175   k8s-node02   <none>           <none>

PV和PVC状态信息查看

 1 ### 注意挂载顺序
 2 [root@k8s-master pv-pvc]# kubectl get pv -o wide
 3 NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON   AGE    VOLUMEMODE
 4 pv-nfs1   1Gi        RWO            Recycle          Available                       nfs                     116s   Filesystem
 5 pv-nfs2   3Gi        RWO            Recycle          Bound       default/www-web-0   nfs                     116s   Filesystem
 6 pv-nfs3   5Gi        RWO            Recycle          Available                       slow                    116s   Filesystem
 7 pv-nfs4   10Gi       RWO            Recycle          Bound       default/www-web-2   nfs                     116s   Filesystem
 8 pv-nfs5   5Gi        RWX            Recycle          Available                       nfs                     116s   Filesystem
 9 pv-nfs6   5Gi        RWO            Recycle          Bound       default/www-web-1   nfs                     116s   Filesystem
10 [root@k8s-master pv-pvc]#
11 [root@k8s-master pv-pvc]# kubectl get pvc -o wide
12 NAME        STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
13 www-web-0   Bound    pv-nfs2   3Gi        RWO            nfs            87s   Filesystem
14 www-web-1   Bound    pv-nfs6   5Gi        RWO            nfs            84s   Filesystem
15 www-web-2   Bound    pv-nfs4   10Gi       RWO            nfs            82s   Filesystem

PVC与PV绑定时会根据storageClassName(存储类名称)和accessModes(访问模式)判断哪些PV符合绑定需求。然后再根据存储量大小判断,首先存PV储量必须大于或等于PVC声明量;其次就是PV存储量越接近PVC声明量,那么优先级就越高(PV量越小优先级越高)。

curl访问验证

在NFS服务端k8s-node03(172.16.1.113)对应NFS共享目录创建文件

1 echo "pv-nfs2===" > /data/nfs2/index.html
2 echo "pv-nfs4+++" > /data/nfs4/index.html
3 echo "pv-nfs6---" > /data/nfs6/index.html

curl访问pod

 1 [root@k8s-master pv-pvc]# kubectl get pod -o wide
 2 NAME    READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
 3 web-0   1/1     Running   0          8m23s   10.244.2.174   k8s-node02   <none>           <none>
 4 web-1   1/1     Running   0          8m20s   10.244.4.139   k8s-node01   <none>           <none>
 5 web-2   1/1     Running   0          8m17s   10.244.2.175   k8s-node02   <none>           <none>
 6 [root@k8s-master pv-pvc]#
 7 [root@k8s-master pv-pvc]# curl 10.244.2.174
 8 pv-nfs2===
 9 [root@k8s-master pv-pvc]#
10 [root@k8s-master pv-pvc]# curl 10.244.4.139
11 pv-nfs6---
12 [root@k8s-master pv-pvc]#
13 [root@k8s-master pv-pvc]# curl 10.244.2.175
14 pv-nfs4+++

即使删除其中一个pod,pod被拉起来后也能正常访问。

删除sts并回收PV

删除statefulset

1 [root@k8s-master pv-pvc]# kubectl delete -f sts-pod-pvc.yaml
2 service "nginx" deleted
3 statefulset.apps "web" deleted
4 [root@k8s-master pv-pvc]#
5 [root@k8s-master pv-pvc]# kubectl get pod -o wide
6 No resources found in default namespace.

查看PVC和PV,并删除PVC

 1 [root@k8s-master pv-pvc]# kubectl get pvc -o wide
 2 NAME        STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
 3 www-web-0   Bound    pv-nfs2   3Gi        RWO            nfs            24m   Filesystem
 4 www-web-1   Bound    pv-nfs6   5Gi        RWO            nfs            24m   Filesystem
 5 www-web-2   Bound    pv-nfs4   10Gi       RWO            nfs            24m   Filesystem
 6 [root@k8s-master pv-pvc]#
 7 [root@k8s-master pv-pvc]# kubectl get pv -o wide
 8 NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON   AGE   VOLUMEMODE
 9 pv-nfs1   1Gi        RWO            Recycle          Available                       nfs                     26m   Filesystem
10 pv-nfs2   3Gi        RWO            Recycle          Bound       default/www-web-0   nfs                     26m   Filesystem
11 pv-nfs3   5Gi        RWO            Recycle          Available                       slow                    26m   Filesystem
12 pv-nfs4   10Gi       RWO            Recycle          Bound       default/www-web-2   nfs                     26m   Filesystem
13 pv-nfs5   5Gi        RWX            Recycle          Available                       nfs                     26m   Filesystem
14 pv-nfs6   5Gi        RWO            Recycle          Bound       default/www-web-1   nfs                     26m   Filesystem
15 [root@k8s-master pv-pvc]#
16 [root@k8s-master pv-pvc]# kubectl delete pvc www-web-0 www-web-1 www-web-2
17 persistentvolumeclaim "www-web-0" deleted
18 persistentvolumeclaim "www-web-1" deleted
19 persistentvolumeclaim "www-web-2" deleted

回收PV

 1 ### 由下可见,还有一个pv虽然声明被删除,但资源尚未回收;我们只需等一会儿即可
 2 [root@k8s-master pv-pvc]# kubectl get pv -o wide
 3 NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON   AGE   VOLUMEMODE
 4 pv-nfs1   1Gi        RWO            Recycle          Available                       nfs                     90m   Filesystem
 5 pv-nfs2   3Gi        RWO            Recycle          Available                       nfs                     90m   Filesystem
 6 pv-nfs3   5Gi        RWO            Recycle          Available                       slow                    90m   Filesystem
 7 pv-nfs4   10Gi       RWO            Recycle          Available                       nfs                     90m   Filesystem
 8 pv-nfs5   5Gi        RWX            Recycle          Available                       nfs                     90m   Filesystem
 9 pv-nfs6   5Gi        RWO            Recycle          Released    default/www-web-1   nfs                     90m   Filesystem
10 [root@k8s-master pv-pvc]#
11 ### 可见该pv还有引用
12 [root@k8s-master pv-pvc]# kubectl get pv pv-nfs6 -o yaml
13 apiVersion: v1
14 kind: PersistentVolume
15 metadata:
16 ………………
17 spec:
18   accessModes:
19   - ReadWriteOnce
20   capacity:
21     storage: 5Gi
22   ################### 可见仍然在被使用
23   claimRef:
24     apiVersion: v1
25     kind: PersistentVolumeClaim
26     name: www-web-1
27     namespace: default
28     resourceVersion: "1179810"
29     uid: d4d8943c-6b16-45a5-8ffc-691fcefc4f88
30   ###################
31   nfs:
32     path: /data/nfs6
33     server: 172.16.1.113
34   persistentVolumeReclaimPolicy: Recycle
35   storageClassName: nfs
36   volumeMode: Filesystem
37 status:
38   phase: Released

在NFS服务端查看结果如下,可见/data/nfs6资源尚未回收,而/data/nfs2/、/data/nfs4/资源已经被回收。

 1 [root@k8s-node03 ~]# tree /data/
 2 /data/
 3 ├── nfs1
 4 ├── nfs2
 5 ├── nfs3
 6 ├── nfs4
 7 ├── nfs5
 8 └── nfs6
 9     └── index.html
10
11 5 directories, 2 files

针对这种情况有两种处理方式:

1、我们什么也不用做,等一会儿集群就能回收该资源

2、我们进行手动回收,操作如下

手动回收资源
 1 [root@k8s-master pv-pvc]# kubectl edit pv pv-nfs6
 2 ### 去掉claimRef: 部分
 3 ### 再次查看pv信息
 4 [root@k8s-master pv-pvc]# kubectl get pv -o wide
 5 NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE    VOLUMEMODE
 6 pv-nfs1   1Gi        RWO            Recycle          Available           nfs                     108m   Filesystem
 7 pv-nfs2   3Gi        RWO            Recycle          Available           nfs                     108m   Filesystem
 8 pv-nfs3   5Gi        RWO            Recycle          Available           slow                    108m   Filesystem
 9 pv-nfs4   10Gi       RWO            Recycle          Available           nfs                     108m   Filesystem
10 pv-nfs5   5Gi        RWX            Recycle          Available           nfs                     108m   Filesystem
11 pv-nfs6   5Gi        RWO            Recycle          Available           nfs                     108m   Filesystem

Kubernetes K8S之存储Volume详解-LMLPHP

之后到NFS服务端操作,清除该pv下的数据

[root@k8s-node03 ~]# rm -fr /data/nfs6/*

到此,手动回收资源操作成功!

StatefulSet网络标识与PVC

1、匹配StatefulSet的Pod name(网络标识)的模式为:$(statefulset名称)-$(序号),比如StatefulSet名称为web,副本数为3。则为:web-0、web-1、web-2

2、StatefulSet为每个Pod副本创建了一个DNS域名,这个域名的格式为:$(podname).(headless service name),也就意味着服务之间是通过Pod域名来通信而非Pod IP。当Pod所在Node发生故障时,Pod会被漂移到其他Node上,Pod IP会发生改变,但Pod域名不会变化

3、StatefulSet使用Headless服务来控制Pod的域名,这个Headless服务域名的为:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名

4、根据volumeClaimTemplates,为每个Pod创建一个PVC,PVC的命令规则为:$(volumeClaimTemplates name)-$(pod name),比如volumeClaimTemplates为www,pod name为web-0、web-1、web-2;那么创建出来的PVC为:www-web-0、www-web-1、www-web-2

5、删除Pod不会删除对应的PVC,手动删除PVC将自动释放PV。

相关阅读

1、NFS 服务搭建与配置

2、Kubernetes K8S 资源控制器StatefulSets详解

完毕!


———END———
如果觉得不错就关注下呗 (-^O^-) !

Kubernetes K8S之存储Volume详解-LMLPHP

10-23 12:57