“ 今天一起来学习StatefulSet,一种特殊的Deployment”
特殊的Deployment
01.Deployment的局限
Deployment并不能满足所有的应用场景,因为它默认对应用做了一个简化假设处理,认为一个应用的所有Pod是完全一样的,但往往在实际应用中,多个实例相互间是存在依赖关系的,比如:主从关系,主备关系,实例与数据之间的关系等。
实例间的不对等关系,和实例对外部数据的依赖关系,这些类型的应用,被成为“有状态应用”(StatefulApplication)。
于是Kubernetes项目在Deployment的基础上,扩展出了对“有状态应用”的支持,这个编排功能就是:StatefulSet
02.有状态应用
StatefulSet把真实世界中的应用,抽象为两种情况:
拓扑状态
这种情况意味着,应用的多实例间不是完全对等的关系。这些应用实例,必须按照某些顺序启动,比如应用的A节点要优先于B节点启动。而如果我们把A和B两个Pod删除掉,它们再次被创建出来时也必须严格按照这个顺序才行。并且,新创建出的Pod,必须和原来的Pod的网络标识一样,这样原先的访问者才能使用原来的方法访问到这个新Pod。
存储状态
这种情况意味着,应用的多个实例分别绑定了不同的存储数据。对于这些应用实例来说,Pod A第一次读取到的数据,和隔了十分钟之后再次读取到的数据,应该是同一份数据,哪怕在此之间Pod A被重新创建过。
所以,StatefulSet的核心功能,就是通过某种方式记录这些状态,然后在Pod被重新创建时,能够为新的Pod恢复这些状态。
03.拓扑状态
拓扑状态和Headless Service是息息相关的。
HeadlessService
Service是K8S中用来 将一组Pod暴露给外界访问的一种机制,有VIP和DNS两种方式。HeadlessService就是DNS的一种。即当访问DNS时,最终会解析到Pod的真实地址。
一个标准的Headless Service的YAML文件:
字段clusterIP为None,代表这个service是Headless的。
之后,它所代理的所有Pod的IP地址,都会被绑定一个这样格式的DNS记录
<pod-name>.<svc-name>.<namespace>.svc.cluster.local
这个DNS记录,就是该Pod的唯一可解析身份。
下面来看看StatefulSet是怎么利用这个DNS来维持Pod的拓扑状态的。
一个StatefulSet的YAML文件:
这个配置文件中,servicename=nginx,标识告诉StatefulSet控制器,使用nginx这个Headless service来保证Pod的可解析身份。
创建如上的service和StatefulSet
再通过Events查看,
可以看到StatefulSet为每个Pod都设置了编号,且永远不会重复。
通过如下命令来做个测试
可以看到,最后解析的都是Pod的真实IP地址。
此时我们删除掉这两个Pod
可以看到,这两个Pod会按照原来的顺序被创建
但是可以发现它们的IP变化了,
所以,对于“有状态的应用”访问,必须使用DNS记录或者hostname的方式,而不能使用直接访问Pod的IP的方式。
04. 存储状态
K8S项目引入了一组叫做PersistentVolume Claim(PVC)和Persistent Volume(PV)的API对象,来帮助使用持久化Volume。
首先定义一个PVC,声明想要的Volume的属性
然后在应用的Pod中,使用这个PVC
下面来创建PV对象
这里使用的时ceph这种分布式的存储系统
这样,K8S就会自动绑定PVC到这个PV了。
一个完整的StatefulSet的YAML文件
凡是被这个StatefulSet管理的Pod,都会声明一个对应的PVC,而这个PVC的定义,都来自于模板volumeClaimTemplates的定义。
05. 整体流程
首先,StatefulSet控制器直接管理的是Pod。StatefulSet里面的Pod实例都是有细微区别的,而StatefulSet区分这些实例的方式,就是通过在Pod的名字里加上事先约定好的编号。
其次,Kubernetes通过HeadlessService为这些有编号的Pod,在DNS服务器中生成带有同样编号的DNS记录,用于外部访问Pod时使用。
最后,StatefulSet还为每一个Pod分配并创建一个同样编号的PVC,从而保证了每个Pod都拥有一个独立的Volume。
StatefulSet就是一种特殊的Deployment,它的独特之处在于,它的每个Pod都被编号了。这个编号体现在Pod的名字和hostname等信息上,不仅代表了Pod的创建顺序,也是Pod重要的网络标识。有了这个编号,StatefulSet就使用Kubernetes的两个标准功能:Headless Service和PV/PVC,实现了对Pod应用的拓扑状态和存储状态的维护。
好了,这就是今天的分享,现在感觉K8S的学习曲线还是蛮陡的,不加把劲,不多多思考,还是很容易晕的哦!