K8s 从懵圈到熟练-集群伸缩原理
作者 | 聲東? 阿里云技術(shù)專家
<關(guān)注公眾號(hào),回復(fù)?排查?即可下載電子書(shū)>
《深入淺出 Kubernetes》一書(shū)共匯集 12 篇技術(shù)文章,幫助你一次搞懂 6 個(gè)核心原理,吃透基礎(chǔ)理論,一次學(xué)會(huì) 6 個(gè)典型問(wèn)題的華麗操作!以下內(nèi)容節(jié)選自本書(shū):
阿里云 K8s 集群的一個(gè)重要特性,是集群的節(jié)點(diǎn)可以動(dòng)態(tài)的增加或減少。有了這個(gè)特性,集群才能在計(jì)算資源不足的情況下擴(kuò)容新的節(jié)點(diǎn),同時(shí)也可以在資源利用率降低的時(shí)候,釋放節(jié)點(diǎn)以節(jié)省費(fèi)用。
這篇文章,我們將討論阿里云 K8s 集群擴(kuò)容與縮容的實(shí)現(xiàn)原理。理解實(shí)現(xiàn)原理,在遇到問(wèn)題的時(shí)候,我們就可以高效地排查并定位原因。
雖然我們的討論是基于1.12.6 版本的,但是理論上后續(xù)版本與這篇文章所述集群伸縮原理出入不大。
節(jié)點(diǎn)增加原理
阿里云 K8s 集群可以給集群增加節(jié)點(diǎn)的方式有,添加已有節(jié)點(diǎn),集群擴(kuò)容,和自動(dòng)伸縮。其中,添加已有節(jié)點(diǎn)又可分為手動(dòng)添加已有節(jié)點(diǎn)和自動(dòng)添加已有節(jié)點(diǎn)。節(jié)點(diǎn)的增加涉及到的組件有,節(jié)點(diǎn)準(zhǔn)備,彈性伸縮(ESS),管控,Cluster Autoscaler 以及調(diào)度器。
手動(dòng)添加已有節(jié)點(diǎn)
節(jié)點(diǎn)準(zhǔn)備,其實(shí)就是把一個(gè)普通的 ECS 實(shí)例,安裝配置成為一個(gè) K8s 集群節(jié)點(diǎn)的過(guò)程。這個(gè)過(guò)程僅靠一條命令就可以完成。這條命令使用 curl 下載 attach_node.sh 腳本,然后以 openapi token 為參數(shù),在 ECS 上運(yùn)行。
curl http:///public/pkg/run/attach//attach_node.sh | bash -s -- --openapi-token這里 token 是一個(gè)對(duì)的 key,而 value 是當(dāng)前集群的基本信息。阿里云 K8s 集群的管控,在接到手動(dòng)添加已有節(jié)點(diǎn)請(qǐng)求的時(shí)候,會(huì)生成這個(gè)對(duì),并把 key 作為 token 返回給用戶。
這個(gè) token(key)存在的價(jià)值,是其可以讓 attach_node.sh 腳本,以匿名身份在 ECS 上索引到集群的基本信息(value),而這些基本信息,對(duì)節(jié)點(diǎn)準(zhǔn)備至關(guān)重要。
總體上來(lái)說(shuō),節(jié)點(diǎn)準(zhǔn)備就做兩件事情,讀和寫。讀即數(shù)據(jù)收集,寫即節(jié)點(diǎn)配置。
這里的讀寫過(guò)程,絕大部分都很基礎(chǔ),大家可以通過(guò)閱讀腳本來(lái)了解細(xì)節(jié)。唯一需要特別說(shuō)明的是,kubeadm join 把節(jié)點(diǎn)注冊(cè)到 Master 的過(guò)程。此過(guò)程需要新加節(jié)點(diǎn)和集群 Master 之間建立互信。
一邊,新加節(jié)點(diǎn)從管控處獲取的 bootstrap token(與 openapi token 不同,此 token 是 value 的一部分內(nèi)容),實(shí)際上是管控通過(guò)可信的途徑從集群 Master 上獲取的。新加節(jié)點(diǎn)使用這個(gè) bootstrap token 連接 Master,Master 則可通過(guò)驗(yàn)證這個(gè) bootstrap token 來(lái)建立對(duì)新加節(jié)點(diǎn)的信任。
另一邊,新加節(jié)點(diǎn)以匿名身份從 Master kube-public 命名空間中獲取集群 cluster-info,cluster-info 包括集群 CA 證書(shū),和使用集群 bootstrap token 對(duì)這個(gè) CA 做的簽名。新加節(jié)點(diǎn)使用從管控處獲取的 bootstrap token,對(duì) CA 生成新的簽名,然后將此簽名與 cluster-info 內(nèi)簽名做對(duì)比,如果兩個(gè)簽名一致,則說(shuō)明 cluster-info 和 bootstrap token 來(lái)自同一集群。新加節(jié)點(diǎn)因?yàn)樾湃喂芸?#xff0c;所以建立對(duì) Master 的信任。
自動(dòng)添加已有節(jié)點(diǎn)
自動(dòng)添加已有節(jié)點(diǎn),不需要人為拷貝黏貼腳本到 ECS 命令行來(lái)完成節(jié)點(diǎn)準(zhǔn)備的過(guò)程。管控使用了 ECS userdata 的特性,把類似以上節(jié)點(diǎn)準(zhǔn)備的腳本,寫入 ECS userdata,然后重啟 ECS 并更換系統(tǒng)盤。當(dāng) ECS 重啟之后,會(huì)自動(dòng)執(zhí)行 Userdata 里邊的腳本,來(lái)完成節(jié)點(diǎn)添加的過(guò)程。這部分內(nèi)容,大家其實(shí)可以通過(guò)查看節(jié)點(diǎn) userdata 來(lái)確認(rèn)。
!/bin/bash mkdir -p /var/log/acs curl http:///public/pkg/run/attach/1.12.6-aliyun.1/attach_node.sh | bash -s -- --docker-version --token --endpoint --cluster-dns > /var/log/acs/init.log這里我們看到,attach_node.sh 的參數(shù),與前一節(jié)的參數(shù)有很大的不同。其實(shí)這里的參數(shù),都是前一節(jié) value 的內(nèi)容,即管控創(chuàng)建并維護(hù)的集群基本信息。自動(dòng)添加已有節(jié)點(diǎn)省略了通過(guò) key 獲取 value 的過(guò)程。
集群擴(kuò)容
集群擴(kuò)容與以上添加已有節(jié)點(diǎn)不同,此功能針對(duì)需要新購(gòu)節(jié)點(diǎn)的情形。集群擴(kuò)容的實(shí)現(xiàn),在添加已有節(jié)點(diǎn)的基礎(chǔ)上,引入了彈性伸縮 ESS 組件。ESS 組件負(fù)責(zé)從無(wú)到有的過(guò)程,而剩下的過(guò)程與添加已有節(jié)點(diǎn)類似,即依靠 ECS userdata 腳本來(lái)完成節(jié)點(diǎn)準(zhǔn)備。下圖是管控通過(guò) ESS 從無(wú)到有創(chuàng)建 ECS 的過(guò)程。
自動(dòng)伸縮
前邊三種方式是需要人為干預(yù)的伸縮方式,而自動(dòng)伸縮的本質(zhì)不同,是它可以在業(yè)務(wù)需求量增加的時(shí)候,自動(dòng)創(chuàng)建 ECS 實(shí)例并加入集群。為了實(shí)現(xiàn)自動(dòng)化,這里引入了另外一個(gè)組件 Cluster Autoscaler。集群自動(dòng)伸縮包括兩個(gè)獨(dú)立的過(guò)程。
其中第一個(gè)過(guò)程,主要用來(lái)配置節(jié)點(diǎn)的規(guī)格屬性,包括設(shè)置節(jié)點(diǎn)的用戶數(shù)據(jù)。這個(gè)用戶數(shù)據(jù)和手動(dòng)添加已有節(jié)點(diǎn)的腳本類似,不同的地方在于,其針對(duì)自動(dòng)伸縮這種場(chǎng)景,增加了一些專門的標(biāo)記。attach_node.sh 腳本會(huì)根據(jù)這些標(biāo)記,來(lái)設(shè)置節(jié)點(diǎn)的屬性。
!/bin/sh curl http:///public/pkg/run/attach/1.12.6-aliyun.1/attach_node.sh | bash -s -- --openapi-token --ess true --labels k8s.io/cluster-autoscaler=true,workload_type=cpu,k8s.aliyun.com=true而第二個(gè)過(guò)程,是實(shí)現(xiàn)自動(dòng)增加節(jié)點(diǎn)的關(guān)鍵。這里引入了一個(gè)新的組件 Autoscaler,它以 Pod 的形式運(yùn)行在 K8s 集群中。理論上來(lái)說(shuō),我們可以把這個(gè)組件當(dāng)做一個(gè)控制器。因?yàn)樗淖饔门c控制器類似,基本上還是監(jiān)聽(tīng) Pod 狀態(tài),以便在 Pod 因?yàn)楣?jié)點(diǎn)資源不足而不能被調(diào)度的時(shí),去修改 ESS 的伸縮規(guī)則來(lái)增加新的節(jié)點(diǎn)。
這里有一個(gè)知識(shí)點(diǎn),集群調(diào)度器衡量資源是否充足的標(biāo)準(zhǔn),是“預(yù)訂率”,而不是“使用率”。這兩者的差別,類似酒店房?jī)r(jià)預(yù)訂率和實(shí)際入住率:完全有可能有人預(yù)訂了酒店,但是并沒(méi)有實(shí)際入住。在開(kāi)啟自動(dòng)伸縮功能的時(shí)候,我們需要設(shè)置縮容閾值,就是“預(yù)訂率”的下線。之所以不需要設(shè)置擴(kuò)容閾值。是因?yàn)?Autoscaler 擴(kuò)容集群,依靠的是 Pod 的調(diào)度狀態(tài):當(dāng) Pod 因?yàn)楣?jié)點(diǎn)資源“預(yù)訂率”太高無(wú)法被調(diào)度的時(shí)候,Autoscaler 就會(huì)擴(kuò)容集群。
節(jié)點(diǎn)減少原理
與增加節(jié)點(diǎn)不同,集群減少節(jié)點(diǎn)的操作只有一個(gè)移除節(jié)點(diǎn)的入口。但對(duì)于用不同方法加入的節(jié)點(diǎn),其各自移除方式略有不同。
首先,通過(guò)添加已有節(jié)點(diǎn)加入的節(jié)點(diǎn),需要三步去移除:管控通過(guò) ECS API 清除 ECS userdata;管控通過(guò) K8s API 從集群中刪除節(jié)點(diǎn);管控通過(guò) ECS InvokeCommand 在 ECS 上執(zhí)行 kubeadm reset 命令清理節(jié)點(diǎn)。
其次,通過(guò)集群擴(kuò)容加入的節(jié)點(diǎn),則在上邊的基礎(chǔ)上,增加了斷開(kāi) ESS 和 ECS 關(guān)系的操作。此操作由管控調(diào)用 ESS API 完成。
最后,經(jīng)過(guò) Cluster Autoscaler 動(dòng)態(tài)增加的節(jié)點(diǎn),則在集群 CPU 資源“預(yù)訂率”降低的時(shí)候,由 Cluster Autoscaler 自動(dòng)移除釋放。其觸發(fā)點(diǎn)是 CPU“預(yù)訂率”,即上圖寫 Metrics 的原因。
總結(jié)
總體上來(lái)說(shuō),K8s 集群節(jié)點(diǎn)的增加與減少,主要涉及四個(gè)組件,分別是 Cluster Autoscaler,ESS,管控以及節(jié)點(diǎn)本身(準(zhǔn)備或清理)。根據(jù)場(chǎng)景不同,我們需要排查不同的組件。其中 Cluster Autoscaler 是一個(gè)普通的 Pod,其日志的獲取和其他 Pod 無(wú)異;ESS 彈性伸縮有其專門的控制臺(tái),我們可以在控制臺(tái)排查其伸縮配置、伸縮規(guī)則等相關(guān)子實(shí)例日志和狀態(tài);而管控的日志,可以通過(guò)查看日志功能來(lái)查看;最后,對(duì)于節(jié)點(diǎn)的準(zhǔn)備與清理,其實(shí)就是排查對(duì)應(yīng)的腳本的執(zhí)行過(guò)程。
以上講道理居多,但如果結(jié)合問(wèn)題診斷實(shí)踐,一定會(huì)對(duì)大家的運(yùn)維工作有所幫助。
<關(guān)注公眾號(hào),回復(fù)?排查?即可下載電子書(shū)>
“阿里巴巴云原生關(guān)注微服務(wù)、Serverless、容器、Service Mesh 等技術(shù)領(lǐng)域、聚焦云原生流行技術(shù)趨勢(shì)、云原生大規(guī)模的落地實(shí)踐,做最懂云原生開(kāi)發(fā)者的技術(shù)圈。”
總結(jié)
以上是生活随笔為你收集整理的K8s 从懵圈到熟练-集群伸缩原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Service Mesh 最火项目 Is
- 下一篇: Istio 将被捐赠给开源基金会 | 云