摘要:才云科技云開源高級工程師唐繼元受邀社群,在線分享高級實踐,介紹如何構建環境。除命令外的停止都是異常停止。
才云科技云開源高級工程師唐繼元受邀DBAplus社群,在線分享《Kubernetes Master High Availability 高級實踐》,介紹如何構建Kubernetes Master High Availability環境。
以下是分享實錄:
大家好,我是才云科技的唐繼元,今天給大家帶來一篇技術分享,本次分享我將為大家介紹如何構建Kubernetes Master High Availability環境。此次分享內容是我在工作中經驗總結,如果有不正確的或者需要改進的地方,歡迎各位大神指正。
相信大家對容器、docker和kubernetes這些概念并不陌生。下面進入本次分享的正題。
Kubernetes作為容器編排管理系統,通過Scheduler、ReplicationController等組件實現了應用層的高可用,但是針對Kubernetes集群,還需要實現Master組件的高可用。
本次分享論述的Master高可用方案主要基于社區的高可用方案(鏈接)的實踐,但是社區的高可用方案中采用的GCE的External Loadbalancer,并未論述如何實現External Loadbalancer,而且也并沒有將Kubernetes集群組件容器化。所以,我們的高可用方案在社區高可用方案的基礎之上進行了如下兩個方面的提升:
第一,除了kubelet之外,Kubernetes所有組件容器化;
第二,通過haproxy和keepalived構建Loadbalancer實現Master的高可用。
下面我們分四個章節來詳細論述Kubernetes Master High Availability環境的搭建。
HA Master整體架構
核心技術點和難點
實踐中的遇到的那些坑
社區關于HA Master的未來發展
HA Master整體架構我們已經成功將支持Master High Availability的Kubernetes集群部署到企業私有云平臺,底層采用的是Ubuntu 14.04操作系統。下面是一個典型的部署環境:
Static Pods是由其所在節點上的kubelet直接管理,而不需要通過Apiserver來監視它們。Static Pods的資源類型只能是Pod,而且不與任何的Replication Controller相關聯,它們完全由kubelet來監視,并且當它們異常停止的時候由該kubelet負責重啟它們。
(haproxy, keepalived):這里表示我們將haproxy和keepalived放置在同一個pod中。
1.1.kubelet對static pod高可用的支持
我們需要為kubelet進程配置一個manifests監視目錄:
--config=/etc/kubernetes/manifests
如果有新的yaml/manifest文件添加到該目錄,kubelet則根據yaml/manifest文件創建一個新的static pod;
如果我們把某個yaml/manifest文件從該目錄刪除,kubelet則會刪除由該yaml/manifest文件所產生的static pod;
如果該目錄下的yaml/manifest文件有更新,kubelet則會刪除原來的static pod,而根據更新后的yaml/manifest文件重新創建一個新的static pod;
如果manifests目錄下的文件沒有任何變化,但是其下某個yaml/manifest文件所產生的static pod錯誤退出或者被誤刪后,kubelet仍然會根據該yaml/manifest文件重新創建一個新的static pod。
這樣,kubelet在一定程度上保證了static pod的高可用。
1.2.kubelet進程的高可用
kubelet通過manifests監視目錄保證了staticpod的高可用,但是如果kubelet進程本身錯誤退出或者被誤刪后,誰來負責重新啟動kubelet進程呢?
在Linux系統中,我們可以通過Monit、Upstart、Systemd、Supervisor等工具實現對服務的監控保證服務的高可用。
在Ubuntu 14.04操作系統中,我們將kubelet做成系統服務,利用Upstart來保證kubelet服務的高可用,下面是kubelet服務基于Upstart的服務啟動腳本/etc/init/kubelet.conf:
其中:
respawn: 該命令設置服務或任務異常停止時將自動啟動。除stop命令外的停止都是異常停止。
respawn limit: 該命令設置服務或任務異常停止后重啟次數和間隔時間。
1.3.Master High Availability Kubernetes整體架構圖
從架構圖中我們可以看到:
1) Upstart保證docker服務和kubelet服務的高可用,而Kubernetes的其他組件將以staticpod的方式由kubelet保證高可用。
2)兩臺lb節點通過haproxy和keepalived構建出一個ExternalLoadbalancer,并提供VIP供客戶端訪問。
3) Haproxy配置成“SSLTermination”方式,外網client通過HTTPS請求訪問集群,而內網client則可以通過HTTPS/HTTP請求訪問。
4) Kubernetes高可用集群通過flannelstatic pod構建一個Overlay網絡,使集群中的docker容器能夠通過Kubernetes Cluster IP進行通信。
2.1.運行在特權模式的組件
Kubernetes集群中的一些組件需要通過內核模塊來為集群提供服務,因此這些組件需要運行在特權模式下,以便能訪問相應的內核模塊。
2.1.1.開啟特權模式
為了支持docker容器在特權模式下運行,我們需要開啟Kubernetes集群的特權模式權限:
--allow-privileged=true
這里主要體現在kubelet服務和apiserver服務。
1) Kubelet service
kubelet服務需要開啟特權模式權限,以便允許docker容器向kubelet請求以特權模式運行。
2) Apiserver static pod
apiserver static pod需要開啟特權模式權限,以便運行在特權模式下的docker容器能夠訪問apiserver服務。
2.1.2.運行在特權模式下的docker容器
運行在特權模式下的docker容器,在yaml文件中需要添加如下字段:
securityContext: privileged: true
這里主要體現在kubeproxy服務、flannel服務和keepalived服務。
1) Kubeproxy static pod
kubeproxy需要通過Iptables設置防火墻規則。
2) Flannel static pod
flannel需要訪問vxlan、openvswitch等路由數據報文。
3) Keepalived static pod
keepalived需要訪問IP_VS內核模塊來建立VIP。
2.2.Static pod必須運行在主機網絡下
如上所述的這些以static pod形式存在的Kubernetes集群組件,必須工作在主機網絡下:
hostNetwork: true
雖然Overlay網絡是為了讓不同節點間的docker容器進行通信,而上述以staticpod形式存在的組件也都是docker容器,但是它們之間的心跳和信息交流都需要通過主機網絡而不是類似于flannel等的Overlay網絡。理由如下:
1)這些static pods不同于應用的pods,它們的穩定保障了Kubernetes集群的穩定性,它們之間的心跳和信息交流都是通過它們配置文件中的靜態IP地址進行的,而docker/flannel網絡是動態的,我們無法保證docker/flannel網絡中IP地址的穩定性,同時也無法事先知道IP地址。
2) kubeproxy、flannel、haproxy需要通過主機網絡修改路由規則,從而使主機上的服務能被其他主機訪問。
3) haproxy需要將外網請求重定向到內網后端服務器上,也必須需要主機網絡。
2.3.External Loadbalancer部署要點
對于如何配置haproxy和keepalived,網絡上有非常多的資源,所以這里不在論述。下面我們來分析一下部署過程中的一些要點。
External Loadbalancer由至少兩臺lb node組成,通過haproxy和keepalived pod實現Master的負載均衡,對外提供統一的VIP。
我們可以將haproxy和keepalived分別放置在不同的pod中,也可以將它們放置在同一個pod中。考慮到keepalived需要監測haproxy的狀態,我們會把haproxy和keepalived放在一起做成一個loadbalancerpod。
2.3.1.lb node配置
1)使能內核IPVS模塊
由于keepalived需要通過IPVS模塊實現路由轉發,所以我們需要使能內核IPVS模塊。
從Linux內核版本2.6起,ip_vs code已經被整合進了內核中,因此,只要在編譯內核的時候選擇了ipvs的功能,Linux即能支持LVS。因此我們只需要配置操作系統啟動時自動加載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)修改內核參數
為了使keepalived將數據包轉發到真實的后端服務器,每一個lb node都需要開啟IP轉發功能
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
另外,keepalived設置的VIP有可能為非本地IP地址,所以我們還需要使能非本地IP地址綁定功能:
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
2.3.2.keepalived監測haproxy狀態的方法
對于普通進程來說, keepalived進程可以通過“killall -0 haproxy”命令檢測haproxy進程是否正常運行(注: Sending the signal 0 to a given PID just checksif any process with the given PID is running)。
然而在docker容器環境下,各容器都有自己的PidNamespace和NetworkNamespace,我們就需要開啟haproxy的健康檢查頁面,然后keepalived通過健康檢查頁面的URL來檢測haproxy目前是否正常運行。
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的狀態檢測:
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服務器走正常的http協議;
2) haproxy本身只提供代理,直接轉發client端的HTTPS請求到后端的web服務器。注意:這種模式下“mode”必須是“tcp”模式, 即僅支持4層代理。
考慮到:第一,用戶親和性訪問需要7層代理的支持;第二,loadbalancer和master走的都是集群內網。所以本實踐采用了第一種方式,配置如下:
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網絡設置
2.4.1Master節點flannel網絡設置
對于Master節點,需要等待Etcd Pod集群啟動完后,先在Master上創建Flannel網絡,然后Flannel Pod客戶端才可以從Etcd中獲取到各個Master節點的IP網段,獲取到IP網段后會在主機上產生文件:“/var/run/flannel/subnet.env”,然后根據該文件修改docker啟動參數:
. /var/run/flannel/subnet.env DOCKER_OPTS="$DOCKER_OPTS --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}"
并重啟docker服務。
2.4.2非Master節點flannel網絡設置
對于非Master節點,待Loadbalancer起來之后,Node節點能夠訪問Apiserver之后,Flannel Pod客戶端才能從Etcd獲取到該Node節點的IP網段,并且同樣會在主機上產生文件:“/var/run/flannel/subnet.env”。然后修改docker啟動參數,并重啟docker服務。
3.1.官網“haproxy docker image”的坑
Docker Hub上“haproxy image”的“docker-entrypoint.sh”內容如下:
問題就出在“haproxy-systemd-wrapper”。如果運行命令:“haproxy -f/etc/haproxy/haproxy.cfg”, 而實際上運行的是經過“haproxy-systemd-wrapper”包裝后的命令:
執行命令“haproxy -f /etc/haproxy/haproxy.cfg”時,真正執行的是:“/usr/local/sbin/haproxy -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg -Ds”,對于“-Ds”選項, 官網是這么描述的:
原來,“haproxy”經過“haproxy-systemd-wrapper”包裝后在后臺執行,而docker container不允許進程后臺執行,否則docker容器將該啟動命令執行完后就退出了。官網image的這個坑很大。
所以,當我們用官網“haproxy image”的時候,就需要用haproxy的完全路徑來執行。比如在yaml文件中:
3.2.haproxy container exited with 137
首先137退出碼表示,其他進程向haproxy container發起了“kill”信號,導致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.
其次,當通過“docker run”命令執行haproxy container,使用的命令與yaml文件中的一樣,而且照樣輸出上述的“WARNING”,但是容器卻不退出。
然后,無奈之下,我試著先將這個“WARNING”解決:這個錯誤是由于haproxy.cfg中添加了SSL證書導致的, 可以通過設置參數“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 ...
當我解決這個“WARNING”之后,奇跡出現了,haproxy container奇跡般的正常運行了。原來在容器的世界,一個“WARNING”也不能疏忽。
社區關于HA Master的未來發展熟悉kubelet配置參數的都知道,我們在給kubelet配置apiserver的時候,可以通過“--api-servers”指定多個:
--api-servers=http://m1b:8080,http://m1c:8080,http://m2a:8080,http://m2b:8080,http://m2c:8080
這看起來似乎已經做到apiserver的高可用配置了,但是實際上當第一個apiserver掛掉之后, 不能成功的連接到后面的apiserver,也就是說目前仍然只有第一個apiserver起作用。
如果上述問題解決之后, 似乎不需要額外的loadbalancer也能實現master的高可用了,但是,除了kubelet需要配置apiserver,controllermanager和scheduler都需要配置apiserver,目前我們還只能通過“--master”配置一個apiserver,無法支持多個apiserver。
社區后續打算支持multi-master配置,實現Kubernetes Master的高可用,而且計劃在Kubernetes 1.4版本中合入。
即使將來社區實現了通過multi-master配置的高可用方式,本次分享的MasterHigh Availability仍然非常有意義,因為在私有云場景中,ExternalLoadbalancer除了實現Master的高可用和負載均衡外,還可以針對Worker Node實現Nodeport請求的負載均衡,從而不僅實現了應用的高可用訪問,同時也大大提高了應用的訪問速度和性能。
參考鏈接:
鏈接
鏈接
好了,以上是本次分享的所有內容,歡迎大家批評指正,同時也希望能為大家帶來些收益。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/32466.html
摘要:問題是不是定義的一個的容器集群是只部署在同一個主機上楊樂到目前是,同一個里的是部署在同一臺主機的。問題這個圖里的是安裝在哪里的所有的客戶端以及會連接這個嘛楊樂可以任意地方,只要能訪問到集群,會作為的出口。 kubernetes1.0剛剛發布,開源社區400多位貢獻者一年的努力,多達14000多次的代碼提交,最終達到了之前預計的milestone, 并意味著這個開源容器編排系統可以正式在...
摘要:相關文章從到學習介紹從到學習上搭建環境并構建運行簡單程序入門從到學習配置文件詳解從到學習介紹從到學習如何自定義從到學習介紹從到學習如何自定義 showImg(https://segmentfault.com/img/remote/1460000016930071?w=1920&h=1275); 前面文章我們已經知道 Flink 是什么東西了,安裝好 Flink 后,我們再來看下安裝路徑...
摘要:了解今天誤解挑戰和機遇,任何關于的討論最好從了解我們為什么需要開始。,近一年前,由云計算基金會調查的的組織使用庫伯內特來管理容器。億美元的價格再次顯示了庫伯奈特的流行。此外,最近,這提供了另一個流行的分布庫伯奈特。了解Kubernetes今天:誤解、挑戰和機遇,任何關于Kubernetes的討論最好從了解我們為什么需要Kubernetes開始。Kubernetes幫助我們管理容器,這些容器現...
閱讀 796·2021-11-24 09:38
閱讀 998·2021-11-11 11:01
閱讀 3236·2021-10-19 13:22
閱讀 1524·2021-09-22 15:23
閱讀 2828·2021-09-08 09:35
閱讀 2766·2019-08-29 11:31
閱讀 2119·2019-08-26 11:47
閱讀 1563·2019-08-26 11:44