摘要:才云科技云開源高級(jí)工程師唐繼元受邀社群,在線分享高級(jí)實(shí)踐,介紹如何構(gòu)建環(huán)境。除命令外的停止都是異常停止。
才云科技云開源高級(jí)工程師唐繼元受邀DBAplus社群,在線分享《Kubernetes Master High Availability 高級(jí)實(shí)踐》,介紹如何構(gòu)建Kubernetes Master High Availability環(huán)境。
以下是分享實(shí)錄:
大家好,我是才云科技的唐繼元,今天給大家?guī)硪黄夹g(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),通過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,而且也并沒有將Kubernetes集群組件容器化。所以,我們的高可用方案在社區(qū)高可用方案的基礎(chǔ)之上進(jìn)行了如下兩個(gè)方面的提升:
第一,除了kubelet之外,Kubernetes所有組件容器化;
第二,通過haproxy和keepalived構(gòu)建Loadbalancer實(shí)現(xiàn)Master的高可用。
下面我們分四個(gè)章節(jié)來詳細(xì)論述Kubernetes Master High Availability環(huán)境的搭建。
HA Master整體架構(gòu)
核心技術(shù)點(diǎn)和難點(diǎn)
實(shí)踐中的遇到的那些坑
社區(qū)關(guān)于HA Master的未來發(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直接管理,而不需要通過Apiserver來監(jiān)視它們。Static Pods的資源類型只能是Pod,而且不與任何的Replication Controller相關(guān)聯(lián),它們完全由kubelet來監(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ì)刪除原來的static pod,而根據(jù)更新后的yaml/manifest文件重新創(chuàng)建一個(gè)新的static pod;
如果manifests目錄下的文件沒有任何變化,但是其下某個(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通過manifests監(jiān)視目錄保證了staticpod的高可用,但是如果kubelet進(jìn)程本身錯(cuò)誤退出或者被誤刪后,誰來負(fù)責(zé)重新啟動(dòng)kubelet進(jìn)程呢?
在Linux系統(tǒng)中,我們可以通過Monit、Upstart、Systemd、Supervisor等工具實(shí)現(xiàn)對(duì)服務(wù)的監(jiān)控保證服務(wù)的高可用。
在Ubuntu 14.04操作系統(tǒng)中,我們將kubelet做成系統(tǒng)服務(wù),利用Upstart來保證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)通過haproxy和keepalived構(gòu)建出一個(gè)ExternalLoadbalancer,并提供VIP供客戶端訪問。
3) Haproxy配置成“SSLTermination”方式,外網(wǎng)client通過HTTPS請(qǐng)求訪問集群,而內(nèi)網(wǎng)client則可以通過HTTPS/HTTP請(qǐng)求訪問。
4) Kubernetes高可用集群通過flannelstatic pod構(gòu)建一個(gè)Overlay網(wǎng)絡(luò),使集群中的docker容器能夠通過Kubernetes Cluster IP進(jìn)行通信。
2.1.運(yùn)行在特權(quán)模式的組件
Kubernetes集群中的一些組件需要通過內(nèi)核模塊來為集群提供服務(wù),因此這些組件需要運(yùn)行在特權(quán)模式下,以便能訪問相應(yīng)的內(nèi)核模塊。
2.1.1.開啟特權(quán)模式
為了支持docker容器在特權(quán)模式下運(yùn)行,我們需要開啟Kubernetes集群的特權(quán)模式權(quán)限:
--allow-privileged=true
這里主要體現(xiàn)在kubelet服務(wù)和apiserver服務(wù)。
1) Kubelet service
kubelet服務(wù)需要開啟特權(quán)模式權(quán)限,以便允許docker容器向kubelet請(qǐng)求以特權(quán)模式運(yùn)行。
2) Apiserver static pod
apiserver static pod需要開啟特權(quán)模式權(quán)限,以便運(yùn)行在特權(quán)模式下的docker容器能夠訪問apiserver服務(wù)。
2.1.2.運(yùn)行在特權(quán)模式下的docker容器
運(yùn)行在特權(quán)模式下的docker容器,在yaml文件中需要添加如下字段:
securityContext: privileged: true
這里主要體現(xiàn)在kubeproxy服務(wù)、flannel服務(wù)和keepalived服務(wù)。
1) Kubeproxy static pod
kubeproxy需要通過Iptables設(shè)置防火墻規(guī)則。
2) Flannel static pod
flannel需要訪問vxlan、openvswitch等路由數(shù)據(jù)報(bào)文。
3) Keepalived static pod
keepalived需要訪問IP_VS內(nèi)核模塊來建立VIP。
2.2.Static pod必須運(yùn)行在主機(jī)網(wǎng)絡(luò)下
如上所述的這些以static pod形式存在的Kubernetes集群組件,必須工作在主機(jī)網(wǎng)絡(luò)下:
hostNetwork: true
雖然Overlay網(wǎng)絡(luò)是為了讓不同節(jié)點(diǎn)間的docker容器進(jìn)行通信,而上述以staticpod形式存在的組件也都是docker容器,但是它們之間的心跳和信息交流都需要通過主機(jī)網(wǎng)絡(luò)而不是類似于flannel等的Overlay網(wǎng)絡(luò)。理由如下:
1)這些static pods不同于應(yīng)用的pods,它們的穩(wěn)定保障了Kubernetes集群的穩(wěn)定性,它們之間的心跳和信息交流都是通過它們配置文件中的靜態(tài)IP地址進(jìn)行的,而docker/flannel網(wǎng)絡(luò)是動(dòng)態(tài)的,我們無法保證docker/flannel網(wǎng)絡(luò)中IP地址的穩(wěn)定性,同時(shí)也無法事先知道IP地址。
2) kubeproxy、flannel、haproxy需要通過主機(jī)網(wǎng)絡(luò)修改路由規(guī)則,從而使主機(jī)上的服務(wù)能被其他主機(jī)訪問。
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ò)上有非常多的資源,所以這里不在論述。下面我們來分析一下部署過程中的一些要點(diǎn)。
External Loadbalancer由至少兩臺(tái)lb node組成,通過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需要通過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模塊:
echo "ip_vs" >> /etc/modules echo "ip_vs_rr" >> /etc/modules echo "ip_vs_wrr" >> /etc/modules
我們可以通過如下命令查看ip_vs模塊是否成功加載:
lsmod | grep ip_vs
如果沒有加載,我們可以通過modprobe命令加載該模塊:
modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr
2)修改內(nèi)核參數(shù)
為了使keepalived將數(shù)據(jù)包轉(zhuǎn)發(fā)到真實(shí)的后端服務(wù)器,每一個(gè)lb node都需要開啟IP轉(zhuǎn)發(fā)功能
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
另外,keepalived設(shè)置的VIP有可能為非本地IP地址,所以我們還需要使能非本地IP地址綁定功能:
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
2.3.2.keepalived監(jiān)測(cè)haproxy狀態(tài)的方法
對(duì)于普通進(jìn)程來說, keepalived進(jìn)程可以通過“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,我們就需要開啟haproxy的健康檢查頁面,然后keepalived通過健康檢查頁面的URL來檢測(cè)haproxy目前是否正常運(yùn)行。
haproxy健康檢查頁面配置:
listen admin_stats bind 0.0.0.0:80 log global mode http maxconn 10 stats enable #Hide HAPRoxy version, a necessity for any public-facing site stats hide-version stats refresh 30s stats show-node stats realm Haproxy Statistics stats auth caicloud:caicloud stats uri /haproxy?stats
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 seconds weight 5 fall 2 # require 2 fail for KO rise 1 # require 1 successes for OK }
2.3.3.haproxy SSL配置
haproxy代理ssl配置有兩種方式:
1) haproxy本身提供SSL證書,后面的web服務(wù)器走正常的http協(xié)議;
2) haproxy本身只提供代理,直接轉(zhuǎn)發(fā)client端的HTTPS請(qǐng)求到后端的web服務(wù)器。注意:這種模式下“mode”必須是“tcp”模式, 即僅支持4層代理。
考慮到:第一,用戶親和性訪問需要7層代理的支持;第二,loadbalancer和master走的都是集群內(nèi)網(wǎng)。所以本實(shí)踐采用了第一種方式,配置如下:
frontend frontend-apiserver-https # Haproxy enable SSL bind *:443 ssl crt /etc/kubernetes/master-loadblancer.pem option forwardfor default_backend backend-apiserver-http
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è)字段:
state BACKUP priority 97
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ù):
. /var/run/flannel/subnet.env DOCKER_OPTS="$DOCKER_OPTS --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}"
并重啟docker服務(wù)。
2.4.2非Master節(jié)點(diǎn)flannel網(wǎng)絡(luò)設(shè)置
對(duì)于非Master節(jié)點(diǎn),待Loadbalancer起來之后,Node節(jié)點(diǎn)能夠訪問Apiserver之后,F(xiàn)lannel 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.1.官網(wǎng)“haproxy docker image”的坑
Docker Hub上“haproxy image”的“docker-entrypoint.sh”內(nèi)容如下:
問題就出在“haproxy-systemd-wrapper”。如果運(yùn)行命令:“haproxy -f/etc/haproxy/haproxy.cfg”, 而實(shí)際上運(yùn)行的是經(jīng)過“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)是這么描述的:
原來,“haproxy”經(jīng)過“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的完全路徑來執(zhí)行。比如在yaml文件中:
3.2.haproxy container exited with 137
首先137退出碼表示,其他進(jìn)程向haproxy container發(fā)起了“kill”信號(hào),導(dǎo)致haproxy container退出,容器日志如下
[WARNING] 155/053036 (1) : Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.
其次,當(dāng)通過“docker run”命令執(zhí)行haproxy container,使用的命令與yaml文件中的一樣,而且照樣輸出上述的“WARNING”,但是容器卻不退出。
然后,無奈之下,我試著先將這個(gè)“WARNING”解決:這個(gè)錯(cuò)誤是由于haproxy.cfg中添加了SSL證書導(dǎo)致的, 可以通過設(shè)置參數(shù)“default-dh-param”解決:
global ... # turn on stats unix socket stats socket /run/haproxy.stats tune.ssl.default-dh-param 2048 frontend frontend-apiserver-https # Haproxy enable SSL bind *:443 ssl crt /etc/kubernetes/master-loadbalancer.pem ...
當(dāng)我解決這個(gè)“WARNING”之后,奇跡出現(xiàn)了,haproxy container奇跡般的正常運(yùn)行了。原來在容器的世界,一個(gè)“WARNING”也不能疏忽。
社區(qū)關(guān)于HA Master的未來發(fā)展熟悉kubelet配置參數(shù)的都知道,我們?cè)诮okubelet配置apiserver的時(shí)候,可以通過“--api-servers”指定多個(gè):
--api-servers=http://m1b:8080,http://m1c:8080,http://m2a:8080,http://m2b:8080,http://m2c:8080
這看起來似乎已經(jīng)做到apiserver的高可用配置了,但是實(shí)際上當(dāng)?shù)谝粋€(gè)apiserver掛掉之后, 不能成功的連接到后面的apiserver,也就是說目前仍然只有第一個(gè)apiserver起作用。
如果上述問題解決之后, 似乎不需要額外的loadbalancer也能實(shí)現(xiàn)master的高可用了,但是,除了kubelet需要配置apiserver,controllermanager和scheduler都需要配置apiserver,目前我們還只能通過“--master”配置一個(gè)apiserver,無法支持多個(gè)apiserver。
社區(qū)后續(xù)打算支持multi-master配置,實(shí)現(xiàn)Kubernetes Master的高可用,而且計(jì)劃在Kubernetes 1.4版本中合入。
即使將來社區(qū)實(shí)現(xiàn)了通過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)用的高可用訪問,同時(shí)也大大提高了應(yīng)用的訪問速度和性能。
參考鏈接:
鏈接
鏈接
好了,以上是本次分享的所有內(nèi)容,歡迎大家批評(píng)指正,同時(shí)也希望能為大家?guī)硇┦找妗?/p>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/32466.html
摘要:從容器到容器編排平臺(tái)以及周邊生態(tài)系統(tǒng)包含很多工具來管理容器的生命周期。終止運(yùn)行中的容器。發(fā)現(xiàn)在由運(yùn)行于多個(gè)主機(jī)上的容器組成的分布式部署容器發(fā)現(xiàn)至關(guān)重要。類似的,當(dāng)容器崩潰時(shí),編排工具可以啟動(dòng)替換。 從容器到容器編排 Docker平臺(tái)以及周邊生態(tài)系統(tǒng)包含很多工具來管理容器的生命周期。例如,Docker Command Line Interface(CLI)支持下面的容器活動(dòng): 從注冊(cè)表...
摘要:?jiǎn)栴}是不是定義的一個(gè)的容器集群是只部署在同一個(gè)主機(jī)上楊樂到目前是,同一個(gè)里的是部署在同一臺(tái)主機(jī)的。問題這個(gè)圖里的是安裝在哪里的所有的客戶端以及會(huì)連接這個(gè)嘛楊樂可以任意地方,只要能訪問到集群,會(huì)作為的出口。 kubernetes1.0剛剛發(fā)布,開源社區(qū)400多位貢獻(xiàn)者一年的努力,多達(dá)14000多次的代碼提交,最終達(dá)到了之前預(yù)計(jì)的milestone, 并意味著這個(gè)開源容器編排系統(tǒng)可以正式在...
摘要:相關(guān)文章從到學(xué)習(xí)介紹從到學(xué)習(xí)上搭建環(huán)境并構(gòu)建運(yùn)行簡(jiǎn)單程序入門從到學(xué)習(xí)配置文件詳解從到學(xué)習(xí)介紹從到學(xué)習(xí)如何自定義從到學(xué)習(xí)介紹從到學(xué)習(xí)如何自定義 showImg(https://segmentfault.com/img/remote/1460000016930071?w=1920&h=1275); 前面文章我們已經(jīng)知道 Flink 是什么東西了,安裝好 Flink 后,我們?cè)賮砜聪掳惭b路徑...
摘要:了解今天誤解挑戰(zhàn)和機(jī)遇,任何關(guān)于的討論最好從了解我們?yōu)槭裁葱枰_始。,近一年前,由云計(jì)算基金會(huì)調(diào)查的的組織使用庫(kù)伯內(nèi)特來管理容器。億美元的價(jià)格再次顯示了庫(kù)伯奈特的流行。此外,最近,這提供了另一個(gè)流行的分布庫(kù)伯奈特。了解Kubernetes今天:誤解、挑戰(zhàn)和機(jī)遇,任何關(guān)于Kubernetes的討論最好從了解我們?yōu)槭裁葱枰狵ubernetes開始。Kubernetes幫助我們管理容器,這些容器現(xiàn)...
閱讀 852·2021-11-24 09:38
閱讀 1059·2021-11-11 11:01
閱讀 3323·2021-10-19 13:22
閱讀 1596·2021-09-22 15:23
閱讀 2914·2021-09-08 09:35
閱讀 2828·2019-08-29 11:31
閱讀 2192·2019-08-26 11:47
閱讀 1625·2019-08-26 11:44