k8s的持久化存储PV&&PVC

1.PV和PVC的引入

Volume 提供了很是好的数据持久化方案,不过在可管理性上还有不足。node

拿前面 AWS EBS 的例子来讲,要使用 Volume,Pod 必须事先知道以下信息:mysql

  1. 当前 Volume 来自 AWS EBS。sql

  2. EBS Volume 已经提早建立,而且知道确切的 volume-id。数据库

Pod 一般是由应用的开发人员维护,而 Volume 则一般是由存储系统的管理员维护。开发人员要得到上面的信息:安全

  1. 要么询问管理员。服务器

  2. 要么本身就是管理员。app

这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一块儿了。若是系统规模较小或者对于开发环境这样的状况还能够接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必需要解决的问题。ide

Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。学习

PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员建立和维护。与 Volume 同样,PV 具备持久性,生命周期独立于 Pod。spa

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 一般由普通用户建立和维护。须要为 Pod 分配存储资源时,用户能够建立一个 PVC,指明存储资源的容量大小和访问模式(好比只读)等信息,Kubernetes 会查找并提供知足条件的 PV。

有了 PersistentVolumeClaim,用户只须要告诉 Kubernetes 须要什么样的存储资源,而没必要关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心建立 PersistentVolume 的细节信息。

 

2.经过NFS实现持久化存储

2.1配置nfs

k8s-master  nfs-server

k8s-node1  k8s-node2 nfs-client

全部节点安装nfs

yum install -y nfs-common nfs-utils 

在master节点建立共享目录

[root@k8s-master k8s]# mkdir /nfsdata

受权共享目录

[root@k8s-master k8s]# chmod 666 /nfsdata

编辑exports文件

[root@k8s-master k8s]# cat /etc/exports
/nfsdata *(rw,no_root_squash,no_all_squash,sync)

配置生效

  [root@k8s-master k8s]# export -r

启动rpc和nfs(注意顺序)

[root@k8s-master k8s]# systemctl start rpcbind
[root@k8s-master k8s]# systemctl start nfs

做为准备工做,咱们已经在 k8s-master 节点上搭建了一个 NFS 服务器,目录为 /nfsdata

2.2建立PV

下面建立一个 PV mypv1,配置文件 nfs-pv1.yml 以下:

① capacity 指定 PV 的容量为 1G。

② accessModes 指定访问模式为 ReadWriteOnce,支持的访问模式有:
ReadWriteOnce – PV 能以 read-write 模式 mount 到单个节点。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多个节点。
ReadWriteMany – PV 能以 read-write 模式 mount 到多个节点。

③ persistentVolumeReclaimPolicy 指定当 PV 的回收策略为 Recycle,支持的策略有:
Retain – 须要管理员手工回收。
Recycle – 清除 PV 中的数据,效果至关于执行 rm -rf /thevolume/*
Delete – 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

④ storageClassName 指定 PV 的 class 为 nfs。至关于为 PV 设置了一个分类,PVC 能够指定 class 申请相应 class 的 PV。

⑤ 指定 PV 在 NFS 服务器上对应的目录。

建立 mypv1

STATUS 为 Available,表示 mypv1 就绪,能够被 PVC 申请。

 

2.3建立PVC

接下来建立 PVC mypvc1,配置文件 nfs-pvc1.yml 以下:

PVC 就很简单了,只须要指定 PV 的容量,访问模式和 class。

执行命令建立 mypvc1

从 kubectl get pvc 和 kubectl get pv 的输出能够看到 mypvc1 已经 Bound 到 mypv1,申请成功。

2.4建立pod

上面已经建立好了pv和pvc,pod中直接使用这个pvc便可

与使用普通 Volume 的格式相似,在 volumes 中经过 persistentVolumeClaim 指定使用 mypvc1 申请的 Volume。

 经过命令建立mypod1

2.5验证

可见,在 Pod 中建立的文件 /mydata/hello 确实已经保存到了 NFS 服务器目录 /nfsdata中。

若是再也不须要使用 PV,可用删除 PVC 回收 PV。

3.PV的回收

当 PV 再也不须要时,可经过删除 PVC 回收。

未删除pvc以前  pv的状态是Bound

删除pvc以后pv的状态变为Available,,此时解除绑定后则能够被新的 PVC 申请。

/nfsdata文件中的文件被删除了

 

由于 PV 的回收策略设置为 Recycle,因此数据会被清除,但这可能不是咱们想要的结果。若是咱们但愿保留数据,能够将策略设置为 Retain

经过 kubectl apply 更新 PV:

 

回收策略已经变为 Retain,经过下面步骤验证其效果:

 

① 从新建立 mypvc1

② 在 mypv1 中建立文件 hello

③ mypv1 状态变为 Released

④ PV 中的数据被完整保留。

虽然 mypv1 中的数据获得了保留,但其 PV 状态会一直处于 Released,不能被其余 PVC 申请。为了从新使用存储资源,能够删除并从新建立 mypv1。删除操做只是删除了 PV 对象,存储空间中的数据并不会被删除。

 

新建的 mypv1 状态为 Available,已经能够被 PVC 申请。

PV 还支持 Delete 的回收策略,会删除 PV 在 Storage Provider 上对应存储空间。NFS 的 PV 不支持 Delete,支持 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

4.PV的动态供给

前面的例子中,咱们提早建立了 PV,而后经过 PVC 申请 PV 并在 Pod 中使用,这种方式叫作静态供给(Static Provision)。

与之对应的是动态供给(Dynamical Provision),即若是没有知足 PVC 条件的 PV,会动态建立 PV。相比静态供给,动态供给有明显的优点:不须要提早建立 PV,减小了管理员的工做量,效率高。

动态供给是经过 StorageClass 实现的,StorageClass 定义了如何建立 PV,下面是两个例子。

StorageClass standard

StorageClass slow

这两个 StorageClass 都会动态建立 AWS EBS,不一样在于 standard 建立的是 gp2 类型的 EBS,而 slow 建立的是 io1 类型的 EBS。不一样类型的 EBS 支持的参数可参考 AWS 官方文档。

StorageClass 支持 Delete 和 Retain 两种 reclaimPolicy,默认是 Delete

与以前同样,PVC 在申请 PV 时,只须要指定 StorageClass 和容量以及访问模式,好比:

 

除了 AWS EBS,Kubernetes 支持其余多种动态供给 PV 的 Provisioner,完整列表请参考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner

5.PV&&PVC在应用在mysql的持久化存储

下面演示如何为 MySQL 数据库提供持久化存储,步骤为:

  1. 建立 PV 和 PVC。

  2. 部署 MySQL。

  3. 向 MySQL 添加数据。

  4. 模拟节点宕机故障,Kubernetes 将 MySQL 自动迁移到其余节点。

  5. 验证数据一致性。

 

首先建立 PV 和 PVC,配置以下:

mysql-pv.yml

 

mysql-pvc.yml

建立 mysql-pv 和 mysql-pvc

 

接下来部署 MySQL,配置文件以下:

 

 PVC mysql-pvc Bound 的 PV mysql-pv 将被 mount 到 MySQL 的数据目录 var/lib/mysql

MySQL 被部署到 k8s-node2,下面经过客户端访问 Service mysql

kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword

 

更新数据库:

① 切换到数据库 mysql。

② 建立数据库表 my_id。

③ 插入一条数据。

④ 确认数据已经写入。

 关闭 k8s-node2,模拟节点宕机故障。

 

验证数据的一致性:

 因为node2节点已经宕机,node1节点接管了这个任务。

经过kubectl run 命令 进入node1的这个pod里,查看数据是否依旧存在

 

MySQL 服务恢复,数据也无缺无损。

6.小结

本章咱们讨论了 Kubernetes 如何管理存储资源。

emptyDir 和 hostPath 类型的 Volume 很方便,但可持久性不强,Kubernetes 支持多种外部存储系统的 Volume。

PV 和 PVC 分离了管理员和普通用户的职责,更适合生产环境。咱们还学习了如何经过 StorageClass 实现更高效的动态供给。

最后,咱们演示了如何在 MySQL 中使用 PersistentVolume 实现数据持久性。

相关文章
相关标签/搜索