新聞動態(tài)
阿里云 K8S 集群節(jié)點伸縮原理
常見問題 發(fā)布者:cya 2019-12-10 08:54 訪問量:313
來自:云棲社區(qū),作者:shengdong
鏈接:https://yq.aliyun.com/articles/704224
阿里云K8S集群的一個重要特性,是集群的節(jié)點可以動態(tài)的增加或減少。有了這個特性,集群才能在計算資源不足的情況下擴容新的節(jié)點,同時也可以在資源利用率降低的時候,釋放節(jié)點以節(jié)省費用。
這篇文章,我們討論阿里云K8S集群擴容與縮容的實現原理。理解實現原理,在遇到問題的時候,我們就可以高效地排查并定位原因。我們的討論基于當前的1.12.6版本。
阿里云K8S集群可以給集群增加節(jié)點的方式有,添加已有節(jié)點,集群擴容,和自動伸縮。其中,添加已有節(jié)點又可分為手動添加已有節(jié)點和自動添加已有節(jié)點。節(jié)點的增加涉及到的組件有,節(jié)點準備,彈性伸縮(ESS),管控,Cluster Autoscaler以及調度器。
節(jié)點準備,其實就是把一個普通的ECS實例,安裝配置成為一個K8S集群節(jié)點的過程。這個過程僅靠一條命令就可以完成。這條命令使用curl下載attach_node.sh腳本,然后以openapi token為參數,在ECS上運行。
curl http:///public/pkg/run/attach//attach_node.sh | bash -s -- --openapi-token
這里token是一個對的key,而value是當前集群的基本信息。阿里云K8S集群的管控,在接到手動添加已有節(jié)點請求的時候,會生成這個對,并把key作為token返回給用戶。
這個token(key)存在的價值,是其可以讓attach_node.sh腳本,以匿名身份在ECS上索引到集群的基本信息(value),而這些基本信息,對節(jié)點準備至關重要。
總體上來說,節(jié)點準備就做兩件事情,讀和寫。讀即數據收集,寫即節(jié)點配置。
這里的讀寫過程,絕大部分都很基礎,大家可以通過閱讀腳本來了解細節(jié)。唯一需要特別說明的是,kubeadm join把節(jié)點注冊到Master的過程。此過程需要新加節(jié)點和集群Master之間建立互信。
一邊,新加節(jié)點從管控處獲取的bootstrap token(與openapi token不同,此token是value的一部分內容),實際上是管控通過可信的途徑從集群Master上獲取的。新加節(jié)點使用這個bootstrap token連接Master,Master則可通過驗證這個bootstrap token來建立對新加節(jié)點的信任。
另一邊,新加節(jié)點以匿名身份從Master kube-public命名空間中獲取集群cluster-info,cluster-info包括集群CA證書,和使用集群bootstrap token對這個CA做的簽名。新加節(jié)點使用從管控處獲取的bootstrap token,對CA生成b新的簽名,然后將此簽名與cluster-info內簽名做對比,如果兩個簽名一致,則說明cluster-info和bootstrap token來自同一集群。新加節(jié)點因為信任管控,所以建立對Master的信任。
自動添加已有節(jié)點,不需要人為拷貝黏貼腳本到ECS命令行來完成節(jié)點準備的過程。管控使用了ECS userdata的特性,把類似以上節(jié)點準備的腳本,寫入ECS userdata,然后重啟ECS并更換系統盤。當ECS重啟之后,會自動執(zhí)行Userdata里邊的腳本,來完成節(jié)點添加的過程。這部分內容,大家其實可以通過查看節(jié)點userdata來確認。
#!/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的參數,與前一節(jié)的參數有很大的不同。其實這里的參數,都是前一節(jié)value的內容,即管控創(chuàng)建并維護的集群基本信息。自動添加已有節(jié)點省略了通過key獲取value的過程。
集群擴容與以上添加已有節(jié)點不同,此功能針對需要新購節(jié)點的情形。集群擴容的實現,在添加已有節(jié)點的基礎上,引入了彈性伸縮ESS組件。ESS組件負責從無到有的過程,而剩下的過程與添加已有節(jié)點類似,即依靠ECS userdata腳本來完成節(jié)點準備。下圖是管控通過ESS從無到有創(chuàng)建ECS的過程。
自動伸縮
前邊三種方式是需要人為干預的伸縮方式,而自動伸縮的本質不同,是它可以在業(yè)務需求量增加的時候,自動創(chuàng)建ECS實例并加入集群。為了實現自動化,這里引入了另外一個組件Cluster Autoscaler。集群自動伸縮包括兩個獨立的過程。
其中第一個過程,主要用來配置節(jié)點的規(guī)格屬性,包括設置節(jié)點的用戶數據。這個用戶數據和手動添加已有節(jié)點的腳本類似,不同的地方在于,其針對自動伸縮這種場景,增加了一些專門的標記。attach_node.sh腳本會根據這些標記,來設置節(jié)點的屬性。
#!/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
而第二個過程,是實現自動增加節(jié)點的關鍵。這里引入了一個新的組件Autoscaler,它以Pod的形式運行在K8S集群中。理論上來說,我們可以把這個組件當做一個控制器。因為它的作用與控制器類似,基本上還是監(jiān)聽Pod狀態(tài),以便在Pod因為節(jié)點資源不足而不能被調度的時,去修改ESS的伸縮規(guī)則來增加新的節(jié)點。
這里有一個知識點,集群調度器衡量資源是否充足的標準,是“預訂率”,而不是“使用率”。這兩者的差別,類似酒店房價預訂率和實際入住率:完全有可能有人預訂了酒店,但是并沒有實際入住。在開啟自動伸縮功能的時候,我們需要設置縮容閾值,就是“預訂率”的下線。之所以不需要設置擴容閾值。是因為Autoscaler擴容集群,依靠的是Pod的調度狀態(tài):當Pod因為節(jié)點資源“預訂率”太高無法被調度的時候,Autoscaler就會擴容集群。
與增加節(jié)點不同,集群減少節(jié)點的操作只有一個移除節(jié)點的入口。但對于用不同方法加入的節(jié)點,其各自移除方式略有不同。
首先,通過添加已有節(jié)點加入的節(jié)點,需要三步去移除:管控通過ECS API清楚ECS userdata;管控通過K8S API從集群中刪除節(jié)點;管控通過ECS InvokeCommand在ECS上執(zhí)行kubeadm reset命令清理節(jié)點。
其次,通過集群擴容加入的節(jié)點,則在上邊的基礎上,增加了斷開ESS和ECS關系的操作。此操作由管控調用ESS API完成。
最后,經過Cluster Autoscaler動態(tài)增加的節(jié)點,則在集群CPU資源“預訂率”降低的時候,由Cluster Autoscaler自動移除釋放。其觸發(fā)點是CPU“預訂率”,即上圖寫Metrics的原因。
總體上來說,K8S集群節(jié)點的增加與減少,主要涉及四個組件,分別是Cluster Autoscaler,ESS,管控以及節(jié)點本身(準備或清理)。根據場景不同,我們需要排查不同的組件。其中Cluster Autoscaler是一個普通的Pod,其日志的獲取和其他Pod無異;ESS彈性伸縮有其專門的控制臺,我們可以在控制臺排查其伸縮配置、伸縮規(guī)則等相關子實例日志和狀態(tài);而管控的日志,可以通過查看日志功能來查看;最后,對于節(jié)點的準備與清理,其實就是排查對應的腳本的執(zhí)行過程。
文章連接: http://www.hsjyfc.com.cn/cjwt/638.html
版權聲明:文章由 晨展科技 整理收集,來源于互聯網或者用戶投稿,如有侵權,請聯系我們,我們會立即刪除。如轉載請保留