盛乐标 周庆林 游伟倩 张予倩
摘要:随着容器技术的发展和微服务架构的流行,用于容器编排的Kubernetes得到了迅速的发展,建设Kubernetes高可用集群的需求也日益增长。然而,Kubernetes高可用集群的部署涉及到众多问题,具有一定的难度。该文将Kubernetes高可用集群详细的部署过程流程化,减少集群部署过程中的不可控因素,提高了Kubernetes高可用集群部署的效率和成功率。
关键词: Kubernetes集群;高可用;微服务;容器编排
中图分类号:TP311.52 文献标识码:A 文章编号:1009-3044(2018)26-0040-04
Abstract: With the development of container technology and the popularity of microservice architecture, the software Kubernetes used for container orchestration has been developing rapidly, and the demand for building Kubernetes high availability clusters is also growing. However, the deployment of Kubernetes high-availability clusters involves many problems and has certain difficulties. In this paper, the detailed deployment process of the Kubernetes high availability cluster is streamlined, the uncontrollable factors in the cluster deployment process are reduced, and the Kubernetes high availability cluster deployment efficiency and success rate are also improved.
Key words: Kubernetes clusters; high availability; microservice; container orchestration
Kubernetes是用于自动部署、扩展和管理容器化应用程序的开源系统,是在Google公司多年生成环境经验基础上构建的。Kubernetes 2015年正式发布之后,受到了众多软件开发和运维人员的关注,其社区活跃度迅速领先于另外两款知名的容器编排系统Swarm和Mesos。然而,Kubernetes因涉及的概念众多,学习曲线比较陡峭。传统的Kubernetes集群部署,只部署单台Kubernetes API服务器,这种部署方式对生产环境来说存在天生的缺陷,容易出现因Kubernetes API服务器单点故障导致整个Kubernetes集群不能正常服务的情形。然而,Kubernetes高可用集群的部署目前仍处在测试阶段,在进行高可用集群部署时往往会遇到一些困难。本文将主要介绍利用Kubeadm进行Kubernetes高可用集群的部署,为生产环境部署Kubernetes高可用集群提供参考。
1 Kubernetes迅速发展的背景
Kubernetes集群是一种新兴的高性能计算集群[1-2]。Kubernetes的迅速发展,与云计算、容器技术和微服务架构的发展密不可分[3-7]。一方面,云计算改变了传统软硬件资源的交付和使用方式,成为一种全新的服务模式;而容器技术实现了软件交付的标准化,将软件安装、软件配置等重复的部分自动化,在软件交付时,交付的内容不仅包含了应用代码,还同時包含了该应用运行时所依赖的环境。以容器领域最著名的软件Docker为例,其可以通过一个配置文件,实现一次构建、到处部署,将应用软件安装部署的工作量从N降为1。另一方面,随着物联网、电子商务的发展,传统软件架构也受到了挑战。传统的Web架构存在开发效率低、维护困难、代码构建不灵活、稳定性差、扩展性不足等缺点。微服务(Microservice)的概念最早出现于2012年,2015年开始兴起。微服务架构将软件的完整功能切分成不同的部分,分散到各个离散的服务中从而实现对解决方案的解耦[8]。因为微服务架构具有复杂度可控、可按需扩展、容错、高可用等特性,并可以用于构建复杂应用,特别适合物联网、电子商务等行业的业务特征,近两年被众多企业采用。
两款同是2015年发布的软件Spring Cloud和Kubernetes都可以提供开发和运行微服务的环境,但两者的区别又非常明显。Spring Cloud主要面向Java开发者,提供了丰富的软件集合,整合了Java库,适合基于JVM云应用开发。然而,单独使用Spring Cloud并不能实现完整的微服务流程,软件开发者还需要考虑自动化部署、资源管理、调度、进程隔离、自愈等一系列超出软件开发之外的问题。Kubernetes则兼容多种编程语言,它是不依赖编程语言的容器管理平台,可以管理应用生命周期,使应用可以自动伸缩和自愈,实现了更广泛的微服务概念集合。Spring Cloud是尽量在JVM的范畴内解决微服务架构的各种问题和挑战,而Kubernetes则在更底层的平台层面为开发者消除这些问题[9]。随着微服务架构的流行和Kubernetes软件的不断演进,部署Kubernetes高可用集群用于生产环境的需求逐渐显现。
2 Kubernetes高可用集群的部署
2.1 环境准备
在部署Kubernetes集群之前,我们要为各个节点(运行Linux的服务器或虚拟机)准备基本的安装环境。Kubernetes集群中的节点主要有三个角色:Etcd服务器、Kubernetes API服务器和应用节点(Workers),总体框架图如图1。在该系统中,Etcd服务和Kubernetes API服务被同时部署在三台相同的节点上,以实现服务的高可用。实际上,Etcd服务和Kubernetes API服务可以被分别部署在不同的节点上,从而实现硬件隔离和更好的性能,但这样做的硬件成本和维护成本都较高,因此在这里我们选择了将 Etcd服务和API服务同时部署在三台相同的节点上。我们这里统一将Etcd服务器、Kubernetes API服务器称为Master节点,将应用节点称为Worker节点,各个节点均运行CentOS 7.4操作系统,其它Linux操作系统部署方法类似。
首先,在各個节点的/etc/hosts文件中加入各个节点的hostname,部署高可用Etcd服务器集群时需要使用各个节点的hostname;其次,目前Kublet不能完全支持SELinux特性,因此需要禁用SELinux;第三,如果是Redhat/CentOS系统,将net.bridge.bridge-nf-call-iptables和net.bridge.bridge-nf-call-iptables6两项系统参数设置为1,否则部署过程中创建的iptables规则不能生效,;第四,设置防火墙规则,允许Etcd和Kubernetes各项服务可以正常通过防火墙,需要允许网络流量通过的端口详见表1。设置完防火墙规则之后,分别安装Docker、Kubeadm、Kubelet和Kubectl。由于Kubeadm不能用于安装和管理Kubelet、Kubectl,因此Kubelet、Kubectl的软件版本最好与Kubeadm保持一致,以避免部署和运行过程中出现不兼容的风险。目前Kubernetes支持的Docker版本不低于1.11;需要注意的是,在新版本Docker中,cgroup driver已经使用cgroupfs代替systemd,我们需要确保/etc/system/system/kubelet.service.d/10-kubeadm.conf文件中的cgroup-driver配置项与Docker中的cgroup driver一致。Docker的cgroup driver可以通过docker info命令查看。
Etcd节点和Kubernetes 部署时需要使用TLS自签名证书,因此我们还需要安装证书制作工具cfssl和cfssljson。另外,为了节点之间互相访问的方便,我们往往会设置各个节点之间的SSH互信,这样通过ssh命令节点间互相访问以及节点间拷贝数据时可以免于输入密码。SSH互信可以通过ssh-keygen和ssh-copy-id命令实现,节点较多时也可以通过Shell脚本方式实现。
2.2 高可用Etcd服务器的部署
Etcd是一套分布式键值对存储系统,主要用于配置共享和服务发现。Kubernetes正是基于Etcd构建的。生产环境中需要部署Etcd服务器集群以避免单点故障。部署Etcd服务器集群首先需要安装相关证书,以三台Etcd服务器(master01、mastert02、master03)为例,具体步骤如下:
1) 在master01节点生成CA证书ca.pem和ca-key.pem;
2) 在master01节点生成Etcd客户端证书client.pem和client-key.pem;
3) 将上述4个证书文件拷贝到master02、master03节点的对应目录;
4) 利用上述的根证书,分别在master01、master02、master03上创建Etcd Server和Peer证书,即server.pem,server-key.pem,peer.pem,peer-key.pem。
完成上述证书制作以后,即可安装Etcd软件,目前Kubernetes官方建议的Etcd版本是3.1.12。修改/etc/etcd.env和/etc/system/system/etcd.service文件,将前者的PEER_NAME,PRIVATE_IP赋值节点hostname和IP地址,将后者ExecStart变量里涉及hostname和IP的部分进行相关配置。设置完成以后启动Etcd服务,并设置Etcd服务开机时自动启动。
2.3 Kubernetes API服务器的部署
本文中Kubernetes API服务器的部署采用kubeadm命令的方式,将Kubernetes的系统服务以容器的方式在服务器上运行。Kubeadm可以通过yaml配置文件的方式运行,config-example.yaml的示例文件如下:
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
api:
advertiseAddress: 192.168.2.11
apiServerCertSANs:
- 192.168.2.5
- 127.0.0.1
- 192.168.2.11
- 192.168.2.12
- 192.168.2.13
- master01
- master02
- master03
etcd:
endpoints:
- https://192.168.2.11:2379
- https://192.168.2.12:2379
- https://192.168.2.13:2379
caFile: /etc/kubernetes/pki/etcd/ca.pem
certFile: /etc/kubernetes/pki/etcd/client.pem
keyFile: /etc/kubernetes/pki/etcd/client-key.pem
apiServerExtraArgs:
endpoint-reconciler-type: lease
networking:
podSubnet: 10.244.0.0/16
kubeProxy:
config:
mode: iptables
kubernetesVersion: v1.10.3
在上述配置文件中,master01节点的IP地址为192.168.2.11,master02和master03节点的IP地址为192.168.2.12和192.168.2.13。apiServerCertSANs配置项中需要加入所有需要访问Kubernetes API服务器的IP地址和域名(hostname),包括在后面配置的高可用/负载均衡IP 192.168.2.5。podSubnet处设置Kubernetes Pod间的通讯网络,kubeadm仅支持基于容器网络接口(Container Network Interface,CNI)的Pod通讯网络。本文中所用的CNI网络是Flannel,也可以使用Calico,Canal,Weave Net等。配置文件中10.244.0.0/16是Flannel和Canal默认分配的网段,若使用其他CNI网络,则需要将podSubnet的值与CNI网络的网段匹配。对于master02和master03节点,只需要将配置文件中advertiseAddress的IP地址更换为各自的IP地址即可。之后,在三台API服务器节点上分别运行如下命令即可:
kubeadm init —config=config-example.yaml
命令成功执行以后,会在标准输出上打印出一行内容:
kubeadm join 192.168.2.11:6443 —token xxxxxx.xxxxxxxxxxx —discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxx
需要记下上面的命令,我们在安装部署worker节点时会再次使用。另外,我们还需要在master节点执行如下命令,否则kubectl命令将不能正常使用:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
執行完上述操作以后,可以通过kubectl get nodes命令查看集群状态。
2.4 CNI网络的安装
Pod是Kubernetes中最基本的资源调度单元,一个Pod由一个或一组(多个)容器组成,Pod内的容器共享存储和网络资源;但是,Pod之间的通讯则需要借助于CNI网络。以Flannel为例,其安装配置文件可从如下地址获取:
https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
如果master节点上只有一张网卡,上面的配置文件可以直接使用,但多数环境下master节点存在两张或更多的网卡,如果直接使用该配置文件,CNI网络将不能正常工作。此时我们需要将配置文件里Containers配置项中的Command加上一个参数:—iface
kubectl apply —f kube-flannel.yml
有些情况我们发现CNI网络安装以后,Kubernetes集群仍然存在内部网络问题,此时我们可以考虑是否节点上存在iptables配置冲突,可以通过如下命令解决:
iptalbes —flush
systemctl restart kubelet
systemctl restart docker
2.5 Worker节点的部署
Master节点部署完成以后,Worker节点的部署则比较简单,直接使用2.3中提到的kubeadm join命令即可。但是,这里需要特别注意的是,Master节点安装完成后屏幕上打印的token有效期是24小时,超过24小时以后我们需要重新生成token。重新生成token的命令为:
kebeadm create token
获取token的命令为:
kubeadm token list
使用新生成的token并结合kubeadm join命令即可进行Woker节点的安装部署。
2.6 Helm的安装与部署
Helm是Kubernetes的软件包管理系统,类似于Redhat的yum,Debian的apt。对于小型应用的部署,也许用kubectl apply —f
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
helm init
客户端的安装命令为:
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
helm init —client-only
如果需要helm命令的自動补全功能,还需要进行如下配置:
helm completion bash > ~/.helmrc
echo "source ~/.helmrc" >> ~/.bashrc
3 Kubernetes API服务器的高可用配置
在2.3中我们实现了对三台Kubernetes API服务器的部署,但是它们都是独立工作的,要实现Kubernetes集群的高可用,我们必须对Kubernetes API服务器使用高可用或者负载均衡措施。本文以Keepalived为例,在三台Master节点上安装好Keepalived以后,为它们配置一个与Master节点同处一个网络中的虚拟IP(VIP),访问该虚拟IP的流量都会被Keepalived定向到其中一台可用的Master节点。之后,将Worker节点对API Server的访问定向到该虚拟IP上,Master节点上执行的命令如下:
kubectl get configmap -n kube-system kube-proxy -o yaml > kube-proxy-cm.yaml
sed -i 's#server:.*#server: https://
kubectl apply -f kube-proxy-cm.yaml —force
kubectl delete pod -n kube-system -l k8s-app=kube-proxy
再将Worker节点kubelet配置文件中的server信息更改为Keepalived虚拟IP。参考命令如下:
sed -i 's#server:.*#server: https://
systemctl restart kubelet
经过上述配置,我们实现了Kubernetes API服务器的高可用,若需要实现Kubernetes API服务器的负载均衡,可以结合LVS、HAProxy、NGINX等实现。
至此,一个完整的高可用Kubernetes集群部署完成。
4 结束语
随着微服务架构和容器技术的迅速发展,部署Kubernetes高可用集群的需求正日益增长,我们以CentOS 7.4操作系统为例,详细介绍了Kubernetes高可用集群部署时的技术要点,将复杂的Kubernetes集群部署流程化,减少Kubernetes集群的部署障碍,便于最新的技术可以被及时地利用到业务中去。
参考文献:
[1] 盛乐标,游伟倩,周庆林.南京大学高性能计算中心建设的探索与实践[J].实验技术与管理,2013,30(11):144-146.
[2] Scott Carey. 云计算2018年发展趋势:无服务器计算、Kubernetes和供应商垄断[N].计算机世界,2018-01-22(010).
[3] Matt Asay, Matt Asay. Why Kubernetes is winning the container war[J]. InfoWorld.com,2016.
[4] Brandon Butler,Brandon Butler. Microsoft Azure now runs Kubernetes, for managing lots of containers[J]. Network World (Online),2017.
[5] Deepak Vohra. Kubernetes on AWS[M].Apress:2017-06-15.
[6] Deepak Vohra. Kubernetes on Google Cloud Platform[M].Apress:2017-06-15.
[7] 田杨锋,王振.基于K8s的PaaS架构及业界典型产品的调研分析[J].科学技术创新,2018(6):97-98.
[8] Martin Fowler, David Rice. Patterns of Enterprise Application Architecture. Addison-Wesley Professional, 2003.
[9] Bilgin Ibryam. Spring Cloud for Microservices Compared to Kubernetes [EB/OL].[2016-12-9]. https://developers.redhat.com/blog/2016/12/09/spring-cloud-for-microservices-compared-to-kubernetes/.
[通联编辑:梁书]