摘要:才云科技云開源高級工程師唐繼元受邀社群,在線分享高級實(shí)踐,介紹如何構(gòu)建環(huán)境。除命令外的停止都是異常停止。
才云科技云開源高級工程師唐繼元受邀DBAplus社群,在線分享《Kubernetes Master High Availability 高級實(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)驗總結(jié),如果有不正確的或者需要改進(jìn)的地方,歡迎各位大神指正。
相信大家對容器、docker和kubernetes這些概念并不陌生。下面進(jìn)入本次分享的正題。
Kubernetes作為容器編排管理系統(tǒng),通過Scheduler、ReplicationController等組件實(shí)現(xiàn)了應(yīng)用層的高可用,但是針對Kubernetes集群,還需要實(shí)現(xiàn)Master組件的高可用。
本次分享論述的Master高可用方案主要基于社區(qū)的高可用方案(鏈接)的實(shí)踐,但是社區(qū)的高可用方案中采用的GCE的External Loadbalancer,并未論述如何實(shí)現(xiàn)External Loadbalancer,而且也并沒有將Kubernetes集群組件容器化。所以,我們的高可用方案在社區(qū)高可用方案的基礎(chǔ)之上進(jìn)行了如下兩個方面的提升:
第一,除了kubelet之外,Kubernetes所有組件容器化;
第二,通過haproxy和keepalived構(gòu)建Loadbalancer實(shí)現(xiàn)Master的高可用。
下面我們分四個章節(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è)私有云平臺,底層采用的是Ubuntu 14.04操作系統(tǒng)。下面是一個典型的部署環(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)它們異常停止的時候由該kubelet負(fù)責(zé)重啟它們。
(haproxy, keepalived):這里表示我們將haproxy和keepalived放置在同一個pod中。
1.1.kubelet對static pod高可用的支持
我們需要為kubelet進(jìn)程配置一個manifests監(jiān)視目錄:
--config=/etc/kubernetes/manifests
如果有新的yaml/manifest文件添加到該目錄,kubelet則根據(jù)yaml/manifest文件創(chuàng)建一個新的static pod;
如果我們把某個yaml/manifest文件從該目錄刪除,kubelet則會刪除由該yaml/manifest文件所產(chǎn)生的static pod;
如果該目錄下的yaml/manifest文件有更新,kubelet則會刪除原來的static pod,而根據(jù)更新后的yaml/manifest文件重新創(chuàng)建一個新的static pod;
如果manifests目錄下的文件沒有任何變化,但是其下某個yaml/manifest文件所產(chǎn)生的static pod錯誤退出或者被誤刪后,kubelet仍然會根據(jù)該yaml/manifest文件重新創(chuàng)建一個新的static pod。
這樣,kubelet在一定程度上保證了static pod的高可用。
1.2.kubelet進(jìn)程的高可用
kubelet通過manifests監(jiān)視目錄保證了staticpod的高可用,但是如果kubelet進(jìn)程本身錯誤退出或者被誤刪后,誰來負(fù)責(zé)重新啟動kubelet進(jìn)程呢?
在Linux系統(tǒng)中,我們可以通過Monit、Upstart、Systemd、Supervisor等工具實(shí)現(xiàn)對服務(wù)的監(jiān)控保證服務(wù)的高可用。
在Ubuntu 14.04操作系統(tǒng)中,我們將kubelet做成系統(tǒng)服務(wù),利用Upstart來保證kubelet服務(wù)的高可用,下面是kubelet服務(wù)基于Upstart的服務(wù)啟動腳本/etc/init/kubelet.conf:
其中:
respawn: 該命令設(shè)置服務(wù)或任務(wù)異常停止時將自動啟動。除stop命令外的停止都是異常停止。
respawn limit: 該命令設(shè)置服務(wù)或任務(wù)異常停止后重啟次數(shù)和間隔時間。
1.3.Master High Availability Kubernetes整體架構(gòu)圖
從架構(gòu)圖中我們可以看到:
1) Upstart保證docker服務(wù)和kubelet服務(wù)的高可用,而Kubernetes的其他組件將以staticpod的方式由kubelet保證高可用。
2)兩臺lb節(jié)點(diǎn)通過haproxy和keepalived構(gòu)建出一個ExternalLoadbalancer,并提供VIP供客戶端訪問。
3) Haproxy配置成“SSLTermination”方式,外網(wǎng)client通過HTTPS請求訪問集群,而內(nèi)網(wǎng)client則可以通過HTTPS/HTTP請求訪問。
4) Kubernetes高可用集群通過flannelstatic pod構(gòu)建一個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請求以特權(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ù)報文。
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ò)是動態(tài)的,我們無法保證docker/flannel網(wǎng)絡(luò)中IP地址的穩(wěn)定性,同時也無法事先知道IP地址。
2) kubeproxy、flannel、haproxy需要通過主機(jī)網(wǎng)絡(luò)修改路由規(guī)則,從而使主機(jī)上的服務(wù)能被其他主機(jī)訪問。
3) haproxy需要將外網(wǎng)請求重定向到內(nèi)網(wǎng)后端服務(wù)器上,也必須需要主機(jī)網(wǎng)絡(luò)。
2.3.External Loadbalancer部署要點(diǎn)
對于如何配置haproxy和keepalived,網(wǎng)絡(luò)上有非常多的資源,所以這里不在論述。下面我們來分析一下部署過程中的一些要點(diǎn)。
External Loadbalancer由至少兩臺lb node組成,通過haproxy和keepalived pod實(shí)現(xiàn)Master的負(fù)載均衡,對外提供統(tǒng)一的VIP。
我們可以將haproxy和keepalived分別放置在不同的pod中,也可以將它們放置在同一個pod中??紤]到keepalived需要監(jiān)測haproxy的狀態(tài),我們會把haproxy和keepalived放在一起做成一個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)核的時候選擇了ipvs的功能,Linux即能支持LVS。因此我們只需要配置操作系統(tǒ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ù)器,每一個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)測haproxy狀態(tài)的方法
對于普通進(jìn)程來說, keepalived進(jìn)程可以通過“killall -0 haproxy”命令檢測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來檢測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對haproxy的狀態(tài)檢測:
vrrp_script check_script { script "/etc/keepalived/check_haproxy.py http://caicloud:[email protected]/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請求到后端的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的配置差不多,除了下面兩個字段:
state BACKUP priority 97
2.4.flannel網(wǎng)絡(luò)設(shè)置
2.4.1Master節(jié)點(diǎn)flannel網(wǎng)絡(luò)設(shè)置
對于Master節(jié)點(diǎn),需要等待Etcd Pod集群啟動完后,先在Master上創(chuàng)建Flannel網(wǎng)絡(luò),然后Flannel Pod客戶端才可以從Etcd中獲取到各個Master節(jié)點(diǎn)的IP網(wǎng)段,獲取到IP網(wǎng)段后會在主機(jī)上產(chǎn)生文件:“/var/run/flannel/subnet.env”,然后根據(jù)該文件修改docker啟動參數(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è)置
對于非Master節(jié)點(diǎn),待Loadbalancer起來之后,Node節(jié)點(diǎn)能夠訪問Apiserver之后,F(xiàn)lannel Pod客戶端才能從Etcd獲取到該Node節(jié)點(diǎn)的IP網(wǎng)段,并且同樣會在主機(jī)上產(chǎn)生文件:“/var/run/flannel/subnet.env”。然后修改docker啟動參數(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”時,真正執(zhí)行的是:“/usr/local/sbin/haproxy -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg -Ds”,對于“-Ds”選項, 官網(wǎng)是這么描述的:
原來,“haproxy”經(jīng)過“haproxy-systemd-wrapper”包裝后在后臺執(zhí)行,而docker container不允許進(jìn)程后臺執(zhí)行,否則docker容器將該啟動命令執(zhí)行完后就退出了。官網(wǎng)image的這個坑很大。
所以,當(dāng)我們用官網(wǎng)“haproxy image”的時候,就需要用haproxy的完全路徑來執(zhí)行。比如在yaml文件中:
3.2.haproxy container exited with 137
首先137退出碼表示,其他進(jìn)程向haproxy container發(fā)起了“kill”信號,導(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”,但是容器卻不退出。
然后,無奈之下,我試著先將這個“WARNING”解決:這個錯誤是由于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)我解決這個“WARNING”之后,奇跡出現(xiàn)了,haproxy container奇跡般的正常運(yùn)行了。原來在容器的世界,一個“WARNING”也不能疏忽。
社區(qū)關(guān)于HA Master的未來發(fā)展熟悉kubelet配置參數(shù)的都知道,我們在給kubelet配置apiserver的時候,可以通過“--api-servers”指定多個:
--api-servers=http://m1b:8080,http://m1c:8080,http://m2a:8080,http://m2b:8080,http://m2c:8080
這看起來似乎已經(jīng)做到apiserver的高可用配置了,但是實(shí)際上當(dāng)?shù)谝粋€apiserver掛掉之后, 不能成功的連接到后面的apiserver,也就是說目前仍然只有第一個apiserver起作用。
如果上述問題解決之后, 似乎不需要額外的loadbalancer也能實(shí)現(xiàn)master的高可用了,但是,除了kubelet需要配置apiserver,controllermanager和scheduler都需要配置apiserver,目前我們還只能通過“--master”配置一個apiserver,無法支持多個apiserver。
社區(qū)后續(xù)打算支持multi-master配置,實(shí)現(xiàn)Kubernetes Master的高可用,而且計劃在Kubernetes 1.4版本中合入。
即使將來社區(qū)實(shí)現(xiàn)了通過multi-master配置的高可用方式,本次分享的MasterHigh Availability仍然非常有意義,因為在私有云場景中,ExternalLoadbalancer除了實(shí)現(xiàn)Master的高可用和負(fù)載均衡外,還可以針對Worker Node實(shí)現(xiàn)Nodeport請求的負(fù)載均衡,從而不僅實(shí)現(xiàn)了應(yīng)用的高可用訪問,同時也大大提高了應(yīng)用的訪問速度和性能。
參考鏈接:
鏈接
鏈接
好了,以上是本次分享的所有內(nèi)容,歡迎大家批評指正,同時也希望能為大家?guī)硇┦找妗?/p>
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/32466.html
摘要:問題是不是定義的一個的容器集群是只部署在同一個主機(jī)上楊樂到目前是,同一個里的是部署在同一臺主機(jī)的。問題這個圖里的是安裝在哪里的所有的客戶端以及會連接這個嘛楊樂可以任意地方,只要能訪問到集群,會作為的出口。 kubernetes1.0剛剛發(fā)布,開源社區(qū)400多位貢獻(xiàn)者一年的努力,多達(dá)14000多次的代碼提交,最終達(dá)到了之前預(yù)計的milestone, 并意味著這個開源容器編排系統(tǒng)可以正式在...
摘要:相關(guān)文章從到學(xué)習(xí)介紹從到學(xué)習(xí)上搭建環(huán)境并構(gòu)建運(yù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 后,我們再來看下安裝路徑...
摘要:了解今天誤解挑戰(zhàn)和機(jī)遇,任何關(guān)于的討論最好從了解我們?yōu)槭裁葱枰_始。,近一年前,由云計算基金會調(diào)查的的組織使用庫伯內(nèi)特來管理容器。億美元的價格再次顯示了庫伯奈特的流行。此外,最近,這提供了另一個流行的分布庫伯奈特。了解Kubernetes今天:誤解、挑戰(zhàn)和機(jī)遇,任何關(guān)于Kubernetes的討論最好從了解我們?yōu)槭裁葱枰狵ubernetes開始。Kubernetes幫助我們管理容器,這些容器現(xiàn)...
閱讀 820·2021-11-24 09:38
閱讀 1028·2021-11-11 11:01
閱讀 3282·2021-10-19 13:22
閱讀 1565·2021-09-22 15:23
閱讀 2865·2021-09-08 09:35
閱讀 2800·2019-08-29 11:31
閱讀 2155·2019-08-26 11:47
閱讀 1596·2019-08-26 11:44