超10万字整理完k8s的volume卷之持久性存储pv和pvc原理和创建绑定-超详细说明,代码和理论都超详细,建议跟着做一遍实验【2】
文章目录本地卷&网络卷【必看】持久性存储 【Persistent Volume】持久性存储说明持久性使用流程PV概述PVC概述volume 和 claim的生命周期供应静态配置动态配置绑定使用持久化声明保护PV示例与参数说明PV文件参数说明accessModes【访问模式】ReadWriteOnceReadOnlyManyReadWriteManypersistentVolumeRecla
文章目录
说明【必看】
- 总数将近11万,存储一共有4大类,本地卷、网络卷、持久性存储和动态卷供应 ,为了能够直观理解,所以我分成了3篇来发布;
初次看的时候,建议3篇都打开,按顺序学习和使实验,有助于理解哈。 后面查阅的时候看标题,点进相应的文章哈 - 这篇是第二篇
本地卷&网络卷【必看】【1】
- 这篇博客中还对volume做了说明,学习持久性存储之前,建议先去这篇文章中学习一下本地卷的概念和网络卷【特别是网络卷,因为持久性存储是网络卷的升级,指导网络卷以后,更容易理解持久性存储】
超10万字整理完k8s的volume卷之本地卷和网络卷详细说明,代码和理论都超详细,建议跟着做一遍实验【emptyDir、hostPath、nfs共享的网络卷】【1】
动态卷供应 【必看】【3】
看这篇博客【上面的本地卷和网络卷是基础知识,足够用了,如果想更深学习,就去这篇博客】【学习动态卷供应之前,建议先学持久性存储】:
超10万字整理完k8s的volume卷之动态卷供应-超详细说明,代码和理论都超详细,建议跟着做一遍实验【3】
持久性存储 【Persistent Volume】
持久性存储说明
-
这是官方文档网址,下面操作其实都可以在这文档里看到,只是可能不大容易看得懂:
http://docs.kubernetes.org.cn/429.html#persistentVolumeClaim
-
普通Volume和使用它的Pod之间是一种静态绑定关系,在定义Pod的文件里,同时定义了它使用的Volume。Volume 是Pod的附属品,我们无法单独创建一个Volume,因为它不是一个独立的K8S资源对象。
-
而Persistent Volume 简称PV是一个K8S资源对象,所以我们可以单独创建一个PV。它不和Pod直接发生关系,而是通过Persistent Volume Claim,简称PVC来实现动态绑定。Pod定义里指定的是PVC,然后PVC会根据Pod的要求去自动绑定合适的PV给Pod使用。
-
既然有了PV这个概念,那么PVC(PersistentVolumeClaim)这个概念也不得不说一下,PVC代表用户使用存储的请求,应用申请PV持久化空间的一个申请、声明。K8s集群可能会有多个PV,你需要不停的为不同的应用创建多个PV。
如图:
- 1)PV是集群中的存储资源,通常由集群管理员创建和管理;
- 2)StorageClass用于对PV进行分类,如果配置正确,Storage也可以根据PVC的请求动态创建PV;
- 3)PVC是使用该资源的请求,通常由应用程序提出请求,并指定对应的StorageClass和需求的空间大小;
- 4)PVC可以作为数据卷的一种,被挂载到Pod中使用;
持久性使用流程
-
PV与PVC的管理过程如下:
- 1)主机共享存储目录【任何共享形式均可,一般使用nfs】
- 2)在主机上划分出一个单独的目录用于PV使用,并且定义其可用大小;
- 3)创建PVC这个资源对象,便于申请PV的存储空间;
- 4)Pod中添加数据卷,数据卷关联到PVC;
- 5)Pod中包含容器,容器挂载数据卷;
-
既然提到了pv和pvc,那么我们就单独对这2样做下说明
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结合。
PV示例与参数说明
PV文件参数说明
下面就是pv的文件
apiVersion: v1 # 自定义版本名称
kind: PersistentVolume
metadata:
name: test-pv #自定义pv名称
spec:
capacity:
storage: 1Gi #指定该PV资源分配的容器为1G
accessModes: #指定访问模式
- ReadWriteOnce # 一共有3种模式
persistentVolumeReclaimPolicy: Recycle #指定回收策略(实验环境,实际环境很少会这样做,就是回收策略会用保留(Retain),而不是回收(Recycle)】
storageClassName: nfs #指定存储类名字
nfs: #需要与存储类名字一致
path: /nfsdata/test-pv #指定NFS的目录
server: 192.168.1.4 #指定NFS的IP地址
部分参数详细说明如下
accessModes【访问模式】
**accessModes
:**PersistentVolume可以通过资源提供者支持的任何方式安装在主机上。如下文表中所示,提供商将具有不同的功能,并且每个PV的访问模式都将设置为该特定卷支持的特定模式。例如,NFS可以支持多个读/写客户端,但是特定的NFS PV可能以只读方式在服务器上导出。每个PV都有自己的一组访问模式,用于描述该特定PV的功能。
ReadWriteOnce
-
ReadWriteOnce
-该卷可以被单个节点以读写方式挂载 -
在CLI命令行中,访问模式缩写为:
RWO-ReadWriteOnce
ReadOnlyMany
ReadOnlyMany
-该卷可以被许多节点以只读方式挂载- 在CLI命令行中,访问模式缩写为:
ROX-ReadOnlyMany
ReadWriteMany
ReadWriteMany
-该卷可以被多个节点以读写方式挂载- 在CLI命令行中,访问模式缩写为:
RWX-ReadWriteMany
persistentVolumeReclaimPolicy【回收策略】
当用户处理完他们的卷时,他们可以从允许回收资源的API中删除PVC对象。PersistentVolume的回收策略告诉集群在释放卷的声明后该如何处理它。目前,卷可以被保留、回收或删除。
Recycle (回收)
如果基础卷插件支持,Recycle回收策略将rm -rf /thevolume/*对该卷执行基本的擦除并使其可用于新的声明。
Retain (保留)
保留回收策略允许手动回收资源。当PersistentVolumeClaim被删除时,PersistentVolume仍然存在,并且该卷被认为是“释放”的。但是,由于之前声明的数据仍然存在,因此另一个声明尚无法得到。管理员可以手动回收卷。
Delete (删除)
对于支持Delete回收策略的卷插件,删除操作会同时从Kubernetes中删除PersistentVolume对象以及外部基础架构中的关联存储资产,例如AWS EBS,GCE PD,Azure Disk或Cinder卷。动态配置的卷将继承其StorageClass的回收策略,默认为Delete。管理员应根据用户的期望配置StorageClass。
storageClassName【指定类】
- 这个可以理解为一个秘钥匹配,这个值可以任意定义,用来和pvc绑定使用。
- 使用情况一般是,如果nfs共享了多个文件,那么在pv文件中的storageClassName定义一个秘钥,然后在pvc中也定义storageClassName和pv一致,这样pvc和pv就能指定绑定在一定了。
volumeMode 【文件挂载类型】
-
volumeMode 是一个可选的 API 参数,所以上面配置文件中并没有写该行内容, 如果该参数被省略,默认的卷模式是 Filesystem。
-
针对 PV 持久卷,Kubernetes 支持两种卷模式(volumeModes):
Filesystem
(文件系统) 和Block
(块)。 -
volumeMode 属性设置为 Filesystem 的卷会被 Pod 挂载(Mount) 到某个目录。 如果卷的存储来自某块设备而该设备目前为空,Kuberneretes 会在第一次挂载卷之前 在设备上创建文件系统。
-
这个是定义在spec下面的,如下【默认的一般mei有这行,只是知道这个以后,如果配置文件有这行,看得懂而已】
spec:
volumeMode: Filesystem
说明【必看】
-
一个卷一次只能使用一种访问模式挂载,即使它支持多种访问模式。
-
**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卷支持删除。
Persistent Volumes类型
- PersistentVolume类型作为插件实现。Kubernetes当前支持以下插件:
所谓插件,可以理解为卷目录存在形式【和网络卷一样】- NFS
- iSCSI
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- CSI
- FC (Fibre Channel)
- FlexVolume
- Flocker
- RBD (Ceph Block Device)
- CephFS
- Cinder (OpenStack block storage)
- Glusterfs
- VsphereVolume
- Quobyte Volumes
- HostPath (仅用于单节点测试——本地存储不受任何方式的支持,也不能在多节点集群中工作)
- Portworx Volumes
- ScaleIO Volumes
- StorageOS
PV卷状态说明
- 卷有一下4种状态【
kubectl get pv
】: - CLI将显示绑定到PV的PVC的名称。
Available
Available
:尚未绑定到声明(claim)的空闲资源
Bound
Bound
:卷已被声明绑定
Released
Released
:声明已被删除,但群集尚未回收该资源
Failed
Failed
:该卷自动回收失败
PV类型与支持的访问模式对应关系
Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
CSI | depends on the driver | depends on the driver | depends on the driver |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | depends on the driver |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | - (works when Pods are collocated) |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
PV-PVC示例【搭建过程】
主机信息
- 下面4台主机呢,其中3台是一个集群,一台已经安装好nfs的服务
如果没有下面环境的,先搭建这么一套出来【k8s集群搭建和nfs服务端配置我博客中都有,如果不会的可以去翻翻博客先学习一下】
服务器名称(hostname) | 系统版本 | IP | 部署模块 |
---|---|---|---|
master | CentOS Linux release 7.6.1810 (Core) | 192.168.59.142 | k8s集群-master节点 |
node1 | CentOS Linux release 7.6.1810 (Core) | 192.168.59.143 | k8s集群-node节点 |
node2 | CentOS Linux release 7.6.1810 (Core) | 192.168.59.144 | k8s集群-node节点 |
etcd1 | CentOS Linux release 7.4.1708 (Core) | 192.168.59.156 | 仅部署nfs【未加入集群】 |
nfs文件共享配置
- 【nfs这个,建议先去我k8s分类中,找到
volume卷的网络卷配置
里面有详细说明nfs主机服务搭建和node节点服务安装】
文件创建并共享【nfs节点操作】
我们随便创建几个文件然后共享出去
[root@etcd1 ~]# mkdir -p /data/nfs1 /data/nfs2 /data/nfs3 /data/nfs4 /data/nfs5
[root@etcd1 ~]# chown -R nfsnobody.nfsnobody /data/
[root@etcd1 ~]# ll /data
总用量 0
drwxr-xr-x 2 nfsnobody nfsnobody 6 8月 20 10:23 nfs1
drwxr-xr-x 2 nfsnobody nfsnobody 6 8月 20 10:23 nfs2
drwxr-xr-x 2 nfsnobody nfsnobody 6 8月 20 10:23 nfs3
drwxr-xr-x 2 nfsnobody nfsnobody 6 8月 20 10:23 nfs4
drwxr-xr-x 2 nfsnobody nfsnobody 6 8月 20 10:23 nfs5
[root@etcd1 ~]#
[root@etcd1 ~]# cat /etc/exports
/data/nfs1 *(rw,async,no_root_squash)
/data/nfs2 *(rw,async,no_root_squash)
/data/nfs3 *(rw,async,no_root_squash)
/data/nfs4 *(rw,async,no_root_squash)
/data/nfs5 *(rw,async,no_root_squash)
[root@etcd1 ~]#
[root@etcd1 ~]# systemctl restart nfs-server.service
[root@etcd1 ~]#
[root@etcd1 ~]# showmount -e 192.168.59.156
Export list for 192.168.59.156:
/data/nfs5 *
/data/nfs4 *
/data/nfs3 *
/data/nfs2 *
/data/nfs1 *
[root@etcd1 ~]#
验证【node节点操作】
任意node节点均可以操作,可以不用验证的,验证一下只是为了更能理解nfs挂载罢了。
[root@node1 ~]# showmount -e 192.168.59.156
Export list for 192.168.59.156:
/data/nfs5 *
/data/nfs4 *
/data/nfs3 *
/data/nfs2 *
/data/nfs1 *
[root@node1 ~]# mkdir /test
[root@node1 ~]# mount -t nfs 192.168.59.156:/data/nfs1 /test
[root@node1 ~]# df -h | grep test
192.168.59.156:/data/nfs1 150G 6.8G 144G 5% /test
[root@node1 ~]#
[root@node1 ~]# umount -lf 192.168.59.156:/data/nfs1
[root@node1 ~]#
[root@node1 ~]#
PV部署
pv创建好以后,再创建pcv,这个和linux中的pv类似。
编辑文件并创建
- pv部署是以yaml文件形式创建,创建方式和pod一样。
命令:kubectl apply -f pv.yaml
- 如果需要创建多个pv,中间需要以
---
隔开【每个pv配置文件一致】
平常呢,建议一个配置文件就写一个信息,不要写多个,我这只是为了展示可以实现这样的场景 - 如下,我创建了2个pv【如果配置文件看不懂,上面有pv文件参数说明,qu看看】
注:因为我们使用的是nfs,所以下面storage参数控制大小是无效的【这个大小需要到nfs主机上设置】,如果使用的块存储的话,定义了3G那么容量就3G
[root@master volume]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /data/nfs1
server: 192.168.59.156
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs2
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /data/nfs2
server: 192.168.59.156
[root@master volume]#
[root@master volume]# kubectl apply -f pv.yaml
persistentvolume/pv-nfs1 created
persistentvolume/pv-nfs2 created
查看pv
命令:kubectl get pv
需要注意的是,这个pv是全局生效的,无论在哪个命名空间都是可以看到该pv信息的
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Available nfs 4m30s
pv-nfs2 3Gi RWO Recycle Available nfs 4m30s
[root@master volume]#
[root@master volume]# kubectl get pv -n default
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Available nfs 4m36s
pv-nfs2 3Gi RWO Recycle Available nfs 4m36s
[root@master volume]# kubectl get pv -n ccx
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Available nfs 4m40s
pv-nfs2 3Gi RWO Recycle Available nfs 4m40s
[root@master volume]#
查看已创建pv详细信息
命令:kubectl describe pv pvname
[root@master volume]# kubectl describe pv pv-nfs
Name: pv-nfs1
Labels: <none>
Annotations: pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs
Status: Bound
Claim: volume/ccx-pvc
Reclaim Policy: Recycle
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 3Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.59.156
Path: /data/nfs1
ReadOnly: false
Events: <none>
Name: pv-nfs2
Labels: <none>
Annotations: pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs
Status: Bound
Claim: volume/hero-pvc
Reclaim Policy: Recycle
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 3Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.59.156
Path: /data/nfs2
ReadOnly: false
Events: <none>
[root@master volume]#
删除pv
命令:kubectl delete pv pv_name
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Failed volume/ccx-pvc nfs 35m
pv-nfs2 3Gi RWO Recycle Failed volume/hero-pvc nfs 35m
[root@master volume]# kubectl delete pv pv-nfs1
persistentvolume "pv-nfs1" deleted
[root@master volume]#
[root@master volume]# kubectl delete pv pv-nfs2
persistentvolume "pv-nfs2" deleted
[root@master volume]#
[root@master volume]# kubectl get pv
No resources found
[root@master volume]#
创建PVC资源对象
-
pvc和pv进行关联主要由2个参数决定
- 1、capcity
pvc里的要求容量 <= pv—capcity - 2、accessmode
必须要和pv里相同
- 1、capcity
-
文件说明如下,如果有需要定义多个,用
---
隔开
[root@master ~]# vim test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc #自定义名称
spec:
accessModes:
- ReadWriteOnce #定义访问模式,必须与PV定义的访问模式一致
resources:
requests:
storage: 1Gi #定义容量【不能高于pv容量】
storageClassName: nfs #定义的名称需与PV定义的名称一致
常规创建
- 命令:
kubectl apply -f pvc.yaml
- 需要注意的是,如果使用
---
隔开了,那么pv中必须也是这样格式,因为是一一对应的,如下,我创建了2个,可以看到后面使用的卷是nfs1和nfs2【我定义在pv中了】
平常呢,建议一个配置文件就写一个信息,不要写多个,我这只是为了展示可以实现这样的场景
[root@master volume]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hero-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: nfs
[root@master volume]# kubectl apply -f pvc.yaml
persistentvolumeclaim/ccx-pvc created
persistentvolumeclaim/hero-pvc created
[root@master volume]#
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs 15s
hero-pvc Bound pv-nfs2 3Gi RWO nfs 15s
[root@master volume]#
注意:“PV与PVC的状态都是Bound,表示PV与PVC的关联成功
指定命名空间创建
- 指定命名空间创建和普通创建一样,就是在后面加了指定命名空间的参数罢了。
命令:kubectl apply -f pvc.yaml -n ccx
【kubectl get ns查看当前命名空间】 - 注:指定命名空间创建呢,后面查看也需要指定命名空间,否则是无法查看到创建的内容的。
并且,一个pv只能被一个pvc使用,如下,我下面指定的这个pv已经在上面通过默认方式创建了,没有删除他,现在指定命名空间创建,就会报错【正常情况这么创建是和常规创建效果是一样的,我就不去删除新建了】。
[root@master volume]# kubectl get ns
NAME STATUS AGE
ccx Active 44d
ccxhero Active 44d
default Active 49d
kube-node-lease Active 49d
kube-public Active 49d
kube-system Active 49d
ns1 Active 44d
pod-1 Active 35d
volume Active 3d18h
[root@master volume]#
[root@master volume]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hero-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: nfs
[root@master volume]#
[root@master volume]# kubectl apply -f pvc.yaml -n ccx
persistentvolumeclaim/ccx-pvc created
persistentvolumeclaim/hero-pvc created
[root@master volume]#
[root@master volume]# kubectl get pvc -n ccx
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Pending nfs 10s
hero-pvc Pending nfs 10s
[root@master volume]#
查看pvc【含指定ns查看】
- 前面说过pv是全局的,但pvc不是,在哪个命名空间创建的,就只能在哪个命名空间中查看到。
- 常规查看【当前默认ns】:
kubectl get pvc
- 指定ns查看【kubectl get ns查看所有命名空间】:
kubectl get pvc -n nsname
- 常规查看【当前默认ns】:
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs 15s
hero-pvc Bound pv-nfs2 3Gi RWO nfs 15s
[root@master volume]#
[root@master volume]# kubectl get pvc -n ccx
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Pending nfs 8m4s
hero-pvc Pending nfs 8m4s
[root@master volume]#
[root@master volume]#
删除pvc
- 常规删除【删除当前所处ns空间的pvc】:
- 方式1:命令:
kubectl delete -f pvc.yaml_name
[root@master volume]#
[root@master volume]# kubectl delete -f pvc.yaml
persistentvolumeclaim "ccx-pvc" deleted
persistentvolumeclaim "hero-pvc" deleted
[root@master volume]#
[root@master volume]# kubectl get pvc
No resources found in volume namespace.
[root@master volume]#
- 方式2:命令:
kubectl delete pvc pvc_name
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs1 7m9s
ccx-pvc2 Bound pv-nfs2 3Gi RWO nfs2 6m4s
[root@master volume]#
[root@master volume]# kubectl get pv^C
[root@master volume]# kubectl delete pvc ccx-pvc
persistentvolumeclaim "ccx-pvc" deleted
[root@master volume]# kubectl delete pvc ccx-pvc2
persistentvolumeclaim "ccx-pvc2" deleted
[root@master volume]#
- 指定命名空间删除:
命令:kubectl delete -f pvc.yaml_name -n ns_name
[root@master volume]# kubectl delete -f pvc.yaml -n ccx
persistentvolumeclaim "ccx-pvc" deleted
persistentvolumeclaim "hero-pvc" deleted
[root@master volume]#
[root@master volume]# kubectl get pvc -n ccx
No resources found in ccx namespace.
[root@master volume]#
pv回收策略测试【了解逻辑为主】
注:下面设计到的回收策略和状态都在上面:PV示例与参数说明 中有详细介绍的。
Recycle
- 我们先创建pc和pvc,并且要pv和pvc的状态都为Bound才行
[root@master volume]# cat pvtest.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfs
server: 192.168.59.156
[root@master volume]# cat pvctest.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master volume]#
[root@master volume]# kubectl apply -f pvtest.yaml
persistentvolume/pv-nfs1 created
[root@master volume]# kubectl apply -f pvctest.yaml
persistentvolumeclaim/ccx-pvc created
[root@master volume]#
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Bound volume/ccx-pvc nfs 8s
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs 5s
[root@master volume]#
[root@master volume]#
- 可以看到,pv-nfs1的挂载目录是/nfs,所以我们去nfs主机的这个目录上随便创建几个文件,然后回到master节点上,删除pvc
[root@etcd1 ~]# cd /nfs
[root@etcd1 nfs]# touch {aa,bb,cc,dd}.txt
[root@etcd1 nfs]# ls
aa.txt bb.txt cc.txt dd.txt
[root@etcd1 nfs]# ls
aa.txt bb.txt cc.txt dd.txt
[root@etcd1 nfs]#
- 然后我们回到master节点,删除pvc,这时候pv的状态就会为
Available
,同时再回到nfs节点中,/nfs中我们创建的文件就没了。
【当然,凡事有意外,比如我这删了pvc以后,pv状态成Failed了,这个时候nfs中文件是不会被删除的,但这是意外情况,正常情况为available才对】
[root@master volume]# kubectl delete -f pvctest.yaml
persistentvolumeclaim "ccx-pvc" deleted
[root@master volume]#
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Failed volume/ccx-pvc nfs 47s
[root@master volume]#
事件查看【pv详细、报错内容查看】
- 因为我上面测试出现意外了,所以我们可以执行这个命令查看:
kubectl describe pv pv_name
可以看到,提示镜像pull失败了,因为我这集群是没有外网的,因为没联网,所以没法下载回收镜像busybox:1.27,所以导致pv回收失败,这个玩意没法指定镜像获取方式,所以没得玩,你如果在有外网的机子上测试,是不会出现这种意外报错的。
[root@master volume]# kubectl describe pv pv-nfs1
Name: pv-nfs1
Labels: <none>
Annotations: pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs
Status: Failed
Claim: volume/ccx-pvc
Reclaim Policy: Recycle
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 3Gi
Node Affinity: <none>
Message: Recycle failed: old recycler pod found, will retry later
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.59.156
Path: /nfs
ReadOnly: false
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning VolumeFailedRecycle 4m24s persistentvolume-controller Recycle failed: old recycler pod found, will retry later
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:49162->[::1]:53: read: connection refused
Normal RecyclerPod 4m20s (x3 over 4m20s) persistentvolume-controller Recycler pod: Pulling image "busybox:1.27"
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:58916->[::1]:53: read: connection refused
Warning RecyclerPod 4m20s (x3 over 4m20s) persistentvolume-controller Recycler pod: Error: ErrImagePull
Normal RecyclerPod 4m20s (x2 over 4m20s) persistentvolume-controller Recycler pod: Back-off pulling image "busybox:1.27"
Warning RecyclerPod 4m20s (x2 over 4m20s) persistentvolume-controller Recycler pod: Error: ImagePullBackOff
Normal RecyclerPod 4m20s (x4 over 4m20s) persistentvolume-controller Recycler pod: Successfully assigned default/recycler-for-pv-nfs1 to node1
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:52686->[::1]:53: read: connection refused
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:39752->[::1]:53: read: connection refused
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:39082->[::1]:53: read: connection refused
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:58654->[::1]:53: read: connection refused
Warning RecyclerPod 4m20s persistentvolume-controller Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:60514->[::1]:53: read: connection refused
Warning RecyclerPod 4m20s (x3 over 4m20s) persistentvolume-controller (combined from similar events): Recycler pod: Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:39184->[::1]:53: read: connection refused
[root@master volume]#
因为没外网测试第一个就有问题了,所以剩下2个我都不想测试了,反正就是这么个逻辑,感兴趣的自己测吧。
绑定pv创建pod
代码解释
- 创建pod前需要先创建好pv和pvc,方法见上面哦。
如下,我已经创建好如下pvc了
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Bound volume/ccx-pvc nfs 12m
[root@master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs 12m
[root@master ~]#
- 下面是一些创建pod的基本参数规则,已经在代码后面注明作用了
这个和创建pod差不太多,只是卷定义稍有不同,pod更多参数可以参考pod创建自定义测试哦。
[root@master volume]# cat pvpod.yaml
apiVersion: v1 #自定义版本号
kind: Pod
metadata:
name: pvpod #自定义pod名称
spec:
containers:
- name: pv-pod #自定义名称
image: nginx #镜像名称
imagePullPolicy: IfNotPresent #定义镜像获取规则,默认pull
args: # 下面是自定义command的一种方式,只有一个容器不定义也可
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- mountPath: /testdata #定义容器中的目录
name: volumedata #保证与卷的名称一致【卷名称在下面】
volumes:
- name: volumedata #定义卷的名称
persistentVolumeClaim:
claimName: ccx-pvc #指定逻辑卷对应的PVC名称【kubectl get pvc查看】
编辑文件并创建pod
[root@master volume]# cat pvpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pvpod
spec:
containers:
- name: pv-pod
image: nginx
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- mountPath: /testdata
name: volumedata
volumes:
- name: volumedata
persistentVolumeClaim:
claimName: ccx-pvc
[root@master volume]# kubectl apply -f pvpod.yaml
pod/pvpod created
[root@master volume]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pvpod 1/1 Running 0 6s
pod数据测试
- 数据测试前,我们需要获取到卷存储的路径和容器内的存储路径
- 我们上面pod绑定的pvc中的pv卷来源是nfs主机中共享的,
/nfs1
目录【可以通过配置文件看出来】 - 然后容器内指定的目录是:
/testdata
【通过配置文件可以看出来
- 我们上面pod绑定的pvc中的pv卷来源是nfs主机中共享的,
[root@master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs 12m
[root@master volume]# cat pvtest.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfs1
server: 192.168.59.156
[root@master volume]#
[root@master volume]#
[root@master volume]# cat pvpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pvpod
spec:
containers:
- name: pv-pod
image: nginx
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- mountPath: /testdata
name: volumedata
volumes:
- name: volumedata
persistentVolumeClaim:
claimName: ccx-pvc
[root@master volume]#
- 这2个路径都知道以后呢
- 我们先去nfs主机的/nfs1中随便创建几个目录,然后进入到容器内看是否能看到
- 然后进入到容器的目录总创建几个文件,再回到nfs主机看是否能看到
#nfs主机
[root@etcd1 ~]# touch /nfs1/fdaf /nfs1/111 /nfs1/2222
[root@etcd1 ~]# ls /nfs1/
111 2222 fdaf
# master节点
[root@master volume]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pvpod 1/1 Running 0 6s
[root@master volume]# kubectl exec -it pvpod -- bash
root@pvpod:/# ls /testdata/
111 2222 fdaf
root@pvpod:/#
root@pvpod:/# touch /testdata/pvpod{test1,test2,test3}.20210820
root@pvpod:/# ls /testdata/
111 2222 fdaf pvpodtest1.20210820 pvpodtest2.20210820 pvpodtest3.20210820
root@pvpod:/#
# nfs主机
[root@etcd1 ~]# ls /nfs1/
111 2222 fdaf pvpodtest1.20210820 pvpodtest2.20210820 pvpodtest3.20210820
[root@etcd1 ~]#
综上,全部测试都很正常,持久性存储没毛病。
删除pod测试
-
这个呢,就要就是为了证明,删除pod是对数据没有任何影响的,影响数据的因素是,pvc和pv的删除操作【回收策略决定】,具体规则上面都有说明的哈。
-
如下,我删除pod,去nfs节点,数据依然存在。
[root@master volume]# kubectl delete pod pvpod
pod "pvpod" deleted
[root@master volume]#
#nfs节点
[root@etcd1 ~]# ls /nfs1/
111 2222 fdaf pvpodtest1.20210820 pvpodtest2.20210820 pvpodtest3.20210820
[root@etcd1 ~]#
- 在通过这个pod文件创建pods,进入容器,数据肯定都在【此期间没有对pvc做过任何变动】
[root@master volume]# kubectl apply -f pvpod.yaml
pod/pvpod created
[root@master volume]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pvpod 1/1 Running 0 4s
[root@master volume]# kubectl exec -it pvpod -- bash
root@pvpod:/# ls /testdata/
111 2222 fdaf pvpodtest1.20210820 pvpodtest2.20210820 pvpodtest3.20210820
root@pvpod:/# exit
exit
[root@master volume]#
关于持久性存储的几个思考和解决思路
这些也仅仅是我针对上面测试中产生的想法罢了,肯定有考虑不周全的地方,也不一定全部正确,如果有误或有更好的建议,还请i留下评论指正为谢。
pv和pvc的对应关系
- 上面测试中我们可以看到,pvc并没有指定pv的参数,如果一台nfs主机共享了很多个目录,且这些目录都需要挂载到不同的pod上,如果你做上面实验了,应该知道有2种方式
- 方式1:使用多个文件创建多个pv,然后绑定pvc
- 方式2:一个文件中使用
---
隔开,对应创建pvc
上面2种方式有对应的问题,我下面分别说明
方式1【多个文件创建pv】
一个pv和一个pvc创建
- 创建pv文件如下【代码如果有看不懂的,回到上面去查看详解】
[root@master volume]# cat pvtest.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfs1
server: 192.168.59.156
[root@master volume]#
[root@master volume]# cat pvctest.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master volume]#
# 创建流程和成功截图
[root@master volume]#kubectl apply -f pvtest.yaml
[root@master volume]#kubectl apply -f pvctest.yaml
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Bound volume/ccx-pvc nfs 51m
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs 51m
[root@master volume]#
问题思考【pvc如何指定pv】
- 根据上面代码:
我们一个pv文件只绑定一个nfs路径,且文件中文件指定存储类型为nfs,我们创建pv的时候,是通过文件创建出pv的,创建pvc的时候,并不能指定pv名称,只能通过这个pv中的类型【nfs这种】来创建pvc,这种情况创建一个pv和pvc肯定没有问题 - 那么如果我通过这个配置文件创建了2个pv呢【存储路径变了,其他不变】,这个时候创建pvc,这个pvc又会指定到哪里呢?
- 直接创建测试看结果
前面说过pvc是不能指定pv名称的,所以pv文件有2个,pvc文件就一个
[root@master volume]# cat pvtest2.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs2
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfs
server: 192.168.59.156
[root@master volume]# cat pvtest.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfs1
server: 192.168.59.156
[root@master volume]#
[root@master volume]# cat pvctest.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master volume]#
现在我们来创建pv和pvc【先删除之前创建的】
可以看到,pv确实有2个,但创建pvc的时候,自动给我绑定到nfs2了
[root@master volume]# kubectl delete -f pvctest.yaml
persistentvolumeclaim "ccx-pvc" deleted
[root@master volume]# kubectl delete pv pv-nfs1
persistentvolume "pv-nfs1" deleted
[root@master volume]#
[root@master volume]# kubectl apply -f pvtest.yaml
persistentvolume/pv-nfs1 created
[root@master volume]# kubectl apply -f pvtest2.yaml
persistentvolume/pv-nfs2 created
[root@master volume]#
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Available nfs 9s
pv-nfs2 3Gi RWO Recycle Available nfs 6s
[root@master volume]# kubectl apply -f pvctest.yaml
persistentvolumeclaim/ccx-pvc created
[root@master volume]#
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs2 3Gi RWO nfs 5s
[root@master volume]#
[root@master volume]#
如果我再次创建,那么就会报错,也就是说,常规情况,创建了2个pv,我们是没有办法控制pvc绑定在哪个pv上的。
【kubectl get pv,status中bound是已经使用的,available是没有使用的】
[root@master volume]# kubectl apply -f pvctest.yaml
persistentvolumeclaim/ccx-pvc unchanged
[root@master volume]#
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs2 3Gi RWO nfs 31s
[root@master volume]#
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Available nfs 2m28s
pv-nfs2 3Gi RWO Recycle Bound volume/ccx-pvc nfs 2m25s
[root@master volume]#
解决问题【pvc无法指定pv】
- 其实这个问题很好解决,配置文件中有一个参数是:
storageClassName:
这个后面我们一般使用的是存储类型【nfs这种参数】,其实这个还有一个功能,类似于秘钥匹配机制,这个参数是可以用来pvc和pv绑定,首先要明白这个参数是可以自定义的,使用啥都可以- 所以我们可以在2个pv文件中定义这个参数分别为:nfs1和nfs2
- 同理,在2个pvc文件中定义这个参数分别为:nfs1和nfs2
- 这样的话这2个pvc和pv就分别绑定起来了,pv和pvc的文件如下
[root@master volume]# cat pvtest.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs1
nfs:
path: /nfs1
server: 192.168.59.156
[root@master volume]# cat pvtest2.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs2
spec:
capacity:
storage: 3Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs2
nfs:
path: /nfs
server: 192.168.59.156
[root@master volume]#
[root@master volume]# cat pvctest.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: nfs1
[root@master volume]# cat pvctest2.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc2
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: nfs2
[root@master volume]#
现在我们通过这4个文件分别创建pvc看效果
[root@master volume]# kubectl apply -f pvtest.yaml
persistentvolume/pv-nfs1 created
[root@master volume]# kubectl apply -f pvtest2.yaml
persistentvolume/pv-nfs2 created
[root@master volume]#
[root@master volume]# kubectl apply -f pvctest.yaml
persistentvolumeclaim/ccx-pvc created
[root@master volume]# kubectl apply -f pvctest2.yaml
persistentvolumeclaim/ccx-pvc2 created
[root@master volume]#
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs1 3Gi RWO nfs1 68s
ccx-pvc2 Bound pv-nfs2 3Gi RWO nfs2 3s
[root@master volume]#
- 完美解决,上面可以看到我们有了ccx-pvc和ccx-pvc2这2个pvc了,这样就可以正常使用pvc名称来创建pod了哦
方式2【一个文件创建多个pv和pvc】
文件代码
- 关于这个,我上面测试其实就已经说过了,而且代码也是之前的代码,反正原理就是,一个文件创建多个pv和pvc【pv数量和pvc要对应起来】
- 原理呢其实就是方式1中的解决问题一样,只是这次代码不用分开文件存放而已。
这个相比较于方式1呢,其实还不用考虑storageClassName,一样也无所谓,更nice。
[root@master volume]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs1
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /data/nfs1
server: 192.168.59.156
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs2
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /data/nfs2
server: 192.168.59.156
[root@master volume]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ccx-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hero-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: nfs
[root@master volume]#
创建pv和pvc
- 这样创建的话呢,就可以一次性创建出很多个pv和pvc了,很方便
#y因为代码中名称一样,所以我需要先删除之前创建的
[root@master volume]# kubectl delete pvc ccx-pvc
persistentvolumeclaim "ccx-pvc" deleted
[root@master volume]# kubectl delete pvc ccx-pvc2
persistentvolumeclaim "ccx-pvc2" deleted
[root@master volume]# kubectl delete pv pv-nfs1
persistentvolume "pv-nfs1" deleted
[root@master volume]# kubectl delete pv pv-nfs2
persistentvolume "pv-nfs2" deleted
[root@master volume]#
# 开始创建
[root@master volume]# kubectl apply -f pv.yaml
persistentvolume/pv-nfs1 created
persistentvolume/pv-nfs2 created
[root@master volume]# kubectl apply -f pvc.yaml
persistentvolumeclaim/ccx-pvc created
persistentvolumeclaim/hero-pvc created
[root@master volume]#
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ccx-pvc Bound pv-nfs2 3Gi RWO nfs 8s
hero-pvc Bound pv-nfs1 3Gi RWO nfs 8s
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs1 3Gi RWO Recycle Bound volume/hero-pvc nfs 18s
pv-nfs2 3Gi RWO Recycle Bound volume/ccx-pvc nfs 18s
[root@master volume]#
- 上面可以看到我们有了ccx-pvc和hero-pvc这2个pvc了,这样就可以正常使用pvc名称来创建pod了哦
当pod状态不正常时,一般我们可以采用以下三种方式进行排错:
1)使用“kubectl describe pod pod名称
查看pod的详细信息;
2)使用kubectl logs pod名称
查看pod的日志信息;
3)使用cat /var/log/messages | grep kubelet
查看对应节点kubelet系统日志;
【demo】mysql对数据持久化的应用
下面通过创建mysql容器的方式来验证Persistent volume的作用!
1)搭建NFS共享存储
本次案例直接在master节点上创建NFS存储!
[root@master ~]# yum -y install nfs-utils rpcbind
[root@master ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl start rpcbind
[root@master ~]# showmount -e
Export list for master:
/nfsdata *
2)创建PV资源对象
[root@master ~]# vim mysql-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain #注意指定的回收策略为手动回收
storageClassName: nfs
nfs:
path: /nfsdata/mysql-pv
server: 192.168.1.4
[root@master ~]# kubectl apply -f mysql-pv.yaml
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
test-pv 1Gi RWO Retain Available nfs 15s
[root@master ~]# mkdir -p /nfsdata/mysql-pv
3)创建PVC资源对象
[root@master ~]# vim mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master ~]# kubectl apply -f mysql-pvc.yaml
[root@master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc Bound mysql-pv 1Gi RWO nfs 13s
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mysql-pv 1Gi RWO Retain Bound default/mysql-pvc nfs 8m14s
4)创建pod资源
[root@master ~]# vim mysql-pod.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql-pod
spec:
selector: #设置给予等值的标签选择器
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env: #设置环境变量,数据库root用户的密码
- name: MYSQL_ROOT_PASSWORD
value: 123.com
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql #这个目录是数据库存放数据的目录(指定的是容器中的目录)
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
[root@master ~]# kubectl apply -f mysql-pod.yaml
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-pod-6cc889468b-gq4qz 1/1 Running 0 3s
5)测试数据持久化效果
[root@master ~]# kubectl exec -it mysql-pod-6cc889468b-gq4qz -- mysql -u root -p123.com
#直接登录运行mysql数据库的pod中的mysql
#插入数据进行测试
mysql> create database lzj;
mysql> use lzj;
mysql> create table my_id( id int(4) );
mysql> insert my_id values (9527);
mysql> select * from my_id;
+------+
| id |
+------+
| 9527 |
+------+
[root@master ~]# ls /nfsdata/mysql-pv/
auto.cnf ibdata1 ib_logfile0 ib_logfile1 lzj mysql performance_schema
#查看pod对应的NFS的目录,确实有了数据
[root@master ~]# kubectl get pod -o wide #查看pod的详细信息
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-pod-6cc889468b-gq4qz 1/1 Running 0 23m 10.244.2.6 node02 <none> <none>
#查看到pod是运行在node02节点上的
#模拟node02宕机,步骤省略,关机、挂起都可以!
[root@node01 ~]# systemctl restart kubelet
#重启node01的kubelet服务
#接下来耐心等待pod的转移,可能需要差不多5分钟
^C[root@master ~]# kubectl get pod -o wide #可以看到pod已经运行在node01上
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-pod-6cc889468b-gdf7k 1/1 Running 0 66s 10.244.1.6 node01 <none> <none>
mysql-pod-6cc889468b-gq4qz 1/1 Terminating 0 32m 10.244.2.6 node02 <none> <none>
[root@master ~]# kubectl exec -it mysql-pod-6cc889468b-gdf7k -- mysql -u root -p123.com
#再次登录到pod中运行的mysql(注意:pod的名称)
mysql> select * from lzj.my_id; #再次数据是否存在
+------+
| id |
+------+
| 9527 |
+------+
1 row in set (0.01 sec)
#数据依旧存在
更多推荐
所有评论(0)