Kubernetes Expansion and Contraction
Kubernetes Expansion and Contraction
在實(shí)際生產(chǎn)系統(tǒng)中,經(jīng)常會(huì)遇到某個(gè)服務(wù)需要擴(kuò)容的場(chǎng)景, 也可能會(huì)遇到由于資源緊張或者工作負(fù)載降低而需要減少服務(wù)示例數(shù)量的場(chǎng)景。因此可以利用 Deployment/RC 的 Scale 機(jī)制來(lái)完成這些工作。
Kubernetes 的 Pod 的擴(kuò)容和縮容操作提供了手動(dòng)和自動(dòng)兩種,手動(dòng)模式提供執(zhí)行 kubectl 命令對(duì)一個(gè) Deployment/RC 進(jìn)行 Pod 副本數(shù)量的設(shè)置,即可一鍵完成。自動(dòng)模式則需要用戶根據(jù)某個(gè)性能指標(biāo)或者自定義業(yè)務(wù)指標(biāo),并制定 Pod 副本數(shù)量的范圍,系統(tǒng)將自動(dòng)在這個(gè)范圍內(nèi)根據(jù)性能指標(biāo)的變化進(jìn)行調(diào)整。
手動(dòng)擴(kuò)容和縮容模式
在 Deployment Nginx 為例:
nginx-deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
??name: nginx-deployment
spec:
??replicas: 3
??template:
????metadata:
??????labels:
????????app: nginx
????spec:
??????containers:
??????- name: nginx
????????image: nginx:1.7.9
????????ports:
????????- containerPort: 80
創(chuàng)建服務(wù):
$ kubectl apply -f nginx-deployment.yaml
deployment?"nginx-deployment"?created
已運(yùn)行的 Pod 副本數(shù)量為 3 個(gè):
$ kubectl get pods
NAME??????????????????????????????? READY???? STATUS??? RESTARTS?? AGE
nginx-deployment-569477d6d8-44xsn?? 1/1?Running?? 0????????? 27s
nginx-deployment-569477d6d8-g4b8f?? 1/1?Running?? 0????????? 27s
nginx-deployment-569477d6d8-sdfsm?? 1/1?Running?? 0????????? 27s
通過(guò) kubectl scale 命令可以將 Pod 副本數(shù)量從初始的 3 更新為 5:
$ kubectl scale deployment nginx-deployment --replicas 5
deployment?"nginx-deployment"?scaled
查看 Pod 數(shù)量:
$ kubectl get pods
NAME??????????????????????????????? READY???? STATUS??? RESTARTS?? AGE
nginx-deployment-569477d6d8-44xsn?? 1/1?Running?? 0????????? 1m
nginx-deployment-569477d6d8-bqm2b?? 1/1?Running?? 0????????? 16s
nginx-deployment-569477d6d8-dmgfk?? 1/1?Running?? 0????????? 16s
nginx-deployment-569477d6d8-g4b8f?? 1/1?Running?? 0????????? 1m
nginx-deployment-569477d6d8-sdfsm?? 1/1?Running?? 0????????? 1m
將 --replicas 設(shè)置為比當(dāng)前 Pod 副本數(shù)量更小的數(shù),系統(tǒng)會(huì)將 “殺掉” 一些運(yùn)行中的 Pod,以實(shí)現(xiàn)應(yīng)用集群縮容:
$ kubectl scale deployment nginx-deployment --replicas=1
deployment?"nginx-deployment"?scaled
$ kubectl get pods
NAME??????????????????????????????? READY???? STATUS??????? RESTARTS?? AGE
nginx-deployment-569477d6d8-44xsn?? 0/1?Terminating?? 0????????? 3m
nginx-deployment-569477d6d8-bqm2b?? 0/1?Terminating?? 0????????? 1m
nginx-deployment-569477d6d8-dmgfk?? 0/1?Terminating?? 0????????? 1m
nginx-deployment-569477d6d8-g4b8f?? 0/1?Terminating?? 0????????? 3m
nginx-deployment-569477d6d8-sdfsm?? 1/1?Running?????? 0????????? 3m
自動(dòng)擴(kuò)容和伸縮模式
從 Kubernetes v1.1 版本開(kāi)始,新增了名為?Horizontal Pod Autoscaler(HPA)的控制器,用于實(shí)現(xiàn)基于 CPU 使用率自動(dòng) Pod 擴(kuò)容和縮容的功能。HPA 控制器基于 Master 的 kube-controller-manager 服務(wù)啟動(dòng)參數(shù) --horizontal-pod-autoscaler-sync-period 定義的時(shí)長(zhǎng)(默認(rèn)值為 30s),周期性的檢測(cè)目標(biāo) Pod 的 CPU 使用率,并在滿足條件時(shí)對(duì) ReplicationController 或 Deployment 中的 Pod 副本數(shù)量進(jìn)行調(diào)整,已復(fù)核用戶定義的平均 Pod CPU 使用率。Pod CPU 使用率來(lái)源于 Heapster 組件,所以需要預(yù)先安裝好 Heapster。
創(chuàng)建 HPA 時(shí)可以使用 kubectl autoscale 命令快速創(chuàng)建或者使用 yaml 配置文件進(jìn)行創(chuàng)建。
在創(chuàng)建 HPA 之前,需要一件存在一個(gè) Deployment/RC 對(duì)象,并且該 Deployment/RC 中的 Pod 必須定義 resources.requests.cpu 的資源請(qǐng)求值,如果不設(shè)置該值,則 Heapster 將無(wú)法采集到該 Pod 的 CPU 使用情況,會(huì)導(dǎo)致 HPA 無(wú)法正常工作。
下面通過(guò)為一個(gè) RC 設(shè)置 HPA,然后使用一個(gè)客戶端對(duì)其進(jìn)行壓力測(cè)試,對(duì) HPA 的用法進(jìn)行示例。
以 php-apache 的 Deployment 為例,使用 cpu request 為 200m,為設(shè)置 limit 上限的值:
php-apache-deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
??name: php-apache
spec:
??replicas: 1
??template:
????metadata:
??????name: php-apache
??????labels:
????????app: php-apache
????spec:
??????containers:
??????- name: php-apache
????????image: gcr.io/google_containers/hpa-example
????????resources:
??????????requests:
????????????cpu: 200m
????????ports:
????????- containerPort: 80
創(chuàng)建服務(wù):
$ kubectl apply -f php-apache-deployment.yaml
deployment?"php-apache"?created
再創(chuàng)建一個(gè) php-apache 的 Service,提供客戶端訪問(wèn):
php-apache-svc.yaml
apiVersion: v1
kind: Service
metadata:
??name: php-apache
spec:
??ports:
??- port: 80
??selector:
????app: php-apache
創(chuàng)建服務(wù):
$ kubectl apply -f php-apache-svc.yaml
service?"php-apache"?created
接下來(lái)為 Deployment 創(chuàng)建一個(gè) HPA 控制器,在 1 和 10 之間調(diào)整 Pod 的副本數(shù)量,使得平均 Pod CPU 使用率維持在 50%。
使用 kubectl autoscale 命令進(jìn)行創(chuàng)建:
$ kubectl autoscale deployment php-apache --min=1 --max=10 --cpu-percent=50
deployment?"php-apache"?autoscaled
或者通過(guò) yaml 配置文件來(lái)創(chuàng)建 HPA,需要在 scaleTargetRef 字段指定需要管理 Deployment/RC 的名字,然后設(shè)置 minReplicas、maxReplicas 和 targetCPUUtilizationPercentage 參數(shù):
hpa-php-apache.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
??name: php-apache
spec:
??scaleTargetRef:
????apiVersion: apps/v1beta1
????kind: Deployment
????name: php-apache
??minReplicas: 1
??maxReplicas: 10
??targetCPUUtilizationPercentage: 50
創(chuàng)建服務(wù):
$ kubectl create -f hpa-php-apache.yaml
horizontalpodautoscaler?"php-apache"?configured
查看已經(jīng)創(chuàng)建的 HPA:
$ kubectl get hpa
NAME???????? REFERENCE?????????????? TARGETS?????????? MINPODS?? MAXPODS?? REPLICAS?? AGE
php-apache?? Deployment/php-apache?<unknown> / 50%?? 1???????? 10??????? 1????????? 4m
然后創(chuàng)建一個(gè) busybox Pod,用戶對(duì) php-apache 服務(wù)發(fā)起壓力測(cè)試的請(qǐng)求:
busybox-pod.yaml
apiVersion: v1
kind: Pod
metadata:
??name: busybox
spec:
??containers:
??- name: busybox
????image: busybox
????command: ["sleep",?"3600"]
創(chuàng)建服務(wù):
$ kubectl create -f busybox-pod.yaml
pod?"busybox"?created
進(jìn)入 busybox 容器,執(zhí)行一個(gè)無(wú)限循環(huán)的 wgat 命令來(lái)訪問(wèn) php-apache 服務(wù):
$ kubectl?exec?-it busybox sh
$?while?true;?do?wget -q -O- http://php-apache?>?/dev/null;?done
注意這里 wget 的目的 URL 地址是 Service 的名稱 “php-apache”,這要求 DNS 服務(wù)正常工作,也可以使用 Service 的虛擬 ClusterIP 地址對(duì)其進(jìn)行訪問(wèn),例如http://169.169.122.145:
等待一段時(shí)間后,觀察 HPA 控制器搜集到的 Pod CPU 使用率:
$ kubectl get hpa
再過(guò)一會(huì),查看 Deployment 副本數(shù)的變化:
$ kubectl get deployment php-apache
可以看到 HPA 已經(jīng)根據(jù) Pod 的 CPU 使用率的提高對(duì) Deployment 進(jìn)行了自動(dòng)擴(kuò)容,Pod 的副本數(shù)量變成了 10 個(gè)。
最后停止壓力測(cè)試,在 busybox 的控制臺(tái)輸入 Ctrl+C,停止無(wú)限循環(huán)操作。
等待一段時(shí)間,觀察 HPA 的變化:
$ kubectl get hpa
再次查看 Deployment 的副本數(shù)量:
$ kubectl get deployment php-apache
可以看到 HPA 根據(jù) Pod CPU 使用率的降低對(duì)副本數(shù)量進(jìn)行了縮容操作,Pod 副本數(shù)量變成了 1 個(gè)。
當(dāng)前 HPA 還只支持將 CPU 使用率作為 Pod 副本擴(kuò)容和縮容的觸發(fā)條件,在將來(lái)的版本中,將會(huì)支持應(yīng)用自定義指標(biāo)(例如每秒請(qǐng)求數(shù)量、請(qǐng)求平均響應(yīng)時(shí)間或其他業(yè)務(wù)指標(biāo))作為觸發(fā)條件。