20221221 11. PV、PVC
简介
部署mysql之前我们需要先了解一个概念有状态服务。这是一种特殊的服务,简单的归纳下就是会产生需要持久化的数据,并且有很强的I/O需求,且重启需要依赖上次存储到磁盘的数据。如典型的mysql,kafka,zookeeper等等。
在我们有比较优秀的商业存储的前提下,非常推荐使用有状态服务进行部署,计算和存储分离那是相当的爽的。在实际生产中如果没有这种存储,localPV也是不错的选择,当然local pv其实和hostPath是一样的。当然我们在开发测试环境也是可以自己搭建一套简单的如NFS服务,来享受存储和计算分离的爽快感。
kubernetes中定义一种资源类型Stateful Service即有状态服务,有状态服务需要的持久化数据动态绑定我们可以利用存储的API PersistentVolume(PV)和PersistentVolumeClaim(PVC)来进行需要的相关数据的绑定和存储。
概念
PV概念
persistentVolume:是由管理员设置的存储,它是集群的一部分。就像节点是集群中的资源一样,PV也是集群中的资源。PV是Volumes之类的卷插件,但具有独立于使用PV的pod的生命周期。
此API对象包含存储实现的细节,即NFS、iSCSI或者特定于云供应商的存储系统
PVC概念
PersistentVolumeClaim | Kubernetes
peresistentVolumeClaim是用户存储的请求。它与pod相似,pod消耗节点资源,PVC消耗PV资源。
pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式。例如:可以以读/写一次或者 只读多次模式挂载。
PV & PVC
PV就好比是一个仓库,我们需要先购买一个仓库,即定义一个PV存储服务,例如CEPH、NFS、Local Hostpath等等。
PVC就好比租户,pv和pvc是一对一绑定的,挂载到pod中,一个pvc可以被多个pod挂载。
示例
pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: data-mariadb-pv
labels:
app: mariadb-pv
spec:
accessModes:
- ReadWriteOnce #hostpath模式只支持 ReadWriteOnce
capacity:
storage: 10Gi
hostPath:
path: /data/mariadb
type: DirectoryOrCreate
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
volumeMode: Filesystem
pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pvc
labels:
app: mariadb-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
使用
volumeMounts:
- mountPath: /etc/mysql/mariadb.conf.d/ #容器内的挂载目录
name: lagoumariadb #随便给一个名字,这个名字必须与volumes.name一致
- mountPath: /var/lib/mysql #容器内的挂载目录
name: volume-mariadb
volumes:
- name: lagoumariadb
configMap:
name: mariadbconfigmap
- name: volume-mariadb
persistentVolumeClaim:
claimName: mariadb-pvc
PV&&PVC 理论补充
存储机制介绍
在 Kubernetes 中,存储资源和计算资源 (CPU、Memory) 同样重要,Kubernetes 为了能让管理员方便管理集群中的存储资源,同时也为了让使用者使用存储更加方便,所以屏蔽了底层存储的实现细节,将存储抽象出两个 API 资源 PersistentVolume 和 PersistentVolumeClaim 对象来对存储进行管理。
-
PersistentVolume(持久化卷): PersistentVolume 简称 PV , 是对底层共享存储的一种抽象,将共享存储定义为一种资源,它属于集群级别资源,不属于任何 Namespace ,用户使用 PV 需要通过 PVC 申请。PV 是由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如说 Ceph、GlusterFS、NFS 等,都是通过插件机制完成与共享存储的对接,且根据不同的存储 PV 可配置参数也不相同
-
PersistentVolumeClaim(持久化卷声明): PersistentVolumeClaim 简称 PVC ,是用户存储的一种声明,类似于对存储资源的申请,它属于一个 Namespace 中的资源,可用于向 PV 申请存储资源。 PVC 和 Pod 比较类似, Pod 消耗的是 Node 节点资源,而 PVC 消耗的是 PV 存储资源, Pod 可以请求 CPU 和 Memory,而 PVC 可以请求特定的存储空间和访问模式
PV 和 PVC 的存在很好的解决了存储管理的问题,不过这些存储每次都需要管理员手动创建和管理,如果一个集群中有很多应用,并且每个应用都要挂载很多存储,那么就需要创建很多 PV 和 PVC 与应用关联。为了解决这个问题 Kubernetes 在 1.4 版本中引入了 StorageClass 对象。
当我们创建 PVC 时指定对应的 StorageClass 就能和 PV 的 StorageClass 关联, StorageClass 会交由与他关联 Provisioner 存储插件来创建与管理存储,它能帮你创建对应的 PV 和在远程存储上创建对应的文件夹,并且还能根据设定的参数,删除与保留数据。所以管理员只要在 StorageClass 中配置好对应的参数就能方便的管理集群中的存储资源。
PV 支持存储的类型
PersistentVolume 类型实现为插件,目前 Kubernetes 支持以下插件:
-
RBD:Ceph 块存储
-
FC:光纤存储设备
-
NFS:网络问卷存储卷
-
iSCSI:iSCSI 存储设备
-
CephFS:开源共享存储系统
-
Flocker:一种开源共享存储系统
-
Glusterfs:一种开源共享存储系统
-
Flexvolume:一种插件式的存储机制
-
HostPath:宿主机目录,仅能用于单机
-
AzureFile:Azure 公有云提供的 File
-
AzureDisk:Azure 公有云提供的 Disk
-
ScaleIO Volumes:DellEMC 的存储设备
-
StorageOS:StorageOS 提供的存储服务
-
VsphereVolume:VMWare 提供的存储系统
-
Quobyte Volumes:Quobyte 提供的存储服务
-
Portworx Volumes:Portworx 提供的存储服务
-
GCEPersistentDisk:GCE 公有云提供的 PersistentDisk
-
AWSElasticBlockStore:AWS 公有云提供的 ElasticBlockStore
PV 的生命周期
PV 生命周期总共四个阶段 :
-
Available(可用)—— 可用状态,尚未被 PVC 绑定。
-
Bound(已绑定)—— 绑定状态,已经与某个 PVC 绑定。
-
Released(已释放)—— 与之绑定的 PVC 已经被删除,但资源尚未被集群回收。
-
Failed(失败)—— 当删除 PVC 清理资源,自动回收卷时失败,所以处于故障状态。
命令行显示绑定到 PV 的 PVC 的名称
kubectl get pv
PV 的常用配置参数
存储能力 (capacity)
PV 可以通过配置 capacity 中的 storage 参数,对 PV 挂多大存储空间进行设置。 目前 capacity 只有一个设置存储大小的选项,未来可能会增加。
存储卷模式(volumeMode)
PV 可以通过配置 volumeMode 参数,对存储卷类型进行设置,可选项包括:
-
Filesystem: 文件系统,默认是此选项
-
Block: 块设备
目前 Block 模式只有 AWSElasticBlockStore、AzureDisk、FC、GCEPersistentDisk、iSCSI、LocalVolume、RBD、VsphereVolume 等支持)。
访问模式(accessModes)
PV 可以通过配置 accessModes 参数,设置访问模式来限制应用对资源的访问权限,有以下机制访问模式:
-
ReadWriteOnce——该卷可以被单个节点以读/写模式挂载
-
ReadOnlyMany——该卷可以被多个节点以只读模式挂载
-
ReadWriteMany——该卷可以被多个节点以读/写模式挂载
PersistentVolume 可以以资源提供者支持的任何方式挂载到主机上。供应商具有不同的功能,每个PV的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式
在命令行中,访问模式缩写为:
-
RWO - ReadWriteOnce
-
ROX - ReadOnlyMany
-
RWX - ReadWriteMany
不同的存储所支持的访问模式也不相同,具体如下:
Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | √ | - | - |
AzureFile | √ | √ | √ |
AzureDisk | √ | - | - |
CephFS | √ | √ | √ |
Cinder | √ | - | - |
FC | √ | √ | - |
FlexVolume | √ | √ | - |
Flocker | √ | - | - |
GCEPersistentDisk | √ | √ | - |
GlusteFS | √ | √ | √ |
HostPath | √ | - | - |
iSCSI | √ | √ | - |
PhotonPersistentDisk | √ | - | - |
Quobyte | √ | √ | √ |
NFS | √ | √ | √ |
RBD | √ | √ | - |
VsphereVolume | √ | - | - |
PortworxVolume | √ | - | √ |
ScaleIO | √ | √ | - |
StorageOS | √ | - | - |
挂载参数(mountOptions)
PV 可以根据不同的存储卷类型,设置不同的挂载参数,每种类型的存储卷可配置参数都不相同。如 NFS 存储,可以设置 NFS 挂载配置,如下:
# 下面例子只是 NFS 支持的部分参数,其它参数请自行查找 NFS 挂载参数。
mountOptions:
- hard
- nfsvers=4
存储类 (storageClassName)
PV 可以通过配置 storageClassName 参数指定一个存储类 StorageClass 资源,具有特定StorageClass 的 PV 只能与指定相同 StorageClass 的 PVC 进行绑定,没有设置 StorageClass 的 PV 也是同样只能与没有指定 StorageClass 的 PVC 绑定。
回收策略(persistentVolumeReclaimPolicy)
PV 可以通过配置 persistentVolumeReclaimPolicy 参数设置回收策略,可选项如下:
-
Retain(保留): 保留数据,需要由管理员手动清理
-
Recycle(回收): 删除数据,即删除目录下的所有文件,比如说执行
rm -rf /thevolume/*
命令,目前只有 NFS 和 HostPath 支持 -
Delete(删除): 删除存储资源,仅仅部分云存储系统支持,比如删除 AWS EBS 卷,目前只有 AWS EBS,GCE PD,Azure 磁盘和 Cinder 卷支持删除
PVC 常用参数
筛选器(selector)
PVC 可以通过在 Selecter 中设置 Label 标签,筛选出带有指定 Label 的 PV 进行绑定。
Selecter 中可以指定 matchLabels 或 matchExpressions ,如果两个字段都设定了就需要同时满足才能匹配。
selector:
matchLabels:
release: "stable"
matchExpressions:
- key: environment
operator: In
values: dev
资源请求(resources)
PVC 设置目前只有 requests.storage 一个参数,用于指定申请存储空间的大小。
resources:
requests:
storage: 8Gi
存储类(storageClass)
PVC 要想绑定带有特定 StorageClass 的 PV 时,也必须设定 storageClassName 参数,且名称也必须要和 PV 中的 storageClassName 保持一致。如果要绑定的 PV 没有设置 storageClassName 则 PVC 中也不需要设置。
当 PVC 中如果未指定 storageClassName 参数或者指定为空值,则还需要考虑 Kubernetes 中是否设置了默认的 StorageClass :
-
未启用 DefaultStorageClass:等于 storageClassName 值为空
-
启用 DefaultStorageClass:等于 storageClassName 值为默认的 StorageClass
-
如果设置
storageClassName=""
,则表示该 PVC 不指定 StorageClass
访问模式(accessModes)
PVC 中可设置的访问模式与 PV 中一样,用于限制应用对资源的访问权限。
NFS 存储卷
NFS 介绍
NFS 是 Network FileSystem 的缩写,顾名思义就是网络文件存储系统, 分为服务端(Server)和客户端(Client)。最早由 sun 公司开发,是类 unix 系统间实现磁盘共享的一种方法。 它允许网络中的计算机之间通过 TCP/IP 网络共享资源。通过 NFS,我们本地 NFS 的客户端应用可以透明地读写位于服务端 NFS 服务器上的文件,就像访问本地文件一样方便。简单的理解,NFS 就是可以透过网络,让不同的主机、不同的操作系统可以共享存储的服务。
NFS 在文件传送或信息传送过程中依赖于 RPC(Remote Procedure Call) 协议,即远程过程调用,NFS 的各项功能都必须要向 RPC 来注册,如此一来 RPC 才能了解 NFS 这个服务的各项功能 Port、PID、NFS 在服务器所监听的 IP 等,而客户端才能够透过 RPC 的询问找到正确对应的端口,所以,NFS 必须要有 RPC 存在时才能成功的提供服务,简单的理解二者关系:NFS是 一个文件存储系统,而 RPC 是负责信息的传输。
NFS 共享存储方式
-
手动方式静态创建所需要的PV和PVC
-
通过创建PVC动态地创建对应PV,无需手动创建PV
安装
NFS文件挂载
yum install -y nfs-utils rpcbind
mkdir -p /nfs
chmod 777 /nfs
# 主节点
vim /etc/exports
/nfs *(rw,no_root_squash,no_all_squash,sync)
参数说明
参数 | 说明 |
---|---|
ro | 只读访问 |
rw | 读写访问 |
sync | 所有数据在请求时写入共享 |
async | nfs 在写入数据前可以响应请求 |
secure | nfs 通过 1024 以下的安全 TCP/IP 端口发送 |
insecure | nfs 通过 1024 以上的端口发送 |
wdelay | 如果多个用户要写入 nfs 目录,则归组写入(默认) |
no_wdelay | 如果多个用户要写入 nfs 目录,则立即写入,当使用 async 时,无需此设置 |
hide | 在 nfs 共享目录中不共享其子目录 |
no_hide | 共享 nfs 目录的子目录 |
subtree_check | 如果共享 /usr/bin 之类的子目录时,强制 nfs 检查父目录的权限(默认) |
no_subtree_check | 不检查父目录权限 |
all_squash | 共享文件的 UID 和 GID 映射匿名用户 anonymous,适合公用目录 |
no_all_squash | 保留共享文件的 UID 和 GID(默认) |
root_squash | root 用户的所有请求映射成如 anonymous 用户一样的权限(默认) |
no_root_squash | root 用户具有根目录的完全管理访问权限 |
anonuid=xxx | 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 UID |
anongid=xxx | 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 GID |
systemctl start rpcbind
systemctl start nfs
# 设置开启启动
systemctl enable rpcbind
systemctl enable nfs
# 在另一台 Linux 虚拟机上测试一下,是否能够正确挂载:
showmount -e 172.16.0.7
# 在客户端创建挂在目录
mkdir -p /nfs
# 挂载远端目录到本地
mount 172.16.0.7:/nfs /nfs
# 客户端卸载 NFS 挂载目录
umount /nfs
# 强制卸载
umount -l /nfs
示例
pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: data-mariadb-pv
labels:
app: mariabd-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /mariadb
server: 192.168.198.156
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
volumeMode: Filesystem
pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pvc
labels:
app: mariadb-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
使用
volumeMounts:
- mountPath: /etc/mysql/mariadb.conf.d/ #容器内的挂载目录
name: lagoumariadb #随便给一个名字,这个名字必须与volumes.name一致
- mountPath: /var/lib/mysql #容器内的挂载目录
name: volume-mariadb
volumes:
- name: lagoumariadb
configMap:
name: mariadbconfigmap
- name: volume-mariadb
persistentVolumeClaim:
claimName: mariadb-pvc