Statefulset
StatefulSet主要用于管理有状态的服务。比如在生产环境中,可以部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、Kafka集群和ZooKeeper集群等。
有状态服务需要在本地存储持久化数据,典型的是分布式数据库的应用,分布式节点实例之间有依赖的拓扑关系,比如:主从关系。 如果K8s停止分布式集群中任一实例Pod,就可能会导致数据丢失或者集群的崩溃。
Statefulset 组成
Headless Service:用来定义Pod网络标识( DNS domain); volumeClaimTemplates :存储卷申请模板,创建PVC,指定pvc名称大小,将自动创建pvc,且pvc必须由存储类供应; StatefulSet :定义具体应用,如名为Nginx,有三个Pod副本,并为每个Pod定义了一个域名部署statefulset。
StatefulSet特点
StatefulSet和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod。不同的是StatefulSet为每个Pod维护了一个粘性标识。这些Pod是根据相同的规范创建的但不可互换,每个Pod都有一个持久的标识符,在重新调度时也会保留,一般格式为StatefulSetName-Number。比如定义一个名字是Redis-Sentinel的StatefulSet,指定创建三个Pod,那么创建出来的Pod名字就为Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。StatefulSet所控制的Pod副本启停顺序是有序的。StatefulSet中的Pod采用稳定的持久化存储卷(PV或者PVC实现),删除Pod时,默认不会删除与StatefulSet相关的存储卷。- 而
StatefulSet创建的Pod一般使用Headless Service(无头服务)进行通信,和普通的Service的区别在于Headless Service没有ClusterIP,它使用的是Endpoint进行互相通信。一般在StatefulSet中指定spec.serviceName的名称与Service资源中的metadata.name保持一致。
Headless Service
Headless Service是没有Cluster IP的Service(与普通Service的区别),在Headless Service中可以看到spec.ClusterIP=None。
若解析Headless Service的DNS域名,返回的是该Service对应的全部Pod的Endpoint列表,StatefulSet在Headless Service基础上为StatefulSet控制的每个Pod实例创建DNS域名,格式为$(pod_name).$(headless_service_name),全限定域名为:
FQDN:$(pod_name).$(headless_service_name).$(namespace_name).svc.cluster.local