Kubernetes Master High Availability 高級實踐

才云科技云開源高級工程師唐繼元受邀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環境的搭建。

  1. HA Master整體架構

  2. 核心技術點和難點

  3. 實踐中的遇到的那些坑

  4. 社區關于HA Master的未來發展

HA Master整體架構

我們已經成功將支持Master High Availability的Kubernetes集群部署到企業私有云平臺,底層采用的是Ubuntu 14.04操作系統。下面是一個典型的部署環境:

clipboard.png

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:

clipboard.png

其中:
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_statsbind  0.0.0.0:80log  globalmode  httpmaxconn  10stats  enable#Hide  HAPRoxy version, a necessity for any public-facing sitestats  hide-versionstats  refresh 30sstats  show-nodestats  realm Haproxy\ Statisticsstats  auth caicloud:caicloudstats  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 secondsweight 5fall 2 # require 2 fail for KOrise 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 SSLbind  *:443 ssl crt /etc/kubernetes/master-loadblancer.pemoption  forwardfordefault_backend  backend-apiserver-http

2.3.4.haproxy配置:haproxy.cfg

clipboard.png
clipboard.png

2.3.5.keepalived配置:keepalived.conf
1) lb-1上keepalived配置

clipboard.png
clipboard.png

2) lb-2上keepalived配置
lb-2跟lb-1的配置差不多,除了下面兩個字段:

 state BACKUPpriority 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.實踐中的遇到的那些坑

3.1.官網“haproxy docker image”的坑
Docker Hub上“haproxy image”的“docker-entrypoint.sh”內容如下:

clipboard.png

問題就出在“haproxy-systemd-wrapper”。如果運行命令:“haproxy -f/etc/haproxy/haproxy.cfg”, 而實際上運行的是經過“haproxy-systemd-wrapper”包裝后的命令:

clipboard.png

執行命令“haproxy -f /etc/haproxy/haproxy.cfg”時,真正執行的是:“/usr/local/sbin/haproxy -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg -Ds”,對于“-Ds”選項, 官網是這么描述的:

clipboard.png

原來,“haproxy”經過“haproxy-systemd-wrapper”包裝后在后臺執行,而docker container不允許進程后臺執行,否則docker容器將該啟動命令執行完后就退出了。官網image的這個坑很大。
所以,當我們用官網“haproxy image”的時候,就需要用haproxy的完全路徑來執行。比如在yaml文件中:

clipboard.png

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 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...

當我解決這個“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://www.pswp.cn/news/543024.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/543024.shtml
英文地址,請注明出處:http://en.pswp.cn/news/543024.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pythonmysqldb_python中MySQLdb的使用

基本的使用如上,還是很簡單的,進一步使用還沒操作,先從網上找點資料放上來,以備后續查看1.引入MySQLdb庫import MySQLdb2.和數據庫建立連接connMySQLdb.connect(host"localhost",user"root",passwd"sa&q…

分布式系統的唯一ID

2019獨角獸企業重金招聘Python工程師標準>>> 需求 為什么需要唯一ID 讓分布式系統中的需要辨別的元素,都能有唯一的辨識標志。 幾乎所有的業務系統,都有生成一個記錄標識的需求,例如: 消息標識:message-id訂…

python程序跨平臺桌面_Python中的跨平臺桌面通知程序

在2010年的Pycon大會上有一個presentation on cross-platform Python development。還有一個關于它的html頁面,其中包含一些跨平臺通知的建議。但是,我在網上找不到它了,但我保存了一個本地副本,這是關于通知的部分:Th…

python去掉html標簽_python 去除html標簽的幾種方法

#! /usr/bin/python# -*- coding:utf-8 -*-created on 2013-12-18author: javaimport refrom htmlparser import htmlparserclass filtertag():def __init__(self):passdef filterhtmltag(self,htmlstr):過濾html中的標簽:param htmlstr:html字符串 或是網頁源碼self.htmlstr …

檢查字符串是否包含數字的Python程序

Given a string and we have to check whether it contains only digits or not in Python. 給定一個字符串,我們必須檢查它在Python中是否僅包含數字。 To check that a string contains only digits (or a string has a number) – we can use isdigit() functio…

android放微信@功能,Android仿微信語音消息的錄制和播放功能

一、簡述效果:實現功能:長按Button時改變Button顯示文字,彈出Dialog(動態更新音量),動態生成錄音文件,開始錄音;監聽手指動作,規定區域。錄音狀態下手指劃出規定區域取消錄音,刪除生…

Golang Clearing slice

//first method :slice nil// second method :slice slice[0:0]Source page : https://www.socketloop.com/tutorials/golang-clearing-slice轉載于:https://www.cnblogs.com/Jim-william/p/5630096.html

python multithreading_操作系統OS,Python - 多進程(multiprocessing)、多線程(multithreading)...

多進程(multiprocessing)參考:1. 多進程概念multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping …

微信 android兼容性問題怎么解決方案,微信小程序兼容性問題

本文我們來談談微信小程序系統兼容性的那些坑。微信小程序兼容性問題微信小程序發布一周多了,兼容性問題,特別是 Android 平臺兼容性問題特別嚴重。據我觀察,好多小程序掉到兼容性的坑里。掉坑里不要緊,更讓人捉急的是&#xff0c…

sap中泰國有預扣稅設置嗎_泰國的繪圖標志| Python中的圖像處理

sap中泰國有預扣稅設置嗎A colored image can be represented as a 3 order matrix. The first order is for the rows, the second order is for the columns and the third order is for specifying the color of the corresponding pixel. Here we use the BGR color format…

Attach Volume 操作(Part II) - 每天5分鐘玩轉 OpenStack(54)

上一節我們討論了 attach volume 操作中 cinder-api 的工作,本節討論 cinder-volume 和 nova-compute 如何將 volume attach 到 Instance。 cinder-volume 初始化 volume 的連接 cinder-volume 接收到 initialize_connection 消息后,會通過 tgt 創建 ta…

python編碼示例_python urllib中的編碼處理示例

復制代碼 代碼如下:>>> import urllib>>> data 麗江>>> print data麗江>>> data\xe4\xb8\xbd\xe6\xb1\x9f>>> urllib.quote(data)%E4%B8%BD%E6%B1%9F那我們想轉回去呢?復制代碼 代碼如下:>>> urllib.unquot…

android 網絡程序下載,Android之網絡文件下載

環境搭建:本地服務器(下載wamp【Windows, Apache, MySQL, PHP 】,安裝即可,然后將網頁或文件放進 www directory)虛擬機(訪問本地服務器的ip:10.0.2.2)注意事項:權限相關網絡訪問 存儲卡訪問 文件權限 如:c…

FMDB的介紹

2019獨角獸企業重金招聘Python工程師標準>>> FMDB方法的介紹 1.首先我們需要創建一個FMDatabase實例: (FMDatabase*)DataBaseSigonInstance { //數據庫初始化 NSString *homeDir NSHomeDirectory(); //NSLog("%",homeDir); NSString *dbPath …

python 打印列表元素_Python程序以不同方式打印列表元素

python 打印列表元素In this program – we are going to learn how can we print all list elements, print specific elements, print a range of the elements, print list multiple times (using * operator), print multiple lists by concatenating them, etc. 在此程序中…

網絡克隆軟件_網文生成器,克隆的是騙錢“病毒”

文章克隆器頁面。圖據北京晚報如今不論男女老少,多半喜歡用手機收集信息、瀏覽自己關注的話題。有的時候,人們會發現,不少親朋發來的鏈接或者公眾號推送的文章,長得特別像,但多少有那么些微不同。其實,不是…

c#讀取指定字符后的字符_在C#中讀取字符的不同方法

c#讀取指定字符后的字符As we know that, Console.ReadLine() is used for input in C#, it actually reads a string and then we convert or parse it to targeted type. 眾所周知, Console.ReadLine()用于C#中的輸入,它實際上是讀取一個字…

使用python 對圖片進行水印,保護自己寫的文章

1,關于文章被爬 說起來挺桑心的,好不容易寫的文章,被爬走。 用個搜索引擎搜索都不是在第一位,寫的文章全給這些網站提供流量了。 這種網站還居多廣告。 還是抱怨少點吧。csdn對于這些事情也是無所作為啊。 最起碼的防盜鏈也不…

r語言descstats_一條命令輕松繪制CNS頂級配圖-ggpubr

Hadley Wickham創建的可視化包ggplot2可以流暢地進行優美的可視化,但是如果要通過ggplot2定制一套圖形,尤其是適用于雜志期刊等出版物的圖形,對于那些沒有深入了解ggplot2的人來說就有點困難了,ggplot2的部分語法是很晦澀的。為此…

android layout_width 屬性,android:layout_weight屬性詳解

在android開發中LinearLayout很常用,LinearLayout的內控件的android:layout_weight在某些場景顯得非常重要,比如我們需要按比例顯示。android并沒用提供table這樣的控件,雖然有TableLayout,但是它并非是我們想象中的像html里面的t…