做者;Juan Ignacio Giro 譯者:段訪 審校:羅廣明 原文: caylent.com/kubernetes-…php
許多Kubernetes用戶,特別是那些企業級用戶,很快就遇到了對環境自動縮放的需求。幸運的是,Kubernetes Horizontal Pod Autoscaler(HPA)容許您將部署配置爲以多種方式水平擴展。使用Kubernetes Autoscaling的最大優點之一是您的集羣能夠跟蹤現有Pod的負載能力,並計算是否須要更多的Pod。html
經過協調內置的兩層可擴展性,能夠充分利用高效的Kubernetes Autoscaling:node
HPA會在集羣中縮放Pod副本的數量。該操做由CPU或內存觸發,以根據須要向上或向下擴展。可是,也能夠根據各類外部的和自定義指標(metrics.k8s.io,external.metrics.k8s.io和custom.metrics.k8s.io)來配置HPA以擴展Pod。linux
VPA主要用於有狀態服務,它可根據須要爲Pod添加CPU或內存——它也適用於無狀態的Pod。爲了應用這些更改,VPA從新啓動Pod以更新新的CPU和內存資源,這些資源能夠配置爲響應OOM(內存不足)事件而啓動。從新啓動Pod的時候,VPA始終確保根據Pod分配預算(PDB)肯定最小數量,您能夠設置該資源分配最大和最小速率。nginx
第二層的自動縮放涉及CA,它在如下狀況下自動調整集羣的大小:git
CA進行例行檢查以肯定是否有任何pod因等待額外資源處於待定狀態,或者集羣節點是否未獲得充分利用。若是須要更多資源,會相應地調整Cluster節點的數量。CA與雲提供商交互以請求其餘節點或關閉空閒節點,並確保按比例放大的集羣保持在用戶設置的限制範圍內。它適用於AWS,Azure和GCP。github
本文提供了經過適用於Kubernetes(Amazon EKS)集羣的Amazon Elastic容器服務,經過HPA和CA安裝和自動擴展的分步指南。如下指南是兩個測試用例示例:apache
1. 根據官方指南建立一個AWS EKS 集羣(控制面板和和工做節點). 一旦你把工做節點以auto scaling group的形式啓動了,它們會自動向EKS集羣註冊,你就能夠開始部署k8s應用了。api
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/
測試k8s hpa 特性和k8s ca 特性同時使用
要求:
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
測試在若是沒有足夠的CPU容量調度pod下,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
複製代碼
清除環境的步驟:
其餘的關於kubernetes autoscaling,能夠閱讀Stefan Prodan的文章 Kubernetes Horizontal Pod Autoscaler with Prometheus Custom Metrics。
還有這些連接也能夠看看 link1, link2, link3。
ServiceMesher 社區是由一羣擁有相同價值觀和理念的志願者們共同發起,於 2018 年 4 月正式成立。
社區關注領域有:容器、微服務、Service Mesh、Serverless,擁抱開源和雲原生,致力於推進 Service Mesh 在中國的蓬勃發展。