Kubernetes Master High Availability 高级实践
才云科技云開(kāi)源高級(jí)工程師唐繼元受邀DBAplus社群,在線分享《Kubernetes Master High Availability 高級(jí)實(shí)踐》,介紹如何構(gòu)建Kubernetes Master High Availability環(huán)境。
以下是分享實(shí)錄:
大家好,我是才云科技的唐繼元,今天給大家?guī)?lái)一篇技術(shù)分享,本次分享我將為大家介紹如何構(gòu)建Kubernetes Master High Availability環(huán)境。此次分享內(nèi)容是我在工作中經(jīng)驗(yàn)總結(jié),如果有不正確的或者需要改進(jìn)的地方,歡迎各位大神指正。
相信大家對(duì)容器、docker和kubernetes這些概念并不陌生。下面進(jìn)入本次分享的正題。
Kubernetes作為容器編排管理系統(tǒng),通過(guò)Scheduler、ReplicationController等組件實(shí)現(xiàn)了應(yīng)用層的高可用,但是針對(duì)Kubernetes集群,還需要實(shí)現(xiàn)Master組件的高可用。
本次分享論述的Master高可用方案主要基于社區(qū)的高可用方案(鏈接)的實(shí)踐,但是社區(qū)的高可用方案中采用的GCE的External Loadbalancer,并未論述如何實(shí)現(xiàn)External Loadbalancer,而且也并沒(méi)有將Kubernetes集群組件容器化。所以,我們的高可用方案在社區(qū)高可用方案的基礎(chǔ)之上進(jìn)行了如下兩個(gè)方面的提升:
第一,除了kubelet之外,Kubernetes所有組件容器化;
第二,通過(guò)haproxy和keepalived構(gòu)建Loadbalancer實(shí)現(xiàn)Master的高可用。
下面我們分四個(gè)章節(jié)來(lái)詳細(xì)論述Kubernetes Master High Availability環(huán)境的搭建。
HA Master整體架構(gòu)
核心技術(shù)點(diǎn)和難點(diǎn)
實(shí)踐中的遇到的那些坑
社區(qū)關(guān)于HA Master的未來(lái)發(fā)展
HA Master整體架構(gòu)
我們已經(jīng)成功將支持Master High Availability的Kubernetes集群部署到企業(yè)私有云平臺(tái),底層采用的是Ubuntu 14.04操作系統(tǒng)。下面是一個(gè)典型的部署環(huán)境:
Static Pods是由其所在節(jié)點(diǎn)上的kubelet直接管理,而不需要通過(guò)Apiserver來(lái)監(jiān)視它們。Static Pods的資源類(lèi)型只能是Pod,而且不與任何的Replication Controller相關(guān)聯(lián),它們完全由kubelet來(lái)監(jiān)視,并且當(dāng)它們異常停止的時(shí)候由該kubelet負(fù)責(zé)重啟它們。
(haproxy, keepalived):這里表示我們將haproxy和keepalived放置在同一個(gè)pod中。
1.1.kubelet對(duì)static pod高可用的支持
我們需要為kubelet進(jìn)程配置一個(gè)manifests監(jiān)視目錄:
--config=/etc/kubernetes/manifests如果有新的yaml/manifest文件添加到該目錄,kubelet則根據(jù)yaml/manifest文件創(chuàng)建一個(gè)新的static pod;
如果我們把某個(gè)yaml/manifest文件從該目錄刪除,kubelet則會(huì)刪除由該yaml/manifest文件所產(chǎn)生的static pod;
如果該目錄下的yaml/manifest文件有更新,kubelet則會(huì)刪除原來(lái)的static pod,而根據(jù)更新后的yaml/manifest文件重新創(chuàng)建一個(gè)新的static pod;
如果manifests目錄下的文件沒(méi)有任何變化,但是其下某個(gè)yaml/manifest文件所產(chǎn)生的static pod錯(cuò)誤退出或者被誤刪后,kubelet仍然會(huì)根據(jù)該yaml/manifest文件重新創(chuàng)建一個(gè)新的static pod。
這樣,kubelet在一定程度上保證了static pod的高可用。
1.2.kubelet進(jìn)程的高可用
kubelet通過(guò)manifests監(jiān)視目錄保證了staticpod的高可用,但是如果kubelet進(jìn)程本身錯(cuò)誤退出或者被誤刪后,誰(shuí)來(lái)負(fù)責(zé)重新啟動(dòng)kubelet進(jìn)程呢?
在Linux系統(tǒng)中,我們可以通過(guò)Monit、Upstart、Systemd、Supervisor等工具實(shí)現(xiàn)對(duì)服務(wù)的監(jiān)控保證服務(wù)的高可用。
在Ubuntu 14.04操作系統(tǒng)中,我們將kubelet做成系統(tǒng)服務(wù),利用Upstart來(lái)保證kubelet服務(wù)的高可用,下面是kubelet服務(wù)基于Upstart的服務(wù)啟動(dòng)腳本/etc/init/kubelet.conf:
其中:
respawn: 該命令設(shè)置服務(wù)或任務(wù)異常停止時(shí)將自動(dòng)啟動(dòng)。除stop命令外的停止都是異常停止。
respawn limit: 該命令設(shè)置服務(wù)或任務(wù)異常停止后重啟次數(shù)和間隔時(shí)間。
1.3.Master High Availability Kubernetes整體架構(gòu)圖
從架構(gòu)圖中我們可以看到:
1) Upstart保證docker服務(wù)和kubelet服務(wù)的高可用,而Kubernetes的其他組件將以staticpod的方式由kubelet保證高可用。
2)兩臺(tái)lb節(jié)點(diǎn)通過(guò)haproxy和keepalived構(gòu)建出一個(gè)ExternalLoadbalancer,并提供VIP供客戶端訪問(wèn)。
3) Haproxy配置成“SSLTermination”方式,外網(wǎng)client通過(guò)HTTPS請(qǐng)求訪問(wèn)集群,而內(nèi)網(wǎng)client則可以通過(guò)HTTPS/HTTP請(qǐng)求訪問(wèn)。
4) Kubernetes高可用集群通過(guò)flannelstatic pod構(gòu)建一個(gè)Overlay網(wǎng)絡(luò),使集群中的docker容器能夠通過(guò)Kubernetes Cluster IP進(jìn)行通信。
核心技術(shù)點(diǎn)和難點(diǎn)
2.1.運(yùn)行在特權(quán)模式的組件
Kubernetes集群中的一些組件需要通過(guò)內(nèi)核模塊來(lái)為集群提供服務(wù),因此這些組件需要運(yùn)行在特權(quán)模式下,以便能訪問(wèn)相應(yīng)的內(nèi)核模塊。
2.1.1.開(kāi)啟特權(quán)模式
為了支持docker容器在特權(quán)模式下運(yùn)行,我們需要開(kāi)啟Kubernetes集群的特權(quán)模式權(quán)限:
這里主要體現(xiàn)在kubelet服務(wù)和apiserver服務(wù)。
1) Kubelet service
kubelet服務(wù)需要開(kāi)啟特權(quán)模式權(quán)限,以便允許docker容器向kubelet請(qǐng)求以特權(quán)模式運(yùn)行。
2) Apiserver static pod
apiserver static pod需要開(kāi)啟特權(quán)模式權(quán)限,以便運(yùn)行在特權(quán)模式下的docker容器能夠訪問(wèn)apiserver服務(wù)。
2.1.2.運(yùn)行在特權(quán)模式下的docker容器
運(yùn)行在特權(quán)模式下的docker容器,在yaml文件中需要添加如下字段:
這里主要體現(xiàn)在kubeproxy服務(wù)、flannel服務(wù)和keepalived服務(wù)。
1) Kubeproxy static pod
kubeproxy需要通過(guò)Iptables設(shè)置防火墻規(guī)則。
2) Flannel static pod
flannel需要訪問(wèn)vxlan、openvswitch等路由數(shù)據(jù)報(bào)文。
3) Keepalived static pod
keepalived需要訪問(wèn)IP_VS內(nèi)核模塊來(lái)建立VIP。
2.2.Static pod必須運(yùn)行在主機(jī)網(wǎng)絡(luò)下
如上所述的這些以static pod形式存在的Kubernetes集群組件,必須工作在主機(jī)網(wǎng)絡(luò)下:
雖然Overlay網(wǎng)絡(luò)是為了讓不同節(jié)點(diǎn)間的docker容器進(jìn)行通信,而上述以staticpod形式存在的組件也都是docker容器,但是它們之間的心跳和信息交流都需要通過(guò)主機(jī)網(wǎng)絡(luò)而不是類(lèi)似于flannel等的Overlay網(wǎng)絡(luò)。理由如下:
1)這些static pods不同于應(yīng)用的pods,它們的穩(wěn)定保障了Kubernetes集群的穩(wěn)定性,它們之間的心跳和信息交流都是通過(guò)它們配置文件中的靜態(tài)IP地址進(jìn)行的,而docker/flannel網(wǎng)絡(luò)是動(dòng)態(tài)的,我們無(wú)法保證docker/flannel網(wǎng)絡(luò)中IP地址的穩(wěn)定性,同時(shí)也無(wú)法事先知道IP地址。
2) kubeproxy、flannel、haproxy需要通過(guò)主機(jī)網(wǎng)絡(luò)修改路由規(guī)則,從而使主機(jī)上的服務(wù)能被其他主機(jī)訪問(wèn)。
3) haproxy需要將外網(wǎng)請(qǐng)求重定向到內(nèi)網(wǎng)后端服務(wù)器上,也必須需要主機(jī)網(wǎng)絡(luò)。
2.3.External Loadbalancer部署要點(diǎn)
對(duì)于如何配置haproxy和keepalived,網(wǎng)絡(luò)上有非常多的資源,所以這里不在論述。下面我們來(lái)分析一下部署過(guò)程中的一些要點(diǎn)。
External Loadbalancer由至少兩臺(tái)lb node組成,通過(guò)haproxy和keepalived pod實(shí)現(xiàn)Master的負(fù)載均衡,對(duì)外提供統(tǒng)一的VIP。
我們可以將haproxy和keepalived分別放置在不同的pod中,也可以將它們放置在同一個(gè)pod中。考慮到keepalived需要監(jiān)測(cè)haproxy的狀態(tài),我們會(huì)把haproxy和keepalived放在一起做成一個(gè)loadbalancerpod。
2.3.1.lb node配置
1)使能內(nèi)核IPVS模塊
由于keepalived需要通過(guò)IPVS模塊實(shí)現(xiàn)路由轉(zhuǎn)發(fā),所以我們需要使能內(nèi)核IPVS模塊。
從Linux內(nèi)核版本2.6起,ip_vs code已經(jīng)被整合進(jìn)了內(nèi)核中,因此,只要在編譯內(nèi)核的時(shí)候選擇了ipvs的功能,Linux即能支持LVS。因此我們只需要配置操作系統(tǒng)啟動(dòng)時(shí)自動(dòng)加載IPVS模塊:
我們可以通過(guò)如下命令查看ip_vs模塊是否成功加載:
lsmod | grep ip_vs如果沒(méi)有加載,我們可以通過(guò)modprobe命令加載該模塊:
modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr2)修改內(nèi)核參數(shù)
為了使keepalived將數(shù)據(jù)包轉(zhuǎn)發(fā)到真實(shí)的后端服務(wù)器,每一個(gè)lb node都需要開(kāi)啟IP轉(zhuǎn)發(fā)功能
另外,keepalived設(shè)置的VIP有可能為非本地IP地址,所以我們還需要使能非本地IP地址綁定功能:
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf2.3.2.keepalived監(jiān)測(cè)haproxy狀態(tài)的方法
對(duì)于普通進(jìn)程來(lái)說(shuō), keepalived進(jìn)程可以通過(guò)“killall -0 haproxy”命令檢測(cè)haproxy進(jìn)程是否正常運(yùn)行(注: Sending the signal 0 to a given PID just checksif any process with the given PID is running)。
然而在docker容器環(huán)境下,各容器都有自己的PidNamespace和NetworkNamespace,我們就需要開(kāi)啟haproxy的健康檢查頁(yè)面,然后keepalived通過(guò)健康檢查頁(yè)面的URL來(lái)檢測(cè)haproxy目前是否正常運(yùn)行。
haproxy健康檢查頁(yè)面配置:
keepalived對(duì)haproxy的狀態(tài)檢測(cè):
vrrp_script check_script {script "/etc/keepalived/check_haproxy.py http://caicloud:caicloud@127.0.0.1/haproxy?stats"interval 5 # check every 5 secondsweight 5fall 2 # require 2 fail for KOrise 1 # require 1 successes for OK }2.3.3.haproxy SSL配置
haproxy代理ssl配置有兩種方式:
1) haproxy本身提供SSL證書(shū),后面的web服務(wù)器走正常的http協(xié)議;
2) haproxy本身只提供代理,直接轉(zhuǎn)發(fā)client端的HTTPS請(qǐng)求到后端的web服務(wù)器。注意:這種模式下“mode”必須是“tcp”模式, 即僅支持4層代理。
考慮到:第一,用戶親和性訪問(wèn)需要7層代理的支持;第二,loadbalancer和master走的都是集群內(nèi)網(wǎng)。所以本實(shí)踐采用了第一種方式,配置如下:
2.3.4.haproxy配置:haproxy.cfg
2.3.5.keepalived配置:keepalived.conf
1) lb-1上keepalived配置
2) lb-2上keepalived配置
lb-2跟lb-1的配置差不多,除了下面兩個(gè)字段:
2.4.flannel網(wǎng)絡(luò)設(shè)置
2.4.1Master節(jié)點(diǎn)flannel網(wǎng)絡(luò)設(shè)置
對(duì)于Master節(jié)點(diǎn),需要等待Etcd Pod集群?jiǎn)?dòng)完后,先在Master上創(chuàng)建Flannel網(wǎng)絡(luò),然后Flannel Pod客戶端才可以從Etcd中獲取到各個(gè)Master節(jié)點(diǎn)的IP網(wǎng)段,獲取到IP網(wǎng)段后會(huì)在主機(jī)上產(chǎn)生文件:“/var/run/flannel/subnet.env”,然后根據(jù)該文件修改docker啟動(dòng)參數(shù):
并重啟docker服務(wù)。
2.4.2非Master節(jié)點(diǎn)flannel網(wǎng)絡(luò)設(shè)置
對(duì)于非Master節(jié)點(diǎn),待Loadbalancer起來(lái)之后,Node節(jié)點(diǎn)能夠訪問(wèn)Apiserver之后,Flannel Pod客戶端才能從Etcd獲取到該Node節(jié)點(diǎn)的IP網(wǎng)段,并且同樣會(huì)在主機(jī)上產(chǎn)生文件:“/var/run/flannel/subnet.env”。然后修改docker啟動(dòng)參數(shù),并重啟docker服務(wù)。
3.實(shí)踐中的遇到的那些坑
3.1.官網(wǎng)“haproxy docker image”的坑
Docker Hub上“haproxy image”的“docker-entrypoint.sh”內(nèi)容如下:
問(wèn)題就出在“haproxy-systemd-wrapper”。如果運(yùn)行命令:“haproxy -f/etc/haproxy/haproxy.cfg”, 而實(shí)際上運(yùn)行的是經(jīng)過(guò)“haproxy-systemd-wrapper”包裝后的命令:
執(zhí)行命令“haproxy -f /etc/haproxy/haproxy.cfg”時(shí),真正執(zhí)行的是:“/usr/local/sbin/haproxy -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg -Ds”,對(duì)于“-Ds”選項(xiàng), 官網(wǎng)是這么描述的:
原來(lái),“haproxy”經(jīng)過(guò)“haproxy-systemd-wrapper”包裝后在后臺(tái)執(zhí)行,而docker container不允許進(jìn)程后臺(tái)執(zhí)行,否則docker容器將該啟動(dòng)命令執(zhí)行完后就退出了。官網(wǎng)image的這個(gè)坑很大。
所以,當(dāng)我們用官網(wǎng)“haproxy image”的時(shí)候,就需要用haproxy的完全路徑來(lái)執(zhí)行。比如在yaml文件中:
3.2.haproxy container exited with 137
首先137退出碼表示,其他進(jìn)程向haproxy container發(fā)起了“kill”信號(hào),導(dǎo)致haproxy container退出,容器日志如下
其次,當(dāng)通過(guò)“docker run”命令執(zhí)行haproxy container,使用的命令與yaml文件中的一樣,而且照樣輸出上述的“WARNING”,但是容器卻不退出。
然后,無(wú)奈之下,我試著先將這個(gè)“WARNING”解決:這個(gè)錯(cuò)誤是由于haproxy.cfg中添加了SSL證書(shū)導(dǎo)致的, 可以通過(guò)設(shè)置參數(shù)“default-dh-param”解決:
global...# turn on stats unix socketstats socket /run/haproxy.statstune.ssl.default-dh-param 2048 frontend frontend-apiserver-https# Haproxy enable SSLbind *:443 ssl crt /etc/kubernetes/master-loadbalancer.pem...當(dāng)我解決這個(gè)“WARNING”之后,奇跡出現(xiàn)了,haproxy container奇跡般的正常運(yùn)行了。原來(lái)在容器的世界,一個(gè)“WARNING”也不能疏忽。
社區(qū)關(guān)于HA Master的未來(lái)發(fā)展
熟悉kubelet配置參數(shù)的都知道,我們?cè)诮okubelet配置apiserver的時(shí)候,可以通過(guò)“--api-servers”指定多個(gè):
--api-servers=http://m1b:8080,http://m1c:8080,http://m2a:8080,http://m2b:8080,http://m2c:8080這看起來(lái)似乎已經(jīng)做到apiserver的高可用配置了,但是實(shí)際上當(dāng)?shù)谝粋€(gè)apiserver掛掉之后, 不能成功的連接到后面的apiserver,也就是說(shuō)目前仍然只有第一個(gè)apiserver起作用。
如果上述問(wèn)題解決之后, 似乎不需要額外的loadbalancer也能實(shí)現(xiàn)master的高可用了,但是,除了kubelet需要配置apiserver,controllermanager和scheduler都需要配置apiserver,目前我們還只能通過(guò)“--master”配置一個(gè)apiserver,無(wú)法支持多個(gè)apiserver。
社區(qū)后續(xù)打算支持multi-master配置,實(shí)現(xiàn)Kubernetes Master的高可用,而且計(jì)劃在Kubernetes 1.4版本中合入。
即使將來(lái)社區(qū)實(shí)現(xiàn)了通過(guò)multi-master配置的高可用方式,本次分享的MasterHigh Availability仍然非常有意義,因?yàn)樵谒接性茍?chǎng)景中,ExternalLoadbalancer除了實(shí)現(xiàn)Master的高可用和負(fù)載均衡外,還可以針對(duì)Worker Node實(shí)現(xiàn)Nodeport請(qǐng)求的負(fù)載均衡,從而不僅實(shí)現(xiàn)了應(yīng)用的高可用訪問(wèn),同時(shí)也大大提高了應(yīng)用的訪問(wèn)速度和性能。
參考鏈接:
鏈接
鏈接
好了,以上是本次分享的所有內(nèi)容,歡迎大家批評(píng)指正,同時(shí)也希望能為大家?guī)?lái)些收益。
總結(jié)
以上是生活随笔為你收集整理的Kubernetes Master High Availability 高级实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux shell脚本备份mysql
- 下一篇: 为什么年轻人挣得很多还是穷?北上广深挑战