盛樂標(biāo) 周慶林 游偉倩 張予倩
摘要:隨著容器技術(shù)的發(fā)展和微服務(wù)架構(gòu)的流行,用于容器編排的Kubernetes得到了迅速的發(fā)展,建設(shè)Kubernetes高可用集群的需求也日益增長。然而,Kubernetes高可用集群的部署涉及到眾多問題,具有一定的難度。該文將Kubernetes高可用集群詳細(xì)的部署過程流程化,減少集群部署過程中的不可控因素,提高了Kubernetes高可用集群部署的效率和成功率。
關(guān)鍵詞: Kubernetes集群;高可用;微服務(wù);容器編排
中圖分類號:TP311.52 文獻(xiàn)標(biāo)識碼: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是用于自動部署、擴(kuò)展和管理容器化應(yīng)用程序的開源系統(tǒng),是在Google公司多年生成環(huán)境經(jīng)驗(yàn)基礎(chǔ)上構(gòu)建的。Kubernetes 2015年正式發(fā)布之后,受到了眾多軟件開發(fā)和運(yùn)維人員的關(guān)注,其社區(qū)活躍度迅速領(lǐng)先于另外兩款知名的容器編排系統(tǒng)Swarm和Mesos。然而,Kubernetes因涉及的概念眾多,學(xué)習(xí)曲線比較陡峭。傳統(tǒng)的Kubernetes集群部署,只部署單臺Kubernetes API服務(wù)器,這種部署方式對生產(chǎn)環(huán)境來說存在天生的缺陷,容易出現(xiàn)因Kubernetes API服務(wù)器單點(diǎn)故障導(dǎo)致整個Kubernetes集群不能正常服務(wù)的情形。然而,Kubernetes高可用集群的部署目前仍處在測試階段,在進(jìn)行高可用集群部署時往往會遇到一些困難。本文將主要介紹利用Kubeadm進(jìn)行Kubernetes高可用集群的部署,為生產(chǎn)環(huán)境部署Kubernetes高可用集群提供參考。
1 Kubernetes迅速發(fā)展的背景
Kubernetes集群是一種新興的高性能計(jì)算集群[1-2]。Kubernetes的迅速發(fā)展,與云計(jì)算、容器技術(shù)和微服務(wù)架構(gòu)的發(fā)展密不可分[3-7]。一方面,云計(jì)算改變了傳統(tǒng)軟硬件資源的交付和使用方式,成為一種全新的服務(wù)模式;而容器技術(shù)實(shí)現(xiàn)了軟件交付的標(biāo)準(zhǔn)化,將軟件安裝、軟件配置等重復(fù)的部分自動化,在軟件交付時,交付的內(nèi)容不僅包含了應(yīng)用代碼,還同時包含了該應(yīng)用運(yùn)行時所依賴的環(huán)境。以容器領(lǐng)域最著名的軟件Docker為例,其可以通過一個配置文件,實(shí)現(xiàn)一次構(gòu)建、到處部署,將應(yīng)用軟件安裝部署的工作量從N降為1。另一方面,隨著物聯(lián)網(wǎng)、電子商務(wù)的發(fā)展,傳統(tǒng)軟件架構(gòu)也受到了挑戰(zhàn)。傳統(tǒng)的Web架構(gòu)存在開發(fā)效率低、維護(hù)困難、代碼構(gòu)建不靈活、穩(wěn)定性差、擴(kuò)展性不足等缺點(diǎn)。微服務(wù)(Microservice)的概念最早出現(xiàn)于2012年,2015年開始興起。微服務(wù)架構(gòu)將軟件的完整功能切分成不同的部分,分散到各個離散的服務(wù)中從而實(shí)現(xiàn)對解決方案的解耦[8]。因?yàn)槲⒎?wù)架構(gòu)具有復(fù)雜度可控、可按需擴(kuò)展、容錯、高可用等特性,并可以用于構(gòu)建復(fù)雜應(yīng)用,特別適合物聯(lián)網(wǎng)、電子商務(wù)等行業(yè)的業(yè)務(wù)特征,近兩年被眾多企業(yè)采用。
兩款同是2015年發(fā)布的軟件Spring Cloud和Kubernetes都可以提供開發(fā)和運(yùn)行微服務(wù)的環(huán)境,但兩者的區(qū)別又非常明顯。Spring Cloud主要面向Java開發(fā)者,提供了豐富的軟件集合,整合了Java庫,適合基于JVM云應(yīng)用開發(fā)。然而,單獨(dú)使用Spring Cloud并不能實(shí)現(xiàn)完整的微服務(wù)流程,軟件開發(fā)者還需要考慮自動化部署、資源管理、調(diào)度、進(jìn)程隔離、自愈等一系列超出軟件開發(fā)之外的問題。Kubernetes則兼容多種編程語言,它是不依賴編程語言的容器管理平臺,可以管理應(yīng)用生命周期,使應(yīng)用可以自動伸縮和自愈,實(shí)現(xiàn)了更廣泛的微服務(wù)概念集合。Spring Cloud是盡量在JVM的范疇內(nèi)解決微服務(wù)架構(gòu)的各種問題和挑戰(zhàn),而Kubernetes則在更底層的平臺層面為開發(fā)者消除這些問題[9]。隨著微服務(wù)架構(gòu)的流行和Kubernetes軟件的不斷演進(jìn),部署Kubernetes高可用集群用于生產(chǎn)環(huán)境的需求逐漸顯現(xiàn)。
2 Kubernetes高可用集群的部署
2.1 環(huán)境準(zhǔn)備
在部署Kubernetes集群之前,我們要為各個節(jié)點(diǎn)(運(yùn)行Linux的服務(wù)器或虛擬機(jī))準(zhǔn)備基本的安裝環(huán)境。Kubernetes集群中的節(jié)點(diǎn)主要有三個角色:Etcd服務(wù)器、Kubernetes API服務(wù)器和應(yīng)用節(jié)點(diǎn)(Workers),總體框架圖如圖1。在該系統(tǒng)中,Etcd服務(wù)和Kubernetes API服務(wù)被同時部署在三臺相同的節(jié)點(diǎn)上,以實(shí)現(xiàn)服務(wù)的高可用。實(shí)際上,Etcd服務(wù)和Kubernetes API服務(wù)可以被分別部署在不同的節(jié)點(diǎn)上,從而實(shí)現(xiàn)硬件隔離和更好的性能,但這樣做的硬件成本和維護(hù)成本都較高,因此在這里我們選擇了將 Etcd服務(wù)和API服務(wù)同時部署在三臺相同的節(jié)點(diǎn)上。我們這里統(tǒng)一將Etcd服務(wù)器、Kubernetes API服務(wù)器稱為Master節(jié)點(diǎn),將應(yīng)用節(jié)點(diǎn)稱為Worker節(jié)點(diǎn),各個節(jié)點(diǎn)均運(yùn)行CentOS 7.4操作系統(tǒng),其它Linux操作系統(tǒng)部署方法類似。
首先,在各個節(jié)點(diǎn)的/etc/hosts文件中加入各個節(jié)點(diǎn)的hostname,部署高可用Etcd服務(wù)器集群時需要使用各個節(jié)點(diǎn)的hostname;其次,目前Kublet不能完全支持SELinux特性,因此需要禁用SELinux;第三,如果是Redhat/CentOS系統(tǒng),將net.bridge.bridge-nf-call-iptables和net.bridge.bridge-nf-call-iptables6兩項(xiàng)系統(tǒng)參數(shù)設(shè)置為1,否則部署過程中創(chuàng)建的iptables規(guī)則不能生效,;第四,設(shè)置防火墻規(guī)則,允許Etcd和Kubernetes各項(xiàng)服務(wù)可以正常通過防火墻,需要允許網(wǎng)絡(luò)流量通過的端口詳見表1。設(shè)置完防火墻規(guī)則之后,分別安裝Docker、Kubeadm、Kubelet和Kubectl。由于Kubeadm不能用于安裝和管理Kubelet、Kubectl,因此Kubelet、Kubectl的軟件版本最好與Kubeadm保持一致,以避免部署和運(yùn)行過程中出現(xiàn)不兼容的風(fēng)險(xiǎn)。目前Kubernetes支持的Docker版本不低于1.11;需要注意的是,在新版本Docker中,cgroup driver已經(jīng)使用cgroupfs代替systemd,我們需要確保/etc/system/system/kubelet.service.d/10-kubeadm.conf文件中的cgroup-driver配置項(xiàng)與Docker中的cgroup driver一致。Docker的cgroup driver可以通過docker info命令查看。
Etcd節(jié)點(diǎn)和Kubernetes 部署時需要使用TLS自簽名證書,因此我們還需要安裝證書制作工具cfssl和cfssljson。另外,為了節(jié)點(diǎn)之間互相訪問的方便,我們往往會設(shè)置各個節(jié)點(diǎn)之間的SSH互信,這樣通過ssh命令節(jié)點(diǎn)間互相訪問以及節(jié)點(diǎn)間拷貝數(shù)據(jù)時可以免于輸入密碼。SSH互信可以通過ssh-keygen和ssh-copy-id命令實(shí)現(xiàn),節(jié)點(diǎn)較多時也可以通過Shell腳本方式實(shí)現(xiàn)。
2.2 高可用Etcd服務(wù)器的部署
Etcd是一套分布式鍵值對存儲系統(tǒng),主要用于配置共享和服務(wù)發(fā)現(xiàn)。Kubernetes正是基于Etcd構(gòu)建的。生產(chǎn)環(huán)境中需要部署Etcd服務(wù)器集群以避免單點(diǎn)故障。部署Etcd服務(wù)器集群首先需要安裝相關(guān)證書,以三臺Etcd服務(wù)器(master01、mastert02、master03)為例,具體步驟如下:
1) 在master01節(jié)點(diǎn)生成CA證書ca.pem和ca-key.pem;
2) 在master01節(jié)點(diǎn)生成Etcd客戶端證書client.pem和client-key.pem;
3) 將上述4個證書文件拷貝到master02、master03節(jié)點(diǎn)的對應(yīng)目錄;
4) 利用上述的根證書,分別在master01、master02、master03上創(chuàng)建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賦值節(jié)點(diǎn)hostname和IP地址,將后者ExecStart變量里涉及hostname和IP的部分進(jìn)行相關(guān)配置。設(shè)置完成以后啟動Etcd服務(wù),并設(shè)置Etcd服務(wù)開機(jī)時自動啟動。
2.3 Kubernetes API服務(wù)器的部署
本文中Kubernetes API服務(wù)器的部署采用kubeadm命令的方式,將Kubernetes的系統(tǒng)服務(wù)以容器的方式在服務(wù)器上運(yùn)行。Kubeadm可以通過yaml配置文件的方式運(yùn)行,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節(jié)點(diǎn)的IP地址為192.168.2.11,master02和master03節(jié)點(diǎn)的IP地址為192.168.2.12和192.168.2.13。apiServerCertSANs配置項(xiàng)中需要加入所有需要訪問Kubernetes API服務(wù)器的IP地址和域名(hostname),包括在后面配置的高可用/負(fù)載均衡IP 192.168.2.5。podSubnet處設(shè)置Kubernetes Pod間的通訊網(wǎng)絡(luò),kubeadm僅支持基于容器網(wǎng)絡(luò)接口(Container Network Interface,CNI)的Pod通訊網(wǎng)絡(luò)。本文中所用的CNI網(wǎng)絡(luò)是Flannel,也可以使用Calico,Canal,Weave Net等。配置文件中10.244.0.0/16是Flannel和Canal默認(rèn)分配的網(wǎng)段,若使用其他CNI網(wǎng)絡(luò),則需要將podSubnet的值與CNI網(wǎng)絡(luò)的網(wǎng)段匹配。對于master02和master03節(jié)點(diǎn),只需要將配置文件中advertiseAddress的IP地址更換為各自的IP地址即可。之后,在三臺API服務(wù)器節(jié)點(diǎn)上分別運(yùn)行如下命令即可:
kubeadm init —config=config-example.yaml
命令成功執(zhí)行以后,會在標(biāo)準(zhǔn)輸出上打印出一行內(nèi)容:
kubeadm join 192.168.2.11:6443 —token xxxxxx.xxxxxxxxxxx —discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxx
需要記下上面的命令,我們在安裝部署worker節(jié)點(diǎn)時會再次使用。另外,我們還需要在master節(jié)點(diǎn)執(zhí)行如下命令,否則kubectl命令將不能正常使用:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
執(zhí)行完上述操作以后,可以通過kubectl get nodes命令查看集群狀態(tài)。
2.4 CNI網(wǎng)絡(luò)的安裝
Pod是Kubernetes中最基本的資源調(diào)度單元,一個Pod由一個或一組(多個)容器組成,Pod內(nèi)的容器共享存儲和網(wǎng)絡(luò)資源;但是,Pod之間的通訊則需要借助于CNI網(wǎng)絡(luò)。以Flannel為例,其安裝配置文件可從如下地址獲?。?/p>
https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
如果master節(jié)點(diǎn)上只有一張網(wǎng)卡,上面的配置文件可以直接使用,但多數(shù)環(huán)境下master節(jié)點(diǎn)存在兩張或更多的網(wǎng)卡,如果直接使用該配置文件,CNI網(wǎng)絡(luò)將不能正常工作。此時我們需要將配置文件里Containers配置項(xiàng)中的Command加上一個參數(shù):—iface
kubectl apply —f kube-flannel.yml
有些情況我們發(fā)現(xiàn)CNI網(wǎng)絡(luò)安裝以后,Kubernetes集群仍然存在內(nèi)部網(wǎng)絡(luò)問題,此時我們可以考慮是否節(jié)點(diǎn)上存在iptables配置沖突,可以通過如下命令解決:
iptalbes —flush
systemctl restart kubelet
systemctl restart docker
2.5 Worker節(jié)點(diǎn)的部署
Master節(jié)點(diǎn)部署完成以后,Worker節(jié)點(diǎn)的部署則比較簡單,直接使用2.3中提到的kubeadm join命令即可。但是,這里需要特別注意的是,Master節(jié)點(diǎn)安裝完成后屏幕上打印的token有效期是24小時,超過24小時以后我們需要重新生成token。重新生成token的命令為:
kebeadm create token
獲取token的命令為:
kubeadm token list
使用新生成的token并結(jié)合kubeadm join命令即可進(jìn)行Woker節(jié)點(diǎn)的安裝部署。
2.6 Helm的安裝與部署
Helm是Kubernetes的軟件包管理系統(tǒng),類似于Redhat的yum,Debian的apt。對于小型應(yīng)用的部署,也許用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命令的自動補(bǔ)全功能,還需要進(jìn)行如下配置:
helm completion bash > ~/.helmrc
echo "source ~/.helmrc" >> ~/.bashrc
3 Kubernetes API服務(wù)器的高可用配置
在2.3中我們實(shí)現(xiàn)了對三臺Kubernetes API服務(wù)器的部署,但是它們都是獨(dú)立工作的,要實(shí)現(xiàn)Kubernetes集群的高可用,我們必須對Kubernetes API服務(wù)器使用高可用或者負(fù)載均衡措施。本文以Keepalived為例,在三臺Master節(jié)點(diǎn)上安裝好Keepalived以后,為它們配置一個與Master節(jié)點(diǎn)同處一個網(wǎng)絡(luò)中的虛擬IP(VIP),訪問該虛擬IP的流量都會被Keepalived定向到其中一臺可用的Master節(jié)點(diǎn)。之后,將Worker節(jié)點(diǎn)對API Server的訪問定向到該虛擬IP上,Master節(jié)點(diǎn)上執(zhí)行的命令如下:
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節(jié)點(diǎn)kubelet配置文件中的server信息更改為Keepalived虛擬IP。參考命令如下:
sed -i 's#server:.*#server: https://
systemctl restart kubelet
經(jīng)過上述配置,我們實(shí)現(xiàn)了Kubernetes API服務(wù)器的高可用,若需要實(shí)現(xiàn)Kubernetes API服務(wù)器的負(fù)載均衡,可以結(jié)合LVS、HAProxy、NGINX等實(shí)現(xiàn)。
至此,一個完整的高可用Kubernetes集群部署完成。
4 結(jié)束語
隨著微服務(wù)架構(gòu)和容器技術(shù)的迅速發(fā)展,部署Kubernetes高可用集群的需求正日益增長,我們以CentOS 7.4操作系統(tǒng)為例,詳細(xì)介紹了Kubernetes高可用集群部署時的技術(shù)要點(diǎn),將復(fù)雜的Kubernetes集群部署流程化,減少Kubernetes集群的部署障礙,便于最新的技術(shù)可以被及時地利用到業(yè)務(wù)中去。
參考文獻(xiàn):
[1] 盛樂標(biāo),游偉倩,周慶林.南京大學(xué)高性能計(jì)算中心建設(shè)的探索與實(shí)踐[J].實(shí)驗(yàn)技術(shù)與管理,2013,30(11):144-146.
[2] Scott Carey. 云計(jì)算2018年發(fā)展趨勢:無服務(wù)器計(jì)算、Kubernetes和供應(yīng)商壟斷[N].計(jì)算機(jī)世界,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架構(gòu)及業(yè)界典型產(chǎn)品的調(diào)研分析[J].科學(xué)技術(shù)創(chuàng)新,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/.
[通聯(lián)編輯:梁書]