1. 程式人生 > 程式設計 >你必知的 Kubernetes 自動縮放

你必知的 Kubernetes 自動縮放

作者;Juan Ignacio Giro 譯者:段訪 審校:羅廣明 原文: caylent.com/kubernetes-…

編者按

許多Kubernetes使用者,特別是那些企業級使用者,很快就遇到了對環境自動縮放的需求。幸運的是,Kubernetes Horizontal Pod Autoscaler(HPA)允許您將部署配置為以多種方式水平擴充套件。使用Kubernetes Autoscaling的最大優勢之一是您的叢集可以跟蹤現有Pod的負載能力,並計算是否需要更多的Pod。

Kubernetes Autoscaling

通過協調內建的兩層可擴充套件性,可以充分利用高效的Kubernetes Autoscaling:

  1. Pod級別的自動縮放:包括Horizontal Pod Autoscaler(HPA)和Vertical Pod Autoscaler(VPA); 兩者都可以擴充套件容器的可用資源。
  2. 叢集級別的自動縮放:叢集自動調節器(CA)通過在必要時向上或向下擴充套件叢集內的節點數來管理這種可擴充套件性平面。

Kubernetes Autoscaling 詳情

Horizontal Pod Autoscaler(HPA)

HPA會在叢集中縮放Pod副本的數量。該操作由CPU或記憶體觸發,以根據需要向上或向下擴充套件。但是,也可以根據各種外部的和自定義指標(metrics.k8s.io,external.metrics.k8s.io和custom.metrics.k8s.io)來配置HPA以擴充套件Pod。

Vertical Pod Autoscaler(VPA)

VPA主要用於有狀態服務,它可根據需要為Pod新增CPU或記憶體——它也適用於無狀態的Pod。為了應用這些更改,VPA重新啟動Pod以更新新的CPU和記憶體資源,這些資源可以配置為響應OOM(記憶體不足)事件而啟動。重新啟動Pod的時候,VPA始終確保根據Pod分配預算(PDB)確定最小數量,您可以設定該資源分配最大和最小速率。

Cluster Autoscaler(CA)

第二層的自動縮放涉及CA,它在以下情況下自動調整叢集的大小:

  • 由於叢集中的容量不足,任何Pod/s都無法執行並進入掛起狀態(在這種情況下,CA將向上擴充套件)。
  • 叢集中的節點在一段時間內未得到充分利用,並且有可能遷移節點上的Pod(在這種情況下,CA將縮小)。

CA進行例行檢查以確定是否有任何pod因等待額外資源處於待定狀態,或者叢集節點是否未得到充分利用。如果需要更多資源,會相應地調整Cluster節點的數量。CA與雲提供商互動以請求其他節點或關閉空閒節點,並確保按比例放大的叢集保持在使用者設定的限制範圍內。它適用於AWS,Azure和GCP。

將HPA和CA與Amazon EKS配合使用的5個步驟

本文提供了通過適用於Kubernetes(Amazon EKS)叢集的Amazon Elastic容器服務,通過HPA和CA安裝和自動擴充套件的分步指南。以下指南是兩個測試用例示例:

叢集要求

  • 滿足EKS叢集要求的Amazon VPC 和 一個安全組。
  • 或者,為免手動建立VPC,AWS提供了建立了VPC和EKS的CloudFormation模板

CloudFormation YAML檔案

1. 根據官方指南建立一個AWS EKS 叢集(控制面板和和工作節點). 一旦你把工作節點以auto scaling group的形式啟動了,它們會自動向EKS叢集註冊,你就可以開始部署k8s應用了。

2. 部署度量伺服器以便HPA能夠根據API提供的CPU/記憶體資料自動縮放POD副本的數量。 metrics.k8s.io api 通常由metrics-server(負責從summary api收集cpu和記憶體度量)提供。

3. 把以下策略應用到EKS建立的worker節點的Role上

{
   "Version": "2012-10-17","Statement": [
      {
         "Effect": "Allow","Action": [
            "autoscaling:DescribeAutoScalingGroups","autoscaling:DescribeAutoScalingInstances","autoscaling:DescribeLaunchConfigurations","autoscaling:DescribeTags","autoscaling:SetDesiredCapacity","autoscaling:TerminateInstanceInAutoScalingGroup"
         ],"Resource": "*"
      }
   ]
}
複製程式碼

4. 部署k8s CA特性

根據你使用的linux發行版,你可能需要更新部署檔案和證書路徑。 例如,如果使用AMI Linux,需要用/etc/ssl/certs/ca-bundle.crt替換/etc/ssl/certs/ca-certificates.crt

5. 更新CA的部署YAML檔案,找到指定的AWS AG(k8s.io/cluster-autoscaler/<CLUSTER NAME>應該包含真實的叢集名稱)標籤。 同時更新AWS_REGION環境變數。

把以下tag新增到 AWS AG, 以便 k8s 的 cluster autoscaler 能夠自動識別 AWS AG:

k8s.io/cluster-autoscaler/enabled k8s.io/cluster-autoscaler/

Kubernetes Autoscaling 測試用例 #1

測試k8s hpa 特性和k8s ca 特性同時使用

要求:

  • 一個執行中的eks叢集
  • 安裝好metric server
  • 安裝了k8s cluster autoscaler 特性

1. 部署一個測試app,為app部署建立HPA資源。

2. 從不同的地理位置發起請求以增加負載。

3. HPA 應該會隨著負載的增加開始縮放pod的數量。它會根據hpa資源指定的進行縮放的。在某一時刻,新的POD在等待其他資源的時候會是等待狀態。

$ kubectl get nodes -w
NAME                             STATUS    ROLES     AGE       VERSION
ip-192-168-189-29.ec2.internal   Ready         1h        v1.10.3
ip-192-168-200-20.ec2.internal   Ready         1h        v1.10.3
複製程式碼
$ kubectl get Pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE
ip-192-168-200-20.ec2.internal
php-apache-8699449574-4mg7w 0/1 Pending 0 17m
php-apache-8699449574-64zkm 1/1 Running 0 1h 192.168.210.90 ip-192-168-200-20
php-apache-8699449574-8nqwk 0/1 Pending 0 17m
php-apache-8699449574-cl8lj 1/1 Running 0 27m 192.168.172.71 ip-192-168-189-29
php-apache-8699449574-cpzdn 1/1 Running 0 17m 192.168.219.71 ip-192-168-200-20
php-apache-8699449574-dn9tb 0/1 Pending 0 17m
...
複製程式碼

4. CA 檢測到因為容量不足而進入等待狀態的pods,調整AWS 自動縮放組的大小。一個新的節點加入了:

$ kubectl get nodes -w
NAME                                       STATUS    ROLES     AGE       VERSION
ip-192-168-189-29.ec2.internal   Ready         2h        v1.10.3
ip-192-168-200-20.ec2.internal   Ready         2h        v1.10.3
ip-192-168-92-187.ec2.internal   Ready         34s       v1.10.3
複製程式碼

5. HPA能夠把等待狀態的POD排程到新的節點上了。 平均cpu使用率低於指定的目標,沒有必要再排程新的pod了。

$ kubectl get hpa
NAME         REFERENCE                    TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   40%/50%   2                  25                 20               1h $ kubectl get Pods -o wide -w
複製程式碼
$ kubectl get Pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE
php-apache-8699449574-4mg7w 1/1 Running 0 25m 192.168.74.4 ip-192-168-92-187
php-apache-8699449574-64zkm 1/1 Running 0 1h 192.168.210.90 ip-192-168-200-20
php-apache-8699449574-8nqwk 1/1 Running 0 25m 192.168.127.85 ip-192-168-92-187
php-apache-8699449574-cl8lj 1/1 Running 0 35m 192.168.172.71 ip-192-168-189-29
...
複製程式碼

6. 關閉幾個terminal,停掉一些負載

7. CPU平均利用率減小了, 所以HPA開始更改部署裡的pod副本數量並殺掉一些pods

$ kubectl get hpa
NAME         REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   47%/50%     2                20                 7                   1h 

$ kubectl get Pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE
...
php-apache-8699449574-v5kwf 1/1 Running 0 36m 192.168.250.0 ip-192-168-200-20
php-apache-8699449574-vl4zj 1/1 Running 0 36m 192.168.242.153 ip-192-168-200-20
php-apache-8699449574-8nqwk 1/1 Terminating 0 26m 192.168.127.85 ip-192-168-92-187
php-apache-8699449574-dn9tb 1/1 Terminating 0 26m 192.168.124.108 ip-192-168-92-187
php-apache-8699449574-k5ngv 1/1 Terminating 0 26m 192.168.108.58 ip-192-168-92-187
...
複製程式碼

8. CA 檢測到一個節點未充分使用,正在執行的pod能夠排程到其他節點上。

$ kubectl get nodes
NAME                             STATUS    ROLES     AGE       VERSION
ip-192-168-189-29.ec2.internal   Ready         2h        v1.10.3
ip-192-168-200-20.ec2.internal   Ready         2h        v1.10.3
ip-192-168-92-187.ec2.internal   NotReady       23m       v1.10.3

$ kubectl get nodes
NAME                             STATUS    ROLES     AGE       VERSION
ip-192-168-189-29.ec2.internal   Ready         2h        v1.10.3
ip-192-168-200-20.ec2.internal   Ready         2h        v1.10.3
複製程式碼

9. 在向下縮放的時候,terminal中應該沒有明顯的timeout

Kubernetes Autoscaling 測試用例 #2

測試在如果沒有足夠的CPU容量排程pod下,CA是否能夠自動調整叢集的大小

要求:

  • 一個執行中的aws eks叢集
  • Kubernetes ca 特性已安裝

1. 建立2個請求小於1vcpu的deployment

$ kubectl run nginx --image=nginx:latest --requests=cpu=200m
$ kubectl run nginx2 --image=nginx:latest --requests=cpu=200m
複製程式碼

2. 建立一個新的deployment,請求比剩餘的cpu更多的資源

$ kubectl run nginx3 --image=nginx:latest --requests=cpu=1
複製程式碼

3. 新的POD會處於等待狀態,因為沒有可用的資源:

$ kubectl get Pods -w
NAME                      READY     STATUS    RESTARTS   AGE
nginx-5fcb54784c-lcfht    1/1       Running   0          13m
nginx2-66667bf959-2fmlr   1/1       Running   0          3m
nginx3-564b575974-xcm5t   0/1       Pending   0          41s
複製程式碼

描述pod的時候,可能會看到沒有足夠的cpu的事件

$ kubectl describe Pod nginx3-564b575974-xcm5t
…..
…..
Events:
Type     Reason            Age               From               Message
----     ------            ----              ----               -------
Warning  FailedScheduling  32s (x7 over 1m)  default-scheduler  0/1 nodes are available: 1 Insufficient cpu
複製程式碼

4. CA自動調整叢集的大小, 新加了一個節點

$ kubectl get nodes
NAME                              STATUS    ROLES     AGE       VERSION
ip-192-168-142-179.ec2.internal   Ready         1m        v1.10.3  <<
ip-192-168-82-136.ec2.internal     Ready         1h        v1.10.3
複製程式碼

5. 叢集現在有了足夠的資源以執行pod

$ kubectl get Pods
NAME                      READY     STATUS    RESTARTS   AGE
nginx-5fcb54784c-lcfht    1/1       Running   0          48m
nginx2-66667bf959-2fmlr   1/1       Running   0          37m
nginx3-564b575974-xcm5t   1/1       Running   0          35m
複製程式碼

6. 兩個部署刪除了。 一段時間後,CA檢測到叢集中的一個節點未被充分利用,執行的pod可以安置到其他存在的節點上。AWS AG 更新,節點數量減1。

$ kubectl get nodes
NAME                                      STATUS    ROLES     AGE       VERSION
ip-192-168-82-136.ec2.internal   Ready         1h          v1.10.3 

$ kubectl get Pods -o wide
NAME                        READY     STATUS    RESTARTS   AGE       IP                       NODE
nginx-5fcb54784c-lcfht   1/1       Running     0                   1h       192.168.98.139   ip-192-168-82-136
複製程式碼

清除環境的步驟:

  1. 刪除新增到eks worker節點上Role的自定義策略
  2. 按照這個指南刪除這個叢集

參考

其他的關於kubernetes autoscaling,可以閱讀Stefan Prodan的文章 Kubernetes Horizontal Pod Autoscaler with Prometheus Custom Metrics

還有這些連結也可以看看 link1,link2,link3

關於 ServiceMesher 社群

ServiceMesher 社群是由一群擁有相同價值觀和理念的志願者們共同發起,於 2018 年 4 月正式成立。

社群關注領域有:容器、微服務、Service Mesh、Serverless,擁抱開源和雲原生,致力於推動 Service Mesh 在中國的蓬勃發展。

社群官網:www.servicemesher.com

ServiceMesher 社群