kubernetes(K8s)容器设计模式实践案例 多节点选举模式

kubernetes(K8s)容器设计模式实践案例 多节点选举模式

《Kubernetes与云原生应用》专栏是InfoQ向轻元科技首席架构师王昕约稿的系列文章。本专栏包含8篇内容,将会从介绍和分析Kubernetes系统以及云原生应用 入手,逐步推出基于Kubernetes的容器设计模式实践案例,希望对计划应用Kubernetes的朋友有所帮助。本文是该专栏的第五篇。

1. Kubernetes系统架构与设计理念
2. 云原生应用的设计理念与挑战
3. Kubernetes与云原生应用的容器设计模式
4. Kubernetes容器设计模式实践案例-单节点多容器模式
5. Kubernetes容器设计模式实践案例-多节点选举模式
6. Kubernetes容器设计模式实践案例-工作队列模式
7. Kubernetes容器设计模式实践案例-分散收集模式
8. 云原生应用的容器设计模式综述与展望

K8s与容器设计模式

目前K8s社区推出的容器设计模式主要分为三大类:第一类,单容器管理模式;第二类,单节点多容器模式;第三类,多节点多容器模式;一类比一类更复杂。根据复杂性的不同,本系列文章给出不同篇幅的实践案例介绍。本文将借助示例介绍多节点多容器模式中的多节点选举模式。

多节点选举模式

多节点选举在分布式系统中是一种重要的模式,特别是对有状态服务来说。在分布式系统中,一般来说,无状态服务,可以随意的水平伸缩,只要把运行业务逻辑的实例复制出去运行就可以,这也就是K8s里ReplicationController和ReplicaSet所做的事情。

对于有状态服务,人们也希望能够水平的扩展,但因为每个实例有自己的持久化状态,而这个持久化状态必须要延续它的生命,因此,有状态服务的水平伸缩模式就是状态的分片,其中机制跟数据库的分片是一致的。

那么对于一个原生为分布式系统设计的有状态服务,每个实例与分片数据的对应关系,就成为这个有状态服务的全局信息。对于任何服务,多个实例的全局信息都需要一个保存的地方。

一个简单的办法是保存在外部的一个代理服务器上,这也就是MariaDB的Galera解决方案的做法,也是所以代理服务器为后端服务器所做的事情。但这种方式的问题在于,系统要依赖外部代理服务器,而代理服务器本身的高可用和水平伸缩还是没有解决的问题。所以对于要原生自己解决高可用和水平伸缩问题的系统,

例如Etcd和ElasticSearch,一定要有原生的主控节点选举机制。

这样这个分布式系统就不需要依赖外部的系统来维护自己的状态了。对于一个分布式系统,最主要的系统全局信息,就是集群中有哪些节点,Master节点是哪个,每个节点对应哪个分片。主控节点的任务,就是保存和分发这些信息。

在K8s集群中,一个微服务实例Pod可以有多个容器。这一特性很好地提高了多节点选举机制的可重用性。

它使得我们可以专门开发一个用于选举的容器镜像,在实际部署中,将选举容器和普通应用容器组合起来,应用容器只需要从本地的选举容器读取状态,就可以得到选举结果。这样,使得应用容器可以只关注自身业务逻辑相关的代码。

k8stu1
选举容器

选举容器的代码

本文中几乎所有的代码都来自于Kubernetes社区contrib项目election的事例代码https://github.com/kubernetes/contrib/tree/master/election

本文作者只是做了少量的必要修改保证在中国地区运行方便,并且增加了一些yaml文件案例以提高案例的清晰度。由衷感谢原election事例的开发者。本文作者改动后的代码在
https://github.com/xwangqingyuan/contrib/tree/master/election

启动3个选举容器观察选举

使用kubectl run启动三个选举容器观察选举。

k8stu2
使用kubectl logs 命令分别观察三个pod的日志,可以发现它们只有一个获得了leader的身份。

k8stu3
我们可以看到三个pod都汇报了election-1124968480-4ztqc。

删除掉成为leader的pod观察选举对leader的更新

k8stu4
可以看到新的pod启动代替了election-1124968480-4ztqc,仍然保证是3个pod。过一段时间后用kubectl log 观察,可以看到3个pod都报告了新的leader是election-1124968480-khiy7。

实验做完后,删除这次实验的deployment。

k8stu5
利用选举容器的组合Pod

用来作为应用容器检测选举结果

用来作为应用容器检测选举结果的nodejs程序。

k8stu6
创建一个pod.yaml文件,定一个一个pod,包含一个主应用容器和一个选举容器,pod.yaml的文件内容如下。
k8stu7
创建一个pod测试这个组合pod的工作

k8stu8
通过kubectl exec查询这个pod的本地服务,得到Master节点。

k8stu9
启动3个组合Pod观察选举

部署3个组合Pod的Deployment文件清单,在https://github.com/xwangqingyuan/contrib/blob/master/election/client/nodejs/election-sidecar.yaml
文件内容

k8stu10
用kubectl create创建3个pod。

k8stu11
用kubectl exec命令分别调用应用容器,察看选举结果。

k8stu12
由此可以看到,对于3个Pod,通过其本地http://localhost:8080查询到的leader都是demo-elector-nodejs-2834911605-0l22l。

删除作为leader的Pod,观察新选举出来的Master Pod。

k8stu13
分别观察各个Pod汇报的Master节点。

k8stu14
可以看到各个节点都汇报Master节点变为了demo-elector-nodejs-2834911605-191ts。

总结

本文主要介绍了K8s集群中,多节点容器模式中的多节点选举模式。

多节点选举模式,主要是为了原生分布式集群系统提供最基本的全局配置信息的保存。选举的目的,是为了选出一个主控节点,保存全局信息,一般来说,主控节点负责全局信息的写入,而这些全局信息会复制到其他节点作为备份。

一旦主控节点失效,新一轮选举会被触发,产生新的主控节点。这一机制是所有分布式系统的基础。本文所介绍的多节点选举模式,依靠K8s的Pod机制,成功地将选举机制与应用业务逻辑相分离,提高了模块的重用性,同时也避免了应用开发者去开发复杂的选举逻辑。

文档分享到此为止.

K8S中文社区微信公众号
分享到:更多 ()