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
                    
                
                
            
        
浙公网安备 33010602011771号