本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Azure VMSS、叢集自動擴展器和使用者指派身分支援
簡介
在 Kubernetes v1.12 中,Azure 虛擬機器擴展集 (VMSS) 和叢集自動調整程式已達到正式發行 (GA) 狀態,而使用者指派身分識別則以預覽功能形式提供。
Azure VMSS 可讓您建立和管理相同的負載平衡 VM,這些 VM 會根據需求或設定的排程自動增加或減少。這讓您能夠輕鬆管理和擴展多個 VM,以提供高可用性和應用程式復原能力,非常適合容器工作負載等大規模應用程式 [1]。
叢集自動調整程式可讓您根據負載條件自動調整 Kubernetes 叢集的大小。
v1.12 帶來的另一個令人興奮的功能是能夠將使用者指派的身分識別與 Kubernetes 叢集搭配使用 [12]。
在本文中,我們將簡要概述 Azure 上的 VMSS、叢集自動調整程式和使用者指派身分識別功能。
VMSS
Azure 的虛擬機器擴展集 (VMSS) 功能為使用者提供從單一中央組態自動建立 VM 的能力、透過 L4 和 L7 負載平衡提供負載平衡、提供使用可用性區域以實現高可用性的路徑,並提供大規模 VM 執行個體等等。
VMSS 由一組虛擬機器組成,這些虛擬機器是相同的,可以在群組層級進行管理和設定。有關 Azure 中此功能的更多詳細資訊,請參閱以下連結 [1]。
透過 Kubernetes v1.12,客戶可以使用 VMSS 執行個體建立 k8s 叢集,並利用 VMSS 功能。
Azure 上的叢集元件
一般而言,Azure 中的獨立 Kubernetes 叢集包含以下部分
- 運算 - VM 本身及其屬性。
- 網路 - 這包括 IP 和負載平衡器。
- 儲存體 - 與 VM 相關聯的磁碟。
運算
雲端 k8s 叢集中的運算由 VM 組成。這些 VM 由 acs-engine 或 AKS 等佈建工具建立 (在受管理的服務的情況下)。最終,它們會以程序 (在某些版本中) 或 Docker 容器的形式執行各種系統守護程序,例如 kubelet、kube-api server 等。
網路
在 Azure Kubernetes 叢集中,各種網路元件匯集在一起,以提供使用者所需的功能。它們通常由網路介面、網路安全性群組、公用 IP 資源、VNET (虛擬網路)、負載平衡器等組成。
儲存體
Kubernetes 叢集建立在 Azure 中建立的磁碟之上。在典型的組態中,我們有受管理的磁碟,用於保存常規作業系統映像,而單獨的磁碟用於 etcd。
雲端供應商元件
Kubernetes 雲端供應商介面提供與雲端互動以管理雲端特定資源,例如公用 IP 和路由。有關這些元件的良好概述,請參閱 [2]。在 Azure Kubernetes 叢集的情況下,Kubernetes 互動會通過 Azure 雲端供應商層,並聯絡雲端中運行的各種服務。
K8s 的雲端供應商實作可以大致分為以下元件介面,我們需要實作這些介面
- 負載平衡器
- 執行個體
- 區域
- 路由
除了上述介面外,來自雲端供應商的儲存服務還通過磁碟區外掛程式層連結。
Azure 雲端供應商實作和 VMSS
在 Azure 雲端供應商中,對於我們實作的每種叢集類型,我們都會指定一個 VMType 選項。在 VMSS 的情況下,VM 類型為「vmss」。佈建軟體 (acs-engine,未來為 AKS 等) 會在 /etc/kubernetes/azure.json 檔案中設定這些值。根據此類型,各種實作將被實例化 [3]
負載平衡器介面提供對底層雲端供應商負載平衡器服務的存取權。Kubernetes 需要有關負載平衡器的資訊及其控制操作,才能處理託管在 Kubernetes 叢集上的服務。對於 VMSS 支援,變更可確保 VMSS 執行個體是負載平衡器集區的一部分 (如果需要)。
執行個體介面可協助雲端控制器從雲端供應商層取得有關節點的各種詳細資訊。例如,節點的詳細資訊 (例如 IP 位址、執行個體 ID 等) 是由控制器透過雲端供應商層向其註冊的執行個體介面取得的。在 VMSS 支援的情況下,我們會與 VMSS 服務交談以收集有關執行個體的資訊。
區域介面可協助雲端控制器取得每個節點的區域資訊。排程器可以使用此類資訊將 Pod 分散到不同的可用性區域。它也是支援拓撲感知動態佈建功能 (例如 AzureDisk) 所必需的。每個 VMSS 執行個體都會標記其目前的區域和地區。
路由介面可協助雲端控制器為 Pod 網路設定進階路由。例如,將為每個節點設定具有前置詞節點的 podCIDR 和下一個躍點節點的內部 IP 的路由。在 VMSS 支援的情況下,下一個躍點是 VMSS 虛擬機器的內部 IP 位址。
Azure 磁碟區外掛程式介面已針對 VMSS 進行修改,以使其正常運作。例如,AzureDisk 的連接/卸離已修改為在 VMSS 執行個體層級執行這些操作。
在 Azure 上設定 VMSS 叢集
以下連結 [4] 提供使用 acs-engine 建立 Kubernetes 叢集的範例。
acs-engine deploy --subscription-id <subscription id> \
--dns-prefix <dns> --location <location> \
--api-model examples/kubernetes.json
API 模型檔案提供 acs-engine 用於建立叢集的各種組態。此處的 API 模型 [5] 提供設定 VMSS 叢集的良好起始組態。
建立 VMSS 叢集後,您可以執行以下一些步驟來進一步了解叢集設定。以下是使用上述命令建立的叢集中 kubectl get nodes 的輸出
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-agentpool1-92998111-vmss000000 Ready agent 1h v1.12.0-rc.2
k8s-agentpool1-92998111-vmss000001 Ready agent 1h v1.12.0-rc.2
k8s-master-92998111-0 Ready master 1h v1.12.0-rc.2
此叢集由兩個工作節點和一個主節點組成。現在我們如何檢查哪個節點在 Azure 術語中是哪個節點?在 VMSS 清單中,我們可以看到單個 VMSS
$ az vmss list -o table -g k8sblogkk1
Name ResourceGroup Location Zones Capacity Overprovision UpgradePolicy
---------------------------- --------------- ---------- ------- ---------- --------------- ---------------
k8s-agentpool1-92998111-vmss k8sblogkk1 westus2 2 False Manual
我們看到作為代理程式的節點 (在 kubectl get nodes 命令中) 是此 vmss 的一部分。我們可以使用以下命令列出屬於 VM 擴展集的執行個體
$ az vmss list-instances -g k8sblogkk1 -n k8s-agentpool1-92998111-vmss -o table
InstanceId LatestModelApplied Location Name ProvisioningState ResourceGroup VmId
------------ -------------------- ---------- ------------------------------ ------------------- --------------- ------------------------------------
0 True westus2 k8s-agentpool1-92998111-vmss_0 Succeeded K8SBLOGKK1 21c57d6c-9c8f-4a62-970f-63ed0fcba53f
1 True westus2 k8s-agentpool1-92998111-vmss_1 Succeeded K8SBLOGKK1 840743b9-0076-4a2e-920e-5ba9da296665
節點名稱與 VM 擴展集中的名稱不符,但是如果我們執行以下命令來列出 providerID,我們可以找到與執行個體名稱相似的相符節點
$ kubectl describe nodes k8s-agentpool1-92998111-vmss000000| grep ProviderID
ProviderID: azure:///subscriptions/<subscription id>/resourceGroups/k8sblogkk1/providers/Microsoft.Compute/virtualMachineScaleSets/k8s-agentpool1-92998111-vmss/virtualMachines/0
目前狀態和未來
目前支援以下功能
- VMSS 主節點和工作節點
- 工作節點上的 VMSS 和主節點組合上的可用性設定。
- 每個 VM 磁碟連接
- Azure 磁碟和 Azure 檔案支援
- 可用性區域 (Alpha)
未來將支援以下功能
- 具有 VMSS 支援的 AKS
- 每個 VM 執行個體公用 IP
叢集自動調整程式
Kubernetes 叢集由節點組成。這些節點可以是虛擬機器、裸機伺服器,甚至可以是虛擬節點 (virtual kubelet)。為了避免迷失在 Kubernetes 生態系統的排列組合中 ;-),讓我們考慮一下我們正在討論的叢集由託管在雲端 (例如:Azure、Google 或 AWS) 中的虛擬機器組成。這實際上意味著您可以存取執行 Kubernetes 代理程式的虛擬機器和執行 k8s 服務 (例如 API 伺服器) 的主節點。有關 k8s 架構的詳細版本,請參閱此處 [11]。
叢集上所需的節點數量取決於叢集上的工作負載。當負載增加時,需要增加節點;當負載減少時,需要減少節點並清理不再使用的資源。解決此問題的一種方法是手動擴展屬於 Kubernetes 叢集的節點,並在需求減少時手動縮減。但是,這不應該自動完成嗎?這個問題的答案是叢集自動調整程式 (CA)。
叢集自動調整程式本身作為 Kubernetes 叢集中的 Pod 運行。下圖說明了與 k8s 叢集相關的設定的高階視圖
由於叢集自動調整程式是 k8s 叢集中的 Pod,因此它可以使用叢集內組態和 Kubernetes go 用戶端 [10] 來聯絡 API 伺服器。
內部
API 伺服器是管理 k8s 叢集狀態的中央服務,它利用後端儲存 (etcd 資料庫),在管理節點上運行或在雲端內運行 (在受管理的服務 (例如 AKS) 的情況下)。對於 Kubernetes 叢集內的任何元件,要找出叢集的狀態 (例如,叢集中註冊的節點),聯絡 API 伺服器是可行的方法。
為了簡化我們的討論,讓我們將 CA 功能分為以下 3 個部分
CA 的主要部分是一個控制迴圈,它在每個掃描間隔持續運行。此迴圈負責更新自動調整程式指標和健康探測。在此迴圈進入之前,自動調整程式在執行 Kubernetes 領導者選舉後執行各種操作,例如宣告領導者狀態。主迴圈初始化靜態自動調整程式元件。此元件根據傳遞到 CA 的參數初始化底層雲端供應商。
CA 執行的各種操作以管理叢集的狀態會傳遞到雲端供應商元件。一些範例,例如 - 增加目標大小、減小目標大小等,會導致雲端供應商元件在內部與雲端服務交談,並執行諸如新增節點或刪除節點之類的操作。這些操作在叢集中的節點群組上執行。靜態自動調整程式還通過查詢 API 伺服器來追蹤系統的狀態 - 諸如列出 Pod 和列出節點之類的操作用於取得此類資訊。
擴展的決策是基於保持未排程狀態的 Pod 以及各種檢查和平衡。可以縮減的空閒節點會從叢集中刪除,並從雲端本身刪除。叢集自動調整程式在擴展和縮減之前應用檢查和平衡 - 例如,最近新增的節點會被特別考慮。在刪除期間,節點會被耗盡,以確保正在運行的 Pod 不會發生中斷。
在 Azure 上設定 CA
叢集自動調整程式作為 acs-engine 的附加元件提供。以下連結 [15] 有一個範例組態檔,用於使用 acs-engine 部署自動調整程式。以下連結 [8] 提供有關手動逐步執行相同操作的詳細資訊。
在 acs-engine 的情況下,我們使用常規命令列來部署
acs-engine deploy --subscription-id <subscription id> \
--dns-prefix <dns> --location <location> \
--api-model examples/kubernetes.json
config 檔案中以下幾行 [15] 中的主要區別確保 CA 作為附加元件部署
"addons": [
{
"name": "cluster-autoscaler",
"enabled": true,
"config": {
"minNodes": "1",
"maxNodes": "5"
}
}
]
上述 json 中的 config 區段可用於為叢集自動調整程式 Pod 提供組態,例如:上述的最小和最大節點。
設定完成後,我們可以看到 cluster-autoscaler Pod 部署在系統命名空間中
$kubectl get pods -n kube-system | grep autoscaler
cluster-autoscaler-7bdc74d54c-qvbjs 1/1 Running 1 6m
以下是來自範例叢集的 CA configmap 和事件的輸出
$kubectl -n kube-system describe configmap cluster-autoscaler-status
Name: cluster-autoscaler-status
Namespace: kube-system
Labels: <none>
Annotations: cluster-autoscaler.kubernetes.io/last-updated=2018-10-02 01:21:17.850010508 +0000 UTC
Data
====
status:
----
Cluster-autoscaler status at 2018-10-02 01:21:17.850010508 +0000 UTC:
Cluster-wide:
Health: Healthy (ready=3 unready=0 notStarted=0 longNotStarted=0 registered=3 longUnregistered=0)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleUp: NoActivity (ready=3 registered=3)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:39:50.493307405 +0000 UTC m=+674.133759650
NodeGroups:
Name: k8s-agentpool1-92998111-vmss
Health: Healthy (ready=2 unready=0 notStarted=0 longNotStarted=0 registered=2 longUnregistered=0 cloudProviderTarget=2 (minSize=1, maxSize=5))
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleUp: NoActivity (ready=2 cloudProviderTarget=2)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:39:50.493307405 +0000 UTC m=+674.133759650
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScaleDownEmpty 42m cluster-autoscaler Scale-down: removing empty node k8s-agentpool1-92998111-vmss000002
從事件中可以看出,叢集自動調整程式縮減並刪除了一個節點,因為此叢集上沒有負載。在這種情況下,configmap 的其餘部分表示自動調整程式目前沒有採取進一步的動作。
目前狀態和未來
叢集自動調整程式目前支援四種類型的 VM:標準 (VMAS)、VMSS、ACS 和 AKS。未來,叢集自動調整程式將整合到 AKS 產品中,以便使用者可以一鍵啟用它。
使用者指派身分識別
為了使 Kubernetes 叢集元件能夠安全地與雲端服務交談,它需要向雲端供應商進行驗證。在 Azure Kubernetes 叢集中,到目前為止,這是透過兩種方式完成的 - 服務主體或受管理的身分識別。在服務主體的情況下,憑證儲存在叢集內,並且使用者需要承擔密碼輪換和其他挑戰才能適應此模型。受管理的服務身分識別消除了使用者的這種負擔,並直接管理服務執行個體 [12]。
受管理的身分識別有兩種可能 - 一種是系統指派,另一種是使用者指派。在系統指派身分識別的情況下,Kubernetes 叢集中的每個 VM 在建立期間都會被指派一個受管理的身分識別。此身分識別由需要存取 Azure 資源的各種 Kubernetes 元件使用。這些操作的範例包括取得/更新負載平衡器組態、取得/更新 VM 資訊等。使用系統指派的受管理身分識別,使用者無法控制指派給底層 VM 的身分識別。系統會自動指派它,這降低了使用者的彈性。
透過 v1.12,我們為 Kubernetes 帶來了使用者指派的受管理身分識別支援。透過此支援,使用者不必管理任何密碼,但同時可以彈性地管理叢集使用的身分識別。例如,如果使用者需要允許叢集存取特定的儲存體帳戶或 Azure 金鑰保存庫,則可以提前建立使用者指派的身分識別並提供金鑰保存庫存取權。
內部
為了了解內部機制,我們將重點關注使用 acs-engine 建立的叢集。這可以透過其他方式進行設定,但基本互動模式相同。
acs-engine 使用所需的組態設定叢集。/etc/kubernetes/azure.json 檔案為叢集元件 (例如:kube-apiserver) 提供了一種收集有關如何存取雲端資源的組態的方法。在使用使用者管理身分識別的叢集中,有一個值填寫了以 UserAssignedIdentityID
作為金鑰。此值填寫了 acs-engine 建立或使用者提供的使用者指派身分識別的用戶端 ID,無論情況如何。用於 Kubernetes 在 Azure 上進行驗證的程式碼可以在此處找到 [14]。此程式碼使用 Azure adal 套件進行驗證以存取雲端中的各種資源。在使用使用者指派身分識別的情況下,會進行以下 API 呼叫以取得新的權杖
adal.NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint,
env.ServiceManagementEndpoint,
config.UserAssignedIdentityID)
這會呼叫執行個體中繼資料服務或 VM 擴充功能 [12] 以收集權杖,然後用於存取各種資源。
設定具有使用者指派身分識別的叢集
透過 v1.12 中對使用者指派身分識別的上游支援,acs-engine 現在支援建立具有使用者指派身分識別的叢集。此處提供的 json 組態檔 [13] 可用於建立具有使用者指派身分識別的叢集。用於建立 VMSS 叢集的相同步驟可用於建立已指派使用者指派身分識別的叢集。
acs-engine deploy --subscription-id <subscription id> \
--dns-prefix <dns> --location <location> \
--api-model examples/kubernetes-msi-userassigned/kube-vmss.json
此處的主要組態值如下
"useManagedIdentity": true
"userAssignedID": "acsenginetestid"
第一個 useManagedIdentity
向 acs-engine 指示我們將使用受管理的身分識別擴充功能。這會設定受管理的身分識別運作所需的必要套件和擴充功能。下一個 userAssignedID
提供有關要與叢集一起使用的使用者身分識別的資訊。
目前狀態和未來
目前,我們支援使用 acs-engine 的部署來建立具有叢集的使用者指派身分識別。未來,這將成為 AKS 的一部分。
參與其中
對於 Azure 特定討論 - 請查看 Azure SIG 頁面 [6],並加入 #sig-azure slack 頻道以了解更多資訊。
對於 CA,請查看 Autoscaler 專案 [7],並加入 #sig-autoscaling Slack 以進行更多討論。
有關 Azure 上的 acs-engine (非受管理類型) 的文件,請參閱此處:[9]。有關 Azure Kubernetes Service (AKS) 的受管理服務的更多詳細資訊,請參閱此處 [5]。
參考文獻
https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview
/docs/concepts/architecture/cloud-controller/
https://github.com/Azure/acs-engine/blob/master/docs/kubernetes/deploy.md
https://github.com/kubernetes/community/tree/master/sig-azure
/docs/concepts/architecture/
https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
https://github.com/Azure/acs-engine/tree/master/examples/kubernetes-msi-userassigned
14)https://github.com/kubernetes/kubernetes/blob/release-1.17/staging/src/k8s.io/legacy-cloud-providers/azure/auth/azure_auth.go