持久化存储pv&pvc
官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
存储资源管理
在基于k8s容器云平台上,对存储资源的使用需求通常包括以下几方面:
1.应用配置文件、密钥的管理;
2.应用的数据持久化存储;
3.在不同的应用间共享数据存储;
k8s的Volume抽象概念就是针对这些问题提供的解决方案,k8s的volume类型非常丰富,从临时目录、宿主机目录、ConfigMap、Secret、共享存储(PV和PVC)。
k8s支持Volume类型包括以下几类:
1.临时空目录(随着Pod的销毁而销毁)
emptyDir:
2.配置类(将配置文件以Volume的形式挂载到容器内)
ConfigMap:将保存在ConfigMap资源对象中的配置文件信息挂载到容器内的某个目录下
Secret:将保存在Secret资源对象中的密码密钥等信息挂载到容器内的某个文件中。
downwardAPI:将downwardAPI的数据以环境变量或文件的形式注入容器中。
3.本地存储类
hostpath:将宿主机的目录或文件挂载到容器内进行使用。
4.共享存储
PV(Persistent Volume):将共享存储定义为一种“持久存储卷”,可以被多个容器应用共享使用。
PVC(Persistent Volume Claim):用户对存储资源的一次“申请”,PVC申请的对象是PV,一旦申请成功,应用就能够像使用本地目录一样使用共享存储了。
ConfigMap、Secret、emptyDir、hostPath等属于临时性存储,当pod被调度到某个节点上时,它们随pod的创建而创建,临时占用节点存储资源,当pod离开节点时,存储资源被交还给节点,pod一旦离开这个节点,存储就失效,不具备持久化存储数据的能力。与此相反,持久化存储拥有独立的生命周期,具备持久化存储能力,其后端一般是独立的存储系统如NFS、iSCSI、cephfs、glusterfs等。
pv与pvc
1、PV 概念
PersistentVolume(PV)是集群中的一块存储,可以由管理员配置或者使用存储类(Storage Class)来动态配置。持久卷是集群资源。PV持久卷和普通的 Volume 一样,也是使用卷插件来实现的,pv是对各种诸如NFS、iSCSI、云存储等各种存储为后端所提供的存储(如:可以从远程的NFS 或分布式对象存储系统中创建出PV存储空间大小、访问方式)。
PV拥有完全独立的生命周期。
PV 就是从存储设备中的空间创建出一个存储资源。
2、PVC概念
PersistentVolumeClaim(PVC) 是用户对存储的请求。概念上与 Pod 类似。Pod会耗用节点资源,而 PVC 申领会耗用 PV 资源。所以用户(通常是开发人员)不能直接使用PV,需要通过pvc先向系统申请存储空间。
PVC 的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC),PVC必须与对应的PV建立关系,PVC会根据配置定义的时候定义申请的空间大小与访问模式去向PV申请存储空间。
总结:
PV是集群中的资源。 PVC是对这些资源的请求。
PV 和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。
PV和PVC的生命周期
PV 和 PVC 之间的相互作用遵循这个生命周期:
Provisioning(配置) ---> Binding(绑定) ---> Using(使用) ---> Releasing(释放) ---> Recycling(回收)
Provisioning,即 PV 的创建,可以直接创建 PV(静态方式),也可以使用 StorageClass 动态创建pv
Binding,将 PV 分配给 PVC
Using,Pod 通过 PVC 使用该Volume,并可以通过准入控制StorageProtection(1.9及以前版本为
PVCProtection) 阻止删除正在使用的PVC
Releasing,Pod 释放 Volume 并删除 PVC
Recycling,回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除
一个PV从创建到销毁的具体流程
一个PV创建完后状态会变成Available,等待被PVC绑定。
一旦被PVC邦定,PV的状态会变成Bound,就可以被定义了相应PVC的Pod使用。
Pod使用完后会释放PV,PV的状态变成Released。
变成Released的PV会根据定义的回收策略做相应的回收工作。
Kubernetes的共享存储供应模式包括静态和动态两种模式
静态模式
静态PV由系统管理员负责创建、提供、维护,系统管理员为用户屏蔽真正提供存储的后端及其实现细节,普通用户作为消费者,只需通过PVC申请、使用此类资源。
动态模式:
上面介绍的PV和PVC模式是需要先创建好PV,然后在将定义好PVC进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高。为了解决这一问题Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是自动创建PV的模板。通过创建StorageClass定义 PV 的属性,比如存储类型、大小等;另外创建这种 PV 需要用到的存储插件。有了这两部分信息,Kubernetes 就能够根据用户提交的 PVC,自动找到对应的 StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,自动创建需要的 PV 并进行绑定。如果用户的PVC中“storage class”的值为"",则表示不能为此PVC动态创建PV。
PV与PVC的绑定
用户创建包含容量、访问模式等信息的PVC,向系统请求存储资源。系统查找已存在PV或者监控新创建PV,如果与PVC匹配则将两者绑定。
如果PVC创建动态PV,则系统将一直将两者绑定。PV与PVC的绑定是一一对应关系,不能重复绑定。如果系统一直没有为PVC找到匹配PV,则PVC会一直处在pending状态,直到系统找到匹配PV。实际绑定的PV容量可能大于PVC中申请的容量。
持久卷pv的类型
PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插件
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- FC (Fibre Channel)
- Flexvolume
- Flocker
- NFS
- iSCSI
- RBD (Ceph Block Device)
- CephFS
- Cinder (OpenStack block storage)
- Glusterfs
- VsphereVolume
- Quobyte Volumes
- HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
- Portworx Volumes
- ScaleIO Volumes
- StorageOS
实验mysql基于NFS共享存储实现静态持久化存储
安装NFS
机器准备
k8s-master 制作nfs服务端作为共享文件系统
[root@k8s-master ~]# yum install -y nfs-utils rpcbind
[root@k8s-master ~]# mkdir /mnt/data #制作共享目录
[root@k8s-master ~]# vim /etc/exports
/mnt/data 192.168.122.0/24(rw,no_root_squash)
[root@k8s-master ~]# systemctl start rpcbind #启动服务
[root@k8s-master ~]# systemctl start nfs
集群中的工作节点都需要安装客户端工具,主要作用是节点能够驱动 nfs 文件系统
只安装,不启动服务
# yum install -y nfs-utils
master节点
制作pv.yaml(一般这个动作由 kubernetes 管理员完成,也就是我们运维人员)
[root@k8s-master ~]# mkdir /k8s/mysql -p
[root@k8s-master ~]# cd /k8s/mysql/
[root@k8s-master mysql]# vim pv.yaml
apiVersion: v1
kind: PersistentVolume #类型定义为pv
metadata:
name: my-pv #pv的名字
labels: #定义标签
type: nfs
spec:
storageClassName: nfs # 存储类型,需要与底层实际的存储一致,这里采用 nfs
nfs: # 定义nfs的配置信息
server: 192.168.122.24 # NFS 服务器的 IP
path: "/mnt/data" # NFS 上共享的目录
capacity: #定义存储能力
storage: 3Gi #指定存储空间
accessModes: #定义访问模式
- ReadWriteMany #读写权限,允许被多个Node挂载
persistentVolumeReclaimPolicy: Retain #定义数据回收策略,这里是保留
PV参数详解
1.存储能力(Capacity)
描述存储设备的能力,目前仅支持对存储空间的设置(storage=xx)。
2.访问模式(Access Modes)
对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限。访问模式如下:
ReadWriteOnce:读写权限,并且只能被单个pod挂载。
ReadOnlyMany:只读权限,允许被多个pod挂载。
ReadWriteMany:读写权限,允许被多个pod挂载。
某些PV可能支持多种访问模式,但PV在挂载时只能使用一种访问模式,多种访问模式不能同时生效。
3.persistentVolumeReclaimPolicy定义数据回收策略
目前支持如下三种回收策略:
保留(Retain):该策略表示保留PV中的数据,不进行回收,必须手动处理。
回收空间(Recycle):该策略表示在PV释放后自动执行清除操作,使PV可以重新使用。效果相当于执行 rm -rf /thevolume/*。只有 NFS 和 HostPath 两种类型的 PV支持 Recycle 策略。
删除(Delete):该策略表示在PV释放后自动删除PV中的数据。同时也会从外部(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所关联的存储资产。 就是把云存储一起删了。
4.storageClassName存储类别(Class)
PV可以设定其存储的类型(Class),通过 storageClassName参数指定一个 StorageClass 资源对象的名称。
具有特定“类别”的 PV 只能与请求了该“类别”的 PVC 进行绑定。未设定 “类别” 的 PV 则只能与不请求任何 “类别” 的 PVC 进行绑定。
相当于一个标签。
创建pv
[root@k8s-master mysql]# kubectl apply -f pv.yaml
persistentvolume/my-pv created
[root@k8s-master mysql]# kubectl get pv
PV 生命周期的各个阶段(Phase)
某个 PV 在生命周期中,可以处于以下4个阶段之一:
- Available:可用状态,还未与某个 PVC 绑定。
- Bound:已与某个 PVC 绑定。
- Released:释放,绑定的 PVC 已经删除,但没有被集群回收存储空间 。
- Failed:自动资源回收失败。
解释:
RWO:readwariteonce: 允许同一个node节点上的pod已读写的方式访问
ROX: readonlymany: 允许不同node节点的pod以只读方式访问
RWX: readwritemany: 允许不同的node节点的pod以读写方式访问
pv创建成功目前属于可用状态,还没有与pvc绑定,那么现在创建pvc
创建pvc
[root@k8s-master mysql]# vim mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim #定义类型为PVC
metadata:
name: mypvc #声明pvc的名称,当做pod的卷使用时会用到
spec:
accessModes: #定义访问pvc的模式,与pv拥有一样的模式
- ReadWriteMany #读写权限,允许被多个pod挂载
resources: #声明可以请求特定数量的资源,目前仅支持 request.storage 的设置,即存储空间大小。
requests:
storage: 3Gi #定义空间大小
storageClassName: nfs #指定绑定pv的类型,即使不指定类型pvc也会自动去匹配对应大小的pv
注意:当我们申请pvc的容量大于pv的容量是无法进行绑定的。
创建pvc
[root@k8s-master mysql]# kubectl apply -f mysql-pvc.yaml
persistentvolumeclaim/mypvc created
[root@k8s-master mysql]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc Bound my-pv 3Gi RWX pv-nfs 37s
status状态
- Available (可用): 表示可用状态,还未被任何PVC绑定
- Bound (已绑定):已经绑定到某个PVC
- Released (已释放):对应的PVC已经删除,但资源还没有被集群收回
- Failed:PV自动回收失败
Kubernetes中会自动帮我们查看pv状态为Available并且根据声明pvc容量storage的大小进行筛选匹配,同时还会根据AccessMode进行匹配。如果pvc匹配不到pv会一直处于pending状态。
mysql使用pvc持久卷
创建secret
[root@k8s-master mysql]# echo -n 'QianFeng@123!' | base64
UWlhbkZlbmdAMTIzIQ==
[root@k8s-master mysql]# vim mysql-secret.yaml
apiVersion: v1
data:
password: UWlhbkZlbmdAMTIzIQ==
kind: Secret
metadata:
annotations:
name: my-pass
type: Opaque
[root@k8s-master mysql]# kubectl apply -f mysql-secret.yaml
secret/my-pass created
[root@k8s-master mysql]# kubectl get secret
NAME TYPE DATA AGE
default-token-24c52 kubernetes.io/service-account-token 3 6d22h
my-pass Opaque 1 69s
创建myslq-pod文件
[root@k8s-master mysql]# cat mysql-pv.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-mysql
labels:
db: mysql
spec:
containers:
- name: my-mysql
image: daocloud.io/library/mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: my-pass
key: password
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim: #定义卷的类型为pvc
claimName: mypvc #指定对应pvc的名字
[root@k8s-master mysql]# kubectl apply -f mysql-pv.yaml
[root@k8s-master mysql]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-mysql 1/1 Running 0 8s
[root@k8s-master mysql]# kubectl get pod -o wide
[root@master mysql]# kubectl get pod -l db=mysql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-mysql 1/1 Running 0 24s 10.244.2.80 node-2 <none> <none>
测试
[root@k8s-master ~]# cd /mnt/data/
[root@k8s-master data]# ll
总用量 188484
-rw-r----- 1 polkitd ssh_keys 56 11月 8 21:49 auto.cnf
-rw------- 1 polkitd ssh_keys 1680 11月 8 21:49 ca-key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 8 21:49 ca.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 8 21:49 client-cert.pem
-rw------- 1 polkitd ssh_keys 1680 11月 8 21:49 client-key.pem
-rw-r----- 1 polkitd ssh_keys 688 11月 8 21:57 ib_buffer_pool
-rw-r----- 1 polkitd ssh_keys 79691776 11月 8 21:59 ibdata1
-rw-r----- 1 polkitd ssh_keys 50331648 11月 8 21:59 ib_logfile0
-rw-r----- 1 polkitd ssh_keys 50331648 11月 8 21:49 ib_logfile1
-rw-r----- 1 polkitd ssh_keys 12582912 11月 8 22:00 ibtmp1
drwxr-x--- 2 polkitd ssh_keys 4096 11月 8 21:49 mysql
drwxr-x--- 2 polkitd ssh_keys 8192 11月 8 21:49 performance_schema
-rw------- 1 polkitd ssh_keys 1680 11月 8 21:49 private_key.pem
-rw-r--r-- 1 polkitd ssh_keys 452 11月 8 21:49 public_key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 8 21:49 server-cert.pem
-rw------- 1 polkitd ssh_keys 1676 11月 8 21:49 server-key.pem
drwxr-x--- 2 polkitd ssh_keys 8192 11月 8 21:49 sys
动态绑定pv
StorageClass 相当于一个创建 PV 的模板,用户通过 PVC 申请存储卷,StorageClass 通过模板自动创建 PV,然后和 PVC 进行绑定。
StorageClass创建动态存储卷流程
1)集群管理员预先创建存储类(StorageClass);
2)用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);
3)存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);
4)系统读取存储类的信息;
5)系统基于存储类的信息,在后台自动创建PVC需要的PV;
6)用户创建一个使用PVC的Pod;
7)Pod中的应用通过PVC进行数据的持久化;
8)而PVC使用PV进行数据的最终持久化处理。
StorageClass支持的动态存储插件: