- 数据管理
#1、Volume
本质上,k8s Volume是一个目录,这一点与Docker Volume类似。
当Volume被mount到Pod,Pod中的所有容器都可以访问这个Volume。
k8s Volume也支持多种backend类型。
↓
Volume提供了对各种backend的抽象,对于容器来说,所有类型的Volume都只是一个目录。
#2、emptyDir
emptyDir Volume是Host上的一个空目录。
emptyDir Volume对于容器来说是持久的,对于Pod则不是。
当Pod从节点删除时,Volume的内容也会被删除。
但如果只是容器被销毁而Pod还在,则Volume不受影响。
↓
emptyDir Volume的生命周期与Pod一一致。
↓
Pod中的所有容器都可以共享Volume,它们可以指定各自的mount路径。
(1)配置文件
Pod有两个容器producer和consumer,它们共享一个Volume。
1、文件最低分volumes定义了一个emptyDir 类型的 Volume shared-volume
2、producer 容器将 shared-volume mount 到 /producer_dir 目录
3、producer 通过 echo 将数据写到文件 hello 里
4、consumer 容器将 shared-volume mount 到 /consumer_dir 目录
5、consumer 通过 cat 从文件 hello 读数据
(2)创建Pod
kubectl apply -f emptyDir.yml
kubectl get pod
kubectl logs producer-consumer consumer
kubectl logs显示容器consumer成功读到了producer写入的数据,验证了两个容器共享 emptyDir Volume。
(3)通过docker inspect查看容器的详细配置信息,可以看到两个容器都mount了同一个目录
↓
↓
emptyDir特别适合Pod中的容器需要临时共享存储空间的场景,比如前面的生产者消费者用例。
- hostPath Volume
hostPath Volume的作用是将Docker Host文件系统中已经存在的目录mount给Pod的容器。
大部分应用不会用,因为这增加了Pod与节点的耦合,限制了Pod的使用。
那些需要访问k8s或Docker内部数据(配置文件和二进制库)的应用则需要使用hostPath。
比如kube-apiserver和kube-controller-manager就是这样的应用
↓
#查看kube-apiserver Pod的配置,这里定义了三个hostPath Volume
kubectl edit --namespace=kube-system pod kube-apiserver-k8s-master
↓
如果Pod被销毁了,hostPath对应的目录也还会被保留。
hostPath的持久性比emptyDir强,不过一旦Host崩溃,hostPath也无法访问了。
- 外部Storage Provider
针对k8s部署在公有云的情况,可以直接使用云硬盘作为Volume。
↓
要在Pod中使用ESB volume,必须先在AWS中创建,然后通过volume-id引用。
其他云硬盘的使用方法可参考各公有云厂商的官方文档。
↓
k8s Volume也可以使用主流的分布式存储,比如Ceph、GlusterFS等。
↓
相对于emptyDir和hostPath,这些Volume类型的最大特点就是不依赖k8s。
volume的底层基础设施由独立的存储系统管理,与k8s集群是分离的。
数据被持久化后,即使整个k8s崩溃也不会受损。
↓
volume提供了非常好的数据持久化方案,不过在可管理性上还有不足。
- PV & PVC
Pod通常是由应用的开发人员维护,而Volume则通常是由存储系统的管理员维护。
管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。
↓
解决方案:PersistentVolume 和 PersistentVolumeClaim
↓
PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。
PV 具有持久性,生命周期独立于 Pod。
↓
PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。
PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。
↓
有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。
这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。
↓
k8s支持多种类型的 PersistentVolume。
- NFS PersistentVolume
#1、准备工作,在k8s-master节点上搭建一个NFS服务器,目录为/nfsdata
showmount -e
#2、创建一个PV mypv1,配置文件nfs-pv1.yml
1、capacity指定PV的容量
2、accessModes指定访问模式为ReadWriteOnce
3、persistentVolumeReclaimPolicy指定当PV的回收策略Recycle
4、storageClassName指定PV的class为nfs
5、指定PV在NFS服务器上对应的目录
#3、创建mypv1
kubectl apply -f nfs-pv1.yml
kuebctl get pv
STATUES为Available,表示mypv1就绪,可以被PVC申请。
#4、创建PVC mypvc1,配置文件nfs-pvc1.yml
PVC就很简单了,只需要指定PV的容量,访问模式和class。
#5、创建mypvc1
kubectl apply -f nfs-pvc1.yml
kubectl get pvc
kubectl get pv
从 kubectl get pvc 和 kubectl get pv 的输出可以看到 mypvc1 已经 Bound 到 mypv1,申请成功。
#6、在Pod中使用存储,pod1.yml配置文件
#7、创建mypod1
kubectl apply -f pod1.yml
kubectl get pod -o wide
#8、验证PV是否可用
#k8s-master节点上执行
kubectl exec mypod1 touch /mydata/hello
ls /nfsdata/pv1/
- 回收PV
#1、当PV不再需要时,可通过删除PVC回收。
kubectl delete pvc mypvc1
kubectl get pod -o wide
kubectl get pv
↓
当 PVC mypvc1 被删除后,我们发现 Kubernetes 启动了一个新 Pod recycler-for-mypv1,这个 Pod 的作用就是清除 PV mypv1 的数据。
此时 mypv1 的状态为 Released,表示已经解除了与 mypvc1 的 Bound,正在清除数据,不过此时还不可用。
↓
当数据清除完毕后,mypv1的状态重新变为Available,此时则可以被新的PVC申请。
#2、因为PV的回收策略设置为Recycle,所以数据会被清除。
如果希望保留数据,可以将策略设置为Retain。
↓
更新PV:
kubectl apply -f nfs-pv1.yml
kubectl get pv
#3、验证Retain的效果
kubectl apply -f nfs.pvc1.yml
kubectl exec mypod1 touch /mydata/hello
ls /nfsdata/pv1/
kubectl delete pvc mypvc1
kubectl get pv
kubectl get pod -o wide
ls /nfsdata/pv1/
↓
↓
虽然mypv1中的数据得到了保留,但其PV状态会一直处于Released,不能被其他PVC申请。
为了重新使用存储资源,可以删除并重新创建mypv1.
删除操作只是删除了PV对象,存储空间中的数据并不会被删除。
kubectl delete pv mypv1
kubectl apply -f nfs-pv1.yml
kubectl get pv
↓
新建的mypv1状态为Available,已经可以被PVC申请。
PV 还支持 Delete 的回收策略,会删除 PV 在 Storage Provider 上对应存储空间。
- PV动态供给
前面的例子:提前创建了PV,然后通过PVC申请PV并在Pod中使用,这种方式叫做静态供给。
动态供给:如果没有满足PVC条件的PV,会动态创建PV。
优势:不需要提前创建PV,减少了管理员的工作量,效率高。
↓
动态供给是通过StorageClass实现的,StorageClass定义了如何创建PV。
#1、StorageClass standard
#2、StorageClass slow
这两个StorageClass都会动态创建AWS EBS。
#3、StorageClass 支持 Delete 和 Retain 两种 reclaimPolicy,默认是 Delete。
#4、与之前一样,PVC在申请PV时,只需要指定 StorageClass 和容量以及访问模式
除了AWS EBS,k8s支持其他多种动态供给PV的Provisioner。
- MySQL使用PV和PVC
#1、步骤
a、创建PV和PVC
b、部署MySQL
c、向MySQL添加数据
d、模拟节点宕机故障,k8s将MySQL自动迁移到其他节点
e、验证数据一致性
#2、创建PV和PVC,配置如下
mysql-pv.yml
mysql-pvc.yml
#3、创建mysql-pv和mysql-pvc
kubectl apply -f mysql-pv.yml
kubectl apply -f mysql-pvc.yml
kubectl get pv,pvc
#4、部署MySQL
PVC mysql-pvc Bound 的 PV mysql-pv 将被 mount 到 MySQL 的数据目录 var/lib/mysql。
#5、创建
kubectl apply -f mysql.yml
kubectl get pod -o wide
#6、MySQL被部署到k8s-node2,通过客户端访问Service mysql
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client – mysql -h mysql -ppassword
更新数据库:
#7、关闭k8s-node2,模拟节点宕机故障
shutdown now
#8、一段时间后,k8s将MySQL迁移到k8s-node1
kubectl get pod -o wide
#9、验证数据的一致性
MySQL服务恢复,数据也完好无损。