写在前面
这篇文章将介绍如何搭建一个高可用的kubernetes集群,主要参考的文档是:http://kubernetes.io/docs/admin/high-availability/。高可用性是一种需求,有多种选择可以实现这个需求,这里我们采用了最简单的方式搭建了这个集群,即在单个master节点的集群的基础上,部署一个高可用的Etcd集群、创建多个master Pod,并建立了一个对应的Service以实现多个master的负载均衡,最后将所有的Work Node全部注册到Service暴露的端口上。下面是集群的架构部署图:
注:这种高可用部署方案不可行,存在单点问题,查看另一篇文章的解决方案: Kubernetes HA集群搭建详细指南
高可用的部署过程
按照架构图的部署方式,需要做以下几步:
- 1、部署一个单master节点的Cluster 1#,单个master的集群部署方式比较简单,详情参考:https://get.k8s.io
- 2、其次我们应该部署一个高可用的Etcd集群Cluster 2#,详情参考:高可用Etcd集群搭建过程
- 3、在Cluster 1#中新建几个Pod,这个Pod里面运行着master所需要的全部组件
- 4、设置一个Service,以NodePort的方式暴露Pod里面的master的服务
- 5、加入新的Node节点注册到Service上,成为我们的工作集群Cluster 3#。
这个过程中比较麻烦的可能是Etcd集群了,搭建过程并不复杂,主要是如何以Pod的形式搭建成一个集群,还没有解决。现在的解决方法是在三台机器上以Docker的形式运行这些etcd服务,但这样的做法,如果遇到要进行Etcd集群扩展,就需要重启Pod里面的master镜像。
创建Pod形式的master镜像
有一点需要注意的是,如果master节点挂了之后,运行着的实例或者服务不受影响的。所以即使Cluster 1#挂了之后,我们的Cluster 3#还可以正常工作的,我们只要保持Cluster 3#的高可用性就可以了。引用Cluster 1#的目的是,我们想借用Kubernetes提供的负载均衡服务。
我们在Cluster 1#里面运行多个master的Pod镜像,通过kube-master-rc.yaml来创建三个Pod实例。
1 | apiVersion: v1 |
注意在kube-apiserver的etcd_servers选项中,我们需要填上Cluster 2#的地址。还需要注意的是,要在kube-controller-manager和kube-scheduler的选项添加—leader-elect=true的选项,这为了保证同一时刻只能有一个master进行管理和调度。
创建Service以实现负载均衡
这一步很简单,可以通过定义kube-master-service.yaml来创建一个Service实例:
1 | apiVersion: v1 |
这里需要注意的是,因为我们这个Service要当作负载均衡器,成为Cluster 3# api_server的接入点,所以它应该要暴露出来,以NodePort或者LoadBalance的方式,这里我们选择的是NodePort的形式,nodePort为8188。
Cluster 3#的组建
为什么上述Pod里的3份master实例就可以实现高可用了呢?会不会有冲突?数据会不一致吗?需要理解这一点,最关键的Etcd集群的特性,它保持了全局的key/value存储的一致性,也就是说3个master都是通过Etcd集群或者当前集群(也就是Cluster 3#)的情况,无论负载均衡器将请求送到了哪个master,最后都是要通过获取Etcd集群里面的数据进行操作的,而Etcd集群在那篇文章中已经验证了,它能保证分布式存储的一致性。
Cluster 3#集群是我们的工作集群,我们可以把一定数目的Work Node机器加入到这个集群上,做法比较简单。首先部署Node上的运行环境,比如说kube-proxy、docker等,然后我们通过启动kubelet向我们的master注册信息,在命令行输入:
1 | kubelet --logtostderr=true --cadvisor-port=8194 --cluster_dns=10.254.88.188 --cluster_domain=Xcloud.local --v=4 --api_servers=http://inf-platform53:8188 --address=0.0.0.0 --allow_privileged=false --docker-root=/home/work/docker/runtime/ |
注意这个cluster-dns我们采用的是Cluster 1#的DNS,它用作域名发现。其次我们把—api_servers设为我们的Service对外提供的地址,即NodeIP+nodePort的形式。至此我们的高可用集群的部署就算是完成了,操作过程中可能会遇到各种各样的问题,不过都可以通过查看log一点点解决,大方向是这么走的。
我们通过在Cluster 1#集群上通过
1 | kubectl describe pods kube-master |
查看我们的master的落在哪几台机器上,这几台机器都是Cluster 3#的master节点,可以在这几台机器通过输入
kubectl get nodes
来查看集群Cluster 3#的情况。