再谈有状态应用部署:StatefulSet控制器
无状态与有状态
Deployment控制器设计原则:管理的所有Pod一模一样,提供同一个服务,也不考虑在哪台Node 运行,可随意扩容和缩容。这种应用称为“无状态”,例如Web服务
在实际的场景中,并不能满足所有应用,尤其是分布式应用,会部署多个实例,这些实例之间往往有 依赖关系,例如主从关系、主备关系,这种应用称为“有状态”,例如MySQL主从、Etcd集群
StatefulSet 控制器概述
StatefulSet控制器用于部署有状态应用,满足一些有状态应 用的需求:
-
Pod有序的部署、扩容、删除和停止
-
Pod分配一个稳定的且唯一的网络标识
-
Pod分配一个独享的存储
StatefulSet 控制器:网络标识
稳定的网络标识:使用Headless Service(相比普通Service只是将spec.clusterIP定义为None)来维 护Pod网络身份,会为每个Pod分配一个数字编号并且按照编号顺序部署。还需要在StatefulSet添加 serviceName: “nginx”字段指定StatefulSet控制器要使用这个Headless Service。
稳定主要体现在主机名和Pod A记录:
主机名:<statefulset名称>-<编号>
Pod DNS A记录:<statefulset名称-编号>.
部署statefulset控制器
vim statefulset-web.yaml
apiVersion: apps/v1 |
部署handless-service
vim handless-service.yaml
apiVersion: v1 |
验证查看
kubectl apply -f statefulset-web.yaml |
查看Pod创建顺序:
查看主机名:
kubectl exec statefulset-web-0 -- hostname |
测试A记录解析:
kubectl run -it dns-test --rm --image=busybox:1.28.4 -- sh |
解析出对应的三个Pod IP记录,其他Pod可使用这个名称访问:
StatefulSet 控制器:独享存储
独享存储:StatefulSet的存储卷使用VolumeClaimTemplate创建,称为卷申请模板,当StatefulSet使用 VolumeClaimTemplate创建一个PersistentVolume时,同样也会为每个Pod分配并创建一个编号的PVC, 每个PVC绑定对应的PV,从而保证每个Pod都拥有独立的存储。
部署nfs
#安装nfs安装包(每个k8s节点都要安装) |
部署nfs-storage
git clone https://github.com/kubernetes-incubator/external-storage |
部署statefulset控制器
vim statefulset-web.yaml
apiVersion: apps/v1 |
kubectl delete -f statefulset-web.yaml |
nfs服务器共享目录
测试在这三个pv目录下创建三个不同内容的index.html页面,然后访问对应不同的Pod的IP
验证访问
从上面图中,我们可以看到每个pod的数据都是独立存储的。
测试删除statefulset控制器
从上图可以看出,当我们删除pod的时候,并没有删除对应pvc和pv,而是做了数据的持久化。
再次重建测试能否访问之前的数据
从上图可以看出,重建之后,数据还是之前的数据,每个pvc对应绑定每个pv,pod的IP发生了变化。
kubernetes根据pod的编号找同样编号的pvc去挂载,从而实现了数据持久化。
通过编号保证每个pod的启动顺序
通过编号为每个pod创建不同的主机名以及dns A记录
通过编号为每个pod创建独立的pvc
StatefulSet 控制器:小结
StatefulSet与Deployment区别:有身份的!
身份三要素:
-
域名
-
主机名
-
存储(PVC)