文章目錄
- 一,需求
- 工作需求
- 說明
- 二,部署
- 精簡命令執行
- 1,要求
- 2,查看EC2 Auto Scaling groups Tag
- 3,創建Serviceaccount需要的Policy,Role
- 4,部署Cluster Autoscaler
- 5,驗證
- 6,常見問題
- 三,參考文檔
一,需求
工作需求
Amazon EKS 是托管的 Kubernetes 服務,可以使用 HPA 和 Cluster Autoscaler 來在集群中實現彈性伸縮,以滿足應用程序的需求并節省資源成本。
說明
Kubernetes(K8s)提供了自動伸縮機制,旨在根據應用程序負載和資源需求的變化自動調整應用的副本數量或節點數量,以滿足性能需求和優化資源利用。K8s 中的兩個關鍵自動伸縮機制是 Horizontal Pod Autoscaler (HPA) 和 Cluster Autoscaler。。
方法 | 定義 | 工作原理 | 范圍 | 目標 | 對象 | 自動化程度 |
---|---|---|---|---|---|---|
Horizontal Pod Autoscaler | HPA 用于自動調整一個 Deployment、ReplicaSet 或者 StatefulSet 中 Pod 的副本數量,以保持某個指標(例如 CPU 使用率或內存使用率)的目標值。當定義的指標超過或低于閾值時,HPA 將增加或減少 Pod 的副本數量。 | 1,監控 Metrics Server 或自定義指標服務收集的數據. 2,根據定義的目標值,計算出需要的副本數量。 3,更新 Deployment、ReplicaSet 或 StatefulSet 中的 Pod 數量。 | HPA 負責調整一個 Deployment、ReplicaSet 或 StatefulSet 中的 Pod 數量 | HPA 關注 Pod 的資源使用率 | Pod | HPA 需要你設置目標值,然后根據這些值自動調整 Pod 數量 |
Cluster Autoscaler | Cluster Autoscaler 是一種自動伸縮機制,它負責在 Kubernetes 集群中自動擴展或收縮節點的數量。當集群中的 Pod 數量增加或減少,Cluster Autoscaler 會根據條件自動擴展或縮減節點數量。 | 1,監控未滿足資源需求的 Pod,并找到它們所在的節點。 2,如果沒有足夠的節點提供資源,Cluster Autoscaler 會請求云提供商(例如 AWS、GCP)來添加新節點。 當節點上的 Pod 數量減少,如果節點的資源利用率過低,Cluster Autoscaler 可能會將節點縮減。 | Cluster Autoscaler 負責調整整個集群中節點的數量 | Cluster Autoscaler 關注節點的資源利用率 | Node | Cluster Autoscaler 可以在需要的時候自動增加或減少節點 |
二,部署
精簡命令執行
執行命令
##創建sa策略
aws iam create-policy \--policy-name AmazonEKSClusterAutoscalerPolicy \--policy-document file://cluster-autoscaler-policy.json
##創建Role角色
aws iam create-role \--role-name AmazonEKSClusterAutoscalerRole \--assume-role-policy-document file://"trust-policy.json"
##下載Autoscaler yaml文件
wget https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
## 修改yaml文件
1,修改鏡像tag為對應EKS版本號
打開以下 Cluster Autoscaler 的 github 的網面,查看與 EKS 版本匹配的最新 Autoscaler 鏡像版本 https://link.zhihu.com/?target=https%3A//github.com/kubernetes/autoscaler/releases
2,修改<YOUR CLUSTER NAME>
3, 在<YOUR CLUSTER NAME>下追加兩行:
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
##部署Cluster Autoscaler
kubectl apply -f cluster-autoscaler-autodiscover.yaml
## 綁定服務帳戶和IAM角色
kubectl annotate serviceaccount cluster-autoscaler -n kube-system eks.amazonaws.com/role-arn=arn:aws:iam::<Account_ID>:role/<Role-name>
1,要求
- 版本 Cluster Autoscaler需要Kubernetes v1.3.0或更高版本
- 權限 Cluster Autoscaler 需要能夠檢查和修改 EC2 Auto Scaling 組。建議使用服務帳戶的IAM角色
- 身份管理 全集群自動縮放器功能策略或者最低IAM策略
- OIDC OIDC 聯合身份驗證允許您的服務承擔 IAM 角色并與 AWS 服務交互,而無需將憑證存儲為環境變量
- AWS憑證 服務帳戶的IAM角色
2,查看EC2 Auto Scaling groups Tag
Cluster Autoscaler 使用 EC2 Auto Scaling groups 服務對 node 進行擴容,我們需要確保 EKS 對應的 Auto Scaling groups 有適合的 Tag。
Cluster Autoscaler 通過 Tag 來識別哪些 Auto Scaling groups 屬于其管轄范圍。
如果我們使用 eksctl 命令或者 AWS 網頁控制臺來創建 node group,則所需 Tag 已經自動設置了,如果用其它方式創建的 node group 則需要確保其對應用的 Auto Scaling groups 中有以下兩個 Tag
3,創建Serviceaccount需要的Policy,Role
通過 service account(sa)來給 Cluster Autoscaler 的 Pod 提供訪問 AWS 的 EC2 Auto Scaling groups 的權限。先創建 sa 需要的 Policy 和 Role。
創建Policy
vim cluster-autoscaler-policy.json
{"Version": "2012-10-17","Statement": [{"Action": ["autoscaling:DescribeAutoScalingGroups","autoscaling:DescribeAutoScalingInstances","autoscaling:DescribeLaunchConfigurations","autoscaling:DescribeTags","autoscaling:SetDesiredCapacity","autoscaling:TerminateInstanceInAutoScalingGroup","ec2:DescribeInstanceTypes","ec2:DescribeLaunchTemplateVersions"],"Resource": "*","Effect": "Allow"}]
}
參考:https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/CA_with_AWS_IAM_OIDC.md
Tips: 這個Policy 提供訪問EC2 autoscaling group的相關權限
創建策略
aws iam create-policy \--policy-name AmazonEKSClusterAutoscalerPolicy \--policy-document file://cluster-autoscaler-policy.json
創建IAM Role
vim trues-policy.json
{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Federated": "arn:aws:iam::<AccountID>:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/<OICD_ID>"},"Action": "sts:AssumeRoleWithWebIdentity","Condition": {"StringEquals": {"oidc.eks.us-east-1.amazonaws.com/id/<OICD_ID>:sub": "system:serviceaccount:kube-system:cluster-autoscaler"}}}]
}###更新角色信任關系aws iam update-assume-role-policy --role-name <role-name> --policy-document file://trust-policy.json更新角色信任關系
aws iam update-assume-role-policy --role-name AmazonEKSClusterAutoscalerRole --policy-document file://"trust-policy.json"
說明:IAM Role 中包括 IAM policy 和 trust relationship 兩部分,我們先用 json 文件來定義 trust relationship 的內容。
trust-policy.json 在創建 Role 時,指定“Trust relationships”中的內容
- 修改“252557384592”為自己的 AWS Account
- 修改“us-east-1”為自己的 Region
- 修改“OpenID Connect provider URL”為自己 EKS 的 OpenID Connect provider URL 中最后的字符串,如下所示
創建角色
aws iam create-role \--role-name AmazonEKSClusterAutoscalerRole \--assume-role-policy-document file://"trust-policy.json"###更新角色信任關系aws iam update-assume-role-policy --role-name <role-name> --policy-document file://trust-policy.json更新角色信任關系
aws iam update-assume-role-policy --role-name AmazonEKSClusterAutoscalerRole --policy-document file://"trust-policy.json"
說明:
role-name:自定義 Role 的名稱
assume-role-policy-document:指定本地 trust-policy 文件
為角色附加策略
aws iam attach-role-policy \--policy-arn arn:aws:iam::<AccountID>:policy/AmazonEKSClusterAutoscalerPolicy \--role-name AmazonEKSClusterAutoscalerRole
4,部署Cluster Autoscaler
下載Autoscaler yaml文件
wget https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
部署Cluster Autoscaler
kubectl apply -f cluster-autoscaler-autodiscover.yaml
綁定服務帳戶和IAM角色
#命令行
kubectl annotate serviceaccount cluster-autoscaler -n kube-system eks.amazonaws.com/role-arn=arn:aws:iam::<ACCOUNTID>:role/<Role-name>(建議使用AmazonEKSClusterAutoscalerRole)
#文件
apiVersion: v1
kind: ServiceAccount
metadata:labels:k8s-addon: cluster-autoscaler.addons.k8s.iok8s-app: cluster-autoscalerannotations:eks.amazonaws.com/role-arn: arn:aws:iam::xxxxx:role/<Role-name> # Add the IAM role created in the above C section.name: cluster-autoscalernamespace: kube-system
5,驗證
#默認擴大節點組節點數量
擴大規模如何運作?
縱向擴展在 API 服務器上創建一個監視來查找所有 Pod。它每 10 秒檢查一次任何不可調度的 pod(可通過--scan-interval標志配置)。當 Kubernetes 調度程序無法找到可以容納 pod 的節點時,該 pod 就無法調度。例如,Pod 可以請求任何集群節點上可用的更多 CPU。不可調度的 pod 通過其 PodCondition 進行識別。每當 Kubernetes 調度程序無法找到運行 pod 的位置時,它就會將“schedulable”PodCondition 設置為 false,并將 Reason 設置為“unschedulable”。如果不可調度的 Pod 列表中有任何項目,Cluster Autoscaler 會嘗試找到新的位置來運行它們。#默認縮減節點組節點數量
每 10 秒(可通過--scan-interval標志配置),如果不需要擴展,Cluster Autoscaler 會檢查哪些節點是不需要的。當滿足以下所有條件時,將考慮刪除節點:
1,該節點上運行的所有 Pod 的 CPU 和內存請求總和(默認情況下包括DaemonSet Pod和Mirror Pod--ignore-daemonsets-utilization ,但可以使用和--ignore-mirror-pods-utilization標志進行配置)小于該節點可分配的 50%。(在 1.1.0 之前,使用節點容量而不是可分配的容量。)可以使用 --scale-down-utilization-threshold標志配置利用率閾值。
2,節點上運行的所有 pod(默認情況下在所有節點上運行的 pod 除外,例如清單運行 pod 或 daemonset 創建的 pod)都可以移動到其他節點。請參閱 哪些類型的 Pod 可以阻止 CA 刪除節點?部分了解有關哪些 pod 不滿足此條件的更多詳細信息,即使其他地方有空間容納它們。在檢查此情況時,所有可移動吊艙的新位置都會被記住。這樣,Cluster Autoscaler 就知道每個 Pod 可以移動到哪里,以及哪些節點在 Pod 遷移方面依賴于哪些其他節點。當然,最終調度程序可能會將 Pod 放置在其他位置。
3,它沒有縮小禁用注釋(請參閱如[何防止 Cluster Autoscaler 縮小特定節點?](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-can-i-prevent-cluster-autoscaler-from-scaling-down-a-particular-node))#測試集群自動綻放程序是否啟動及角色是否已附加
$ kubectl get pods -n kube-system
$ kubectl exec -n kube-system cluster-autoscaler-xxxxxx-xxxxx env | grep AWS#測試命令
kubectl scale deployment autoscaler-demo --replicas=50#擴展日志
I1025 13:48:42.975037 1 scale_up.go:529] Final scale-up plan: [{eksctl-xxx-xxx-xxx-nodegroup-ng-xxxxx-NodeGroup-xxxxxxxxxx 2->3 (max: 8)}]#獲取節點組信息
eksctl get nodegroup --cluster <cluster-name>
#調整節點組現有節點數
eksctl scale nodegroup --cluster <cluster-name> --name <nodegroup-name> --nodes <number>
#調整節點組最小節點數
eksctl scale nodegroup --cluster <cluster-name> --name <nodegroup-name> --nodes-min <number>
#調整節點組最大節點數
eksctl scale nodegroup --cluster <cluster-name> --name <nodegroup-name> --nodes-max <number>
6,常見問題
報錯一:
caused by: InvalidIdentityToken: No OpenIDConnect provider found in your account for https://oidc.eks.us-east-1.amazonaws.com/id/274A18041DB4CF680FA22A5EF99FDFE3
解決:
使用 eksctl 為集群創建 IAM OIDC 身份提供商
eksctl utils associate-iam-oidc-provider --cluster $cluster_name --approve確定集群是否擁有現有 IAM OIDC 提供商。
檢索集群的 OIDC 提供商 ID 并將其存儲在變量中。
oidc_id=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
確定您的賬戶中是否已存在具有您的集群 ID 的 IAM OIDC 提供商。報錯二:
0617 07:29:49.853336 1 aws_manager.go:262] Failed to regenerate ASG cache: WebIdentityErr: failed to retrieve credentials
caused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentitystatus code: 403, request id: ff336b02-e997-47f2-8551-8e00efa05049
F0617 07:29:49.853387 1 aws_cloud_provider.go:430] Failed to create AWS Manager: WebIdentityErr: failed to retrieve credentials
caused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentitystatus code: 403, request id: ff336b02-e997-47f2-8551-8e00efa05049
解決:
修改OICD供應商ID,更新角色信任策略
aws iam update-assume-role-policy --role-name AmazonEKSClusterAutoscalerRole --policy-document file://"trust-policy.json"aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4
如果返回了輸出,則表示您的集群已經有 IAM OIDC 提供商,您可以跳過下一步。如果沒有返回輸出,則您必須為集群創建 IAM OIDC 提供商。
使用以下命令為您的集群創建 IAM OIDC 身份提供商。將 my-cluster 替換為您自己的值。
eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve
三,參考文檔
AWS EKS 集群自動擴容 Cluster Autoscaler
github
CutoscalerFAQ