后Kubernetes時(shí)代,帶你系統(tǒng)梳理K8S 12大關(guān)鍵特性
導(dǎo)讀:
Kubernetes如今風(fēng)靡一時(shí),所有主要的云服務(wù)提供商都將其作為部署云原生應(yīng)用的解決方案。Kubernetes有哪些顯著的特性和工具優(yōu)勢,讓企業(yè)開始接受它?本文作者給出了系統(tǒng)的梳理。
“Action without orchestration is burn out; orchestration w/o action is management.”
沒有編排的行動(dòng)是完蛋的,沒有行動(dòng)的編排是管理,行動(dòng)加上編排是領(lǐng)導(dǎo)。― Orrin Woodward”
- Kubernetes是一種優(yōu)化資源利用率的抽象概念,它允許跨節(jié)點(diǎn)集群高效地進(jìn)行應(yīng)用程序分發(fā)。
- Kubernetes,舵手 !
- Kubernetes是一個(gè)希臘語單詞,意思是“舵手”。
它是一個(gè)由谷歌開始的開源項(xiàng)目,從Borg衍生而來,在谷歌內(nèi)部使用了好幾年,現(xiàn)在用于容器管理。目前由CNCF托管。
Kubernetes(縮寫為K8S)是一種抽象,它通過容器來優(yōu)化CPU和內(nèi)存等資源的利用率,從而可以跨多個(gè)節(jié)點(diǎn)高效地進(jìn)行應(yīng)用程序分發(fā)。K8S可以在裸金屬或任何云基礎(chǔ)設(shè)施提供商的任何地方運(yùn)行。這個(gè)新工具是云無關(guān)的,聚焦于在基礎(chǔ)設(shè)施內(nèi)部部署和調(diào)度容器,而不是直接利用節(jié)點(diǎn)/主機(jī)。
K8S提供的一些平臺特性是:
- 使用pod進(jìn)行容器分組
- 自愈
- 自動(dòng)伸縮
- DNS管理
- 負(fù)載均衡
- 滾動(dòng)更新或回滾
- 資源監(jiān)控和日志記錄
Kubernetes 架構(gòu)

Kubernetes集群由主節(jié)點(diǎn)和一組worker/從屬節(jié)點(diǎn)組成。
Kubernetes的主節(jié)點(diǎn)組成部分是:
- API服務(wù)器(API Server):用戶通過Rest操作或kubectl cli與manifestyaml交互。它用于所有與API對象相關(guān)的操作,如pod創(chuàng)建,它是在etcd中存儲所需狀態(tài)的***組件。
- 調(diào)度器(Scheduler):用戶使用kubectl cli向API服務(wù)器發(fā)出一個(gè)命令來創(chuàng)建pod。在執(zhí)行此操作之后,調(diào)度程序根據(jù)資源需求將pods分配給可用節(jié)點(diǎn)。
- 控制器管理器(Controller Manager):控制器管理器基于集群狀態(tài)對資源進(jìn)行操作,并根據(jù)清單yaml進(jìn)行更改,將當(dāng)前狀態(tài)應(yīng)用程序達(dá)到所需狀態(tài)。換句話說,控制器管理器可以將實(shí)際狀態(tài)與所需的狀態(tài)進(jìn)行協(xié)調(diào)。在控制器管理器中有多個(gè)專用的控制器,以便簡化集群管理。例如,節(jié)點(diǎn)控制器檢查是否有當(dāng)前正在運(yùn)行的節(jié)點(diǎn)停機(jī),并采取糾正措施,而復(fù)制控制器確保在節(jié)點(diǎn)中實(shí)際運(yùn)行所需的pod數(shù)量。
- etcd:所有關(guān)于集群狀態(tài)的配置信息都以key/value對的形式存儲在etcd中,這個(gè)組件由CoreOS實(shí)現(xiàn)。這些狀態(tài)顯示了集群中包含的節(jié)點(diǎn)和需要在其中運(yùn)行的pods。
- 插件(Addons):為了將服務(wù)器DNS記錄添加到Kubernetes,我們需要一個(gè)集群DNS 插件。該插件有助于擴(kuò)展與Kubernetes集群或節(jié)點(diǎn)相關(guān)的功能。還有許多其他的插件,比如用于日志記錄的fluntd、基于角色訪問的rbac等等。
安裝在Kubernetes節(jié)點(diǎn)中的組件是:
- Docker: Docker守護(hù)進(jìn)程在每個(gè)節(jié)點(diǎn)中運(yùn)行。如果容器鏡像不存在,那么它將從docker注冊中提取并運(yùn)行。
- Kubelet: Kubelet節(jié)點(diǎn)代理定期檢查容器內(nèi)容器的健康狀況。此外,它還確保按manifest安裝卷,并下載運(yùn)行容器所需的敏感信息。它還將節(jié)點(diǎn)鏈接到API服務(wù)器。
- Kube-proxy: Kube-proxy在每個(gè)節(jié)點(diǎn)上運(yùn)行,以便在pod中進(jìn)行負(fù)載分配,并為外部主機(jī)提供可用的服務(wù)。它使用iptable規(guī)則或輪詢調(diào)度來將請求轉(zhuǎn)發(fā)到正確的容器。
對于高可用和容錯(cuò)的Kubernetes生產(chǎn)和部署,需要多個(gè)主節(jié)點(diǎn)和一個(gè)單獨(dú)的etcd集群。如果運(yùn)行了三個(gè)API服務(wù)器,則需要一個(gè)網(wǎng)絡(luò)負(fù)載平衡器來正確地將負(fù)載分配到服務(wù)器。***剩下的問題是需要三個(gè)角色來管理控制器管理器和調(diào)度器以維護(hù)集群狀態(tài)和分配節(jié)點(diǎn)。為了更高效、更可靠地執(zhí)行它,只有一個(gè)參與者應(yīng)該執(zhí)行實(shí)際的更改,但是在機(jī)器宕機(jī)的情況下仍然需要其他實(shí)例。為了解決這個(gè)問題,我們可以在API中使用lease-lock 來執(zhí)行主選,而使用它的標(biāo)志是leader- elect。
Kubernetes通過以下任一種方式實(shí)現(xiàn)從Pod到Pod的聯(lián)網(wǎng):
- 第2層(切換解決方案)
- 第3層(橋接解決方案)
- overlay解決方案(weave andflannel)
它們允許在集群中進(jìn)行Pod和Pod之間的通信,并為每個(gè)Pod提供***的IP地址。
Kubernetes關(guān)鍵特性
Pod: Collection of Containers容器集

pod是K8S中的一個(gè)部署單元,它有一個(gè)單獨(dú)的IP地址。在它內(nèi)部,Pause容器通過持有一個(gè)網(wǎng)絡(luò)的名稱空間、端口和ip地址來處理網(wǎng)絡(luò),而這個(gè)地址又被pod中的所有容器使用。
ReplicationController

ReplicationController確保在給定的時(shí)間內(nèi)啟動(dòng)和運(yùn)行所需的容器數(shù)量。Pod模板用于定義容器鏡像標(biāo)識符、端口和標(biāo)簽。使用liveness probes,它可以自動(dòng)治愈pods,并按照期望的狀態(tài)維持pods數(shù)量。也可以通過使用kubectl來手動(dòng)控制副本計(jì)數(shù)。
存儲管理
Pods本質(zhì)是短暫的——任何儲存在pod或容器中的信息都會丟失。為了存儲數(shù)據(jù),一個(gè)持久的系統(tǒng)是必需的,即使在一個(gè)pod被殺死或重新調(diào)度之后,如Amazon Elastic Block Storage (EBS),谷歌GCE PD,或一個(gè)分布式文件系統(tǒng),如網(wǎng)絡(luò)文件系統(tǒng)(NFS)或Gluster文件系統(tǒng)(GFS)。
資源監(jiān)控

監(jiān)控是成功運(yùn)行基礎(chǔ)設(shè)施的關(guān)鍵之一,它是可靠性等級的基礎(chǔ)。Heapster是一個(gè)從kubelet收集指標(biāo)的插件,與cAdvisor集成。cAdvisor用于收集與運(yùn)行容器的CPU、內(nèi)存、I/O和網(wǎng)絡(luò)統(tǒng)計(jì)數(shù)據(jù)相關(guān)的指標(biāo)。由Heapster收集的數(shù)據(jù)存儲在influx DB中,并使用Grafana在UI中顯示。還有其他可使用的接收器,如Kafka或Elastic Search,可以用于存儲數(shù)據(jù)并顯示在用戶界面中。
健康檢查
kubernetes的健康檢查由kubelet代理完成。它分為liveness 和 readiness probes兩種。
處理程序主要有三種類型:
- ExecAction:執(zhí)行Shell命令,如果生成的退出代碼為0,則意味著實(shí)例是健康的。在任何其他情況下,實(shí)例不健康。
- TCPAction: Kubelet將嘗試連接到指定的端口,如果它建立到給定socket的連接,診斷成功。
- HTTPGetAction:基于應(yīng)用程序公開的HTTP端點(diǎn),kubelet對指定路徑上的容器IP地址執(zhí)行HTTP GET請求,如果返回200到300個(gè)響應(yīng)代碼,診斷就成功了。
每個(gè)probe通常有三個(gè)結(jié)果:
- 成功:容器通過診斷。
- 失敗:容器未通過診斷。
- 未知:診斷失敗,不要采取任何行動(dòng)。
水平自動(dòng)伸縮功能
自動(dòng)伸縮使用基于負(fù)載的計(jì)算資源。K8S scale pod自動(dòng)使用Horizontal Pod Autoscaler對象,從Heapster獲取度量數(shù)據(jù),并相應(yīng)地減少或增加pod的數(shù)量。例如,如果自動(dòng)伸縮是基于內(nèi)存利用率,那么控制器就會開始在pod中觀察內(nèi)存使用情況,并根據(jù)容量對該副本計(jì)數(shù)進(jìn)行擴(kuò)展。
服務(wù)發(fā)現(xiàn)
Kubernetes pods是短暫的,ReplicationController 在任何節(jié)點(diǎn)上動(dòng)態(tài)創(chuàng)建它們,因此在集群中發(fā)現(xiàn)服務(wù)是一個(gè)挑戰(zhàn)。服務(wù)需要發(fā)現(xiàn)一個(gè)IP地址和動(dòng)態(tài)的端口,以便在集群中進(jìn)行通信。
有兩種主要的方法來找到它——環(huán)境變量(Environment variables)和DNS。
更可取的是基于DNS的服務(wù)發(fā)現(xiàn),它可以作為集群附加組件使用。跟蹤集群中的新服務(wù),并為每個(gè)服務(wù)創(chuàng)建一組DNS記錄。
網(wǎng)絡(luò)
要完全管理集群,必須正確設(shè)置網(wǎng)絡(luò),并解決三個(gè)網(wǎng)絡(luò)問題:
- 容器到容器的通信:pods通過本地主機(jī)通信,并使用Pause容器網(wǎng)絡(luò)名稱空間,解決這個(gè)問題。
- Pod-to-Pod通信:由軟件定義的網(wǎng)絡(luò)解決,如上面架構(gòu)圖所示。
- 外部到pod通信:由服務(wù)覆蓋。
Kubernetes提供了廣泛的網(wǎng)絡(luò)選擇?,F(xiàn)在還支持容器網(wǎng)絡(luò)接口(CNI)插件,這是容器的通用插件架構(gòu)。目前支持多種編排工具,如Kubernetes、Mesos和CloudFoundry。
有各種覆蓋插件:
- Flannel來自CoreOS,是一個(gè)非常簡單的etcd后端覆蓋網(wǎng)絡(luò)。它創(chuàng)建了另一個(gè)虛擬的、可路由的IP / Pod網(wǎng)絡(luò),運(yùn)行在底層網(wǎng)絡(luò)之上;ergo,稱為覆蓋網(wǎng)絡(luò)。在這個(gè)覆蓋網(wǎng)絡(luò)中,每個(gè)Pod將被分配一個(gè)IP地址,并且會直接使用它們的IP進(jìn)行通信。
- Weave通過CNI插件提供與Kubernetes兼容的覆蓋網(wǎng)絡(luò)。
服務(wù)
Kubernetes服務(wù)是一種抽象,它將通信路由到一組pod,以提供一個(gè)微服務(wù)。Kube-proxy在每個(gè)節(jié)點(diǎn)上運(yùn)行,并通過設(shè)置一組iptable規(guī)則來管理服務(wù)。
設(shè)立服務(wù)的模式有三種:
- ClusterIP(只提供內(nèi)部訪問)
- NodePort(需要在端口上打開防火墻;不建議公開訪問)
- 負(fù)載均衡器(由AWS或GKE等公有云供應(yīng)商擁有)
ConfigMap和Secret
ConfigMap使注入基于環(huán)境的配置成為可能,同時(shí)使容器鏡像在多個(gè)環(huán)境中保持一致。這些可以通過安裝卷或環(huán)境變量(environment variables)來注入,并將這些值存儲在key/value格式中。
Secrets用于存儲敏感數(shù)據(jù),如密碼、OAuth令牌等。
滾動(dòng)部署和回滾
部署對象持有一個(gè)或多個(gè)副本集,以支持回滾機(jī)制。換句話說,每次更改部署配置時(shí)都會創(chuàng)建一個(gè)新的副本集,并保留以前的版本,以便有回滾選項(xiàng)。只有一個(gè)副本集將在特定時(shí)間處于活動(dòng)狀態(tài)。
對于滾動(dòng)部署,需要的策略類型是RollingUpdate和minReadySecs,它指定應(yīng)用程序?yàn)榉?wù)流量所花費(fèi)的時(shí)間。如果在應(yīng)用程序pod還沒有準(zhǔn)備好時(shí),將其保持默認(rèn)狀態(tài),它將不可用。這個(gè)動(dòng)作可以通過以下命令來完成:

或者,
通過替換部署yaml文件中的內(nèi)容并運(yùn)行以下命令:

如果新版本不像預(yù)期的那樣,那么可以通過運(yùn)行以下命令回滾到以前的版本:

如果所需版本是前一版本以外的版本,則運(yùn)行:

Logging 記錄
要監(jiān)視應(yīng)用程序的行為,必須檢查日志——每個(gè)pod生成多個(gè)日志。要開始在儀表板UI中搜索日志,必須有一些機(jī)制收集并將它們聚合到一個(gè)日志查看器中。為了說明這一點(diǎn),F(xiàn)luentd是一個(gè)開源工具,也是CNCF的一部分,與 Elastic Search 和 Kibana ***結(jié)合。