Skip to main content

第 4 章: 實現 Pod 水平擴展

Horizontal Pod Autoscaling 水平擴展

在目前許多第三方雲端服務供應商也都提供 Autosacling 的功能,像是 AWS 或是 Google Cloud Platfrom。而 Kubernetes 本身也提供一個 API - Horizontal Pod Autoscaling,讓我們可以針對不同的 Pod 的使用量,來決定是否新增或減少 Pod 的數量。

helloworld-deployment.yaml 
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: helloworld-deployment
spec:
replicas: 2
selector:
matchLabels:
app: helloworld-pod
template:
metadata:
labels:
app: helloworld-pod
spec:
containers:
- name: my-pod
image: zxcvbnius/docker-demo:latest
ports:
- containerPort: 3000
resources:
requests:
cpu: 200m

可以發現,在 spec 的地方多了一個 resources 的欄位,

  • spec.resources.requests.cpu:透過該欄位的設置,代表當 Kubernetes 在運行該 Pod 時,需要配置 200m CPU 給該 Pod。200m 同等於 200milicpu(milicore),代表要求一個 CPU 20% 的資源。然而直得注意的是,若該 Node 是多核(multiple cores),則 200m 代表要求使用每一核(core)百分之二十的資源。更多關於 spec.resources.requests 可以參考該連結
helloworld-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: helloworld-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1beta2
kind: Deployment
name: helloworld-deployment
minReplicas: 2
maxReplicas: 5
targetCPUUtilizationPercentage: 50

  • spec.scaleTargetRef

    指定 autoscaling 的對象

  • spec.targetCPUUtilizationPercentage

    以 helloworld-deployment 為例,我們指定 CPU 200m 的資源,代表當該 helloworld-pod CPU 使用率達到 100 m 時,HorizontalPodAutoscaler 就會幫我們新產生一個 Pod

支持 Colddown / Delay

Horizontal Pod Autoscaling 也支援 Colddown 與 Delay,避免 Horizontal Pod Autoscaling 一次產生太多 Pod 或是關掉太多 Pod。在建立 Kubernetes Cluster 時,可以加入 --horizontal-pod-autoscaler-downscale-delay 與 --horizontal-pod-autoscaler-upscale-delay 去限制 Autoscaling 的回應時間。

  • -horizontal-pod-autoscaler-downscale-delay
    • 代表 autoscaling 須等多久的時間才能進行 downscale,預設為 5 分鐘
  • -horizontal-pod-autoscaler-upscale-delay
    • 代表 autoscaling 須等多久的時間才能進行 upscale,預設為 3 分鐘

實作:在 minikube 中實現 Horizontal Pod Autoscaling

使用 Horizontal Pod Autoscaling 之前,minikube 必須先安裝好 heapster ,讓 Horizontal Pod Autoscaling 可以知道目前 Kubernetes Cluster 中的資源使用狀況

透過 kubectl create 創建 helloworld-deployment,指令如下,

kubectl create -f ./helloworld-depolyment.yaml
deployment "hello-deployment" created

接著創建一個 helloworld-service ,讓 Kubernetes Cluster 中的其他物件可以訪問到 helloworld-deployment,指令如下:

kubectl expose deploy helloworld-deployment \
> --name helloworld-service \
> --type=ClusterIP
service "helloworld-service" exposed
kubectl get deploy,svc
kubectl create -f ./helloworld-hpa.yaml
horizontalpodautoscaler "helloworld-hpa" created
kubectl get deploy, hpa

可以看到 TARGETS 的欄位目前是,<unknown> / 50%。稍等久一點,等 helloworld-hpa 從 heapster 抓到目前的資料則可看到數字的變化

kubectl get deploy,hpa

從 Grafana 也可以觀察到 helloworld-deployment 的狀態,正如我們在 YAML 設定檔要求 200 milicores,目前的使用率為 0%

要在 minikube 裡面運行一個 server 不斷去訪問 helloworld-pod 使 CPU 的使用率超過 100 m,再來觀察 helloworld-hpa 是否會偵測到幫我們新增 Pod,指令如下:

kubectl run -i --ttyalpine --image=alpine --restart=Never --sh

接著安裝 curl 套件,後訪問 helloworld-service,會吐回 Hello World! 的字串,

curl http://10.108.56.58:3000
Hello World!

接著,我們設置一個無窮迴圈,透過 curl 不斷送請求給 helloworld-deployment,指令如下,

while true; do curl http://10.108.56.58:3000; done

接著,再回頭看 helloworld-hpa 的狀態,可以發現目前 CPU 的使用率以超出我們所設定的 50%

kubectl get deploy,hpa

若再觀察一陣子,會看到 helloworld-deployment底下已有 4 個 Pod,代表 helloworld-hpa 幫我們實現了 Autoscaling

kubectl get deploy,hpa

我們停止 curl 指令,過了一陣子之後可以發現原本 4 個 Pod 已經退回到原本設定的 2 個了

kubectl get deploy,hpa

使用 kubectl 命令進行創建

kubectl autoscale deployment php-apache --min=1 --max=10 --cpu-percetnage=50