- Pod的擴容和縮容
在實際生產系統中,我們經常會遇到某個服務需要擴容的場景,也可能遇到由於資源緊張或者負載降低而需要減少服務實例數量的場景。此時我們可以利用RC的scale機制來完成這些工作。
以《從一個例子開始認識Kubernetes》中myweb的RC為例,已定義的最初副本數量為2,通過kubectl scale 命令可以將其控制的Pod數量從2變為3,也可以從3變成1。
1 [root@localhost ~]# kubectl get po 2 NAME READY STATUS RESTARTS AGE 3 mysql-px9th 1/1 Running 0 1d 4 myweb-fxq9s 1/1 Running 0 1d 5 myweb-tt5sd 1/1 Running 0 1d 6 [root@localhost ~]# kubectl scale rc myweb --replicas=3 7 replicationcontroller "myweb" scaled 8 [root@localhost ~]# kubectl get po 9 NAME READY STATUS RESTARTS AGE 10 mysql-px9th 1/1 Running 0 1d 11 myweb-fxq9s 1/1 Running 0 1d 12 myweb-rkg9m 1/1 Running 0 33s 13 myweb-tt5sd 1/1 Running 0 1d 14 [root@localhost ~]# kubectl scale rc myweb --replicas=1 15 replicationcontroller "myweb" scaled 16 [root@localhost ~]# kubectl get po 17 NAME READY STATUS RESTARTS AGE 18 mysql-px9th 1/1 Running 0 1d 19 myweb-tt5sd 1/1 Running 0 1d
Horizontal Pod Autoscaler(HPA)
對於Kubernetes中的Pod集群來說,HPA可以實現很多自動化功能,比如當Pod中業務負載上升的時候,可以創建新的Pod來保證業務系統穩定運行,當Pod中業務負載下降的時候,可以銷毀Pod來提高資源利用率。HPA控制器默認每隔30秒就會運行一次。 如果要修改間隔時間,可以設置horizontal-pod-autoscaler-sync-period參數。HPA的操作對象是RC、RS或Deployment對應的Pod 根據觀察到的CPU等實際使用量與用戶的期望值進行比對,做出是否需要增減實例數量的決策。
在Kubernetes v1.1中首次引入了hpa特性。hpa第一個版本基於觀察到的CPU利用率,后續版本支持基於內存使用。 在Kubernetes 1.6中引入了一個新的API自定義指標API,它允許HPA訪問任意指標。 Kubernetes 1.7引入了聚合層,允許第三方應用程序通過注冊為API附加組件來擴展Kubernetes API。自定義指標API以及聚合層使得像Prometheus這樣的監控系統可以向HPA控制器公開特定於應用程序的指標。
直接通過kubectl autoscale直接創建
1 ]# docker pull siriuszg/hpa-example 2 ]# kubectl get pod,deployment,svc 3 ]# kubectl run php-apache --image=siriuszg/hpa-example --requests=cpu=50m --expose --port=80 4 ]# kubectl autoscale deployment php-apache --cpu-percent=10 --min=1 --max=3
通過yaml文件創建
創建RC
1 apiVersion: v1 2 kind: ReplicationController 3 metadata: 4 name: php-apache 5 spec: 6 replicas: 1 7 template: 8 metadata: 9 name: php-apache 10 labels: 11 app: php-apache 12 spec: 13 containers: 14 - name: php-apache 15 image: gcr.io/google_containers/hpa-example:latest 16 imagePullPolicy: IfNotPresent 17 resources: 18 requests: 19 cpu: 200m 20 ports: 21 - containerPort: 80
創建SVC
1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: php-apache 5 labels: 6 k8s-app: php-apache 7 spec: 8 ports: 9 # The port that this service should serve on. 10 - port: 80 11 # Label keys and values that must match in order to receive traffic for this service. 12 selector: 13 app: php-apache
創建HPA
1 apiVersion: autoscaling/v1 2 kind: HorizontalPodAutoscaler 3 metadata: 4 name: php-apache 5 namespace: default 6 spec: 7 scaleTargetRef: 8 apiVersion: v1 9 kind: ReplicationController 10 name: php-apache 11 minReplicas: 1 12 maxReplicas: 10 13 targetCPUUtilizationPercentage: 50
使用kubectl create創建yaml文件
1 ]# kubectl create -f php-rc.yaml 2 ]# kubectl create -f php-svc.yaml 3 ]# kubectl create -f hpa-example.yaml
進行壓力測試
1 kubectl run -i --tty load-generator --image=busybox:latest /bin/sh #進入容器后執行一下命令 2 while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
壓測幾分鍾后查看hpa狀態,如果cpu壓力超過了設置的閾值,可以停止壓測。
查看hpa狀態已經超過了閾值,此時查看pod,pod的數量已經增加了。
當停止壓力測試之后,過一段時間,Pod數量又會恢復到1。
- Pod的滾動升級
當集群中的某個服務需要升級時,我們需要停止目前與該服務相關的所有Pod,然后重新拉取鏡像並啟動。如果集群規模比較大,則這樣操作就比較困難,Kubernetes提供了rolling-update功能來解決這個困難。
滾動升級通過執行命令kubectl rolling-update命令一鍵完成,改命令會創建一個新的RC,然后控制舊的RC中的Pod數量逐漸減少到0,同時新的RC中的Pod數量逐漸增加到目標值,最終實現Pod升級。(注:新舊RC需在同一個Namespace中)
1 示例: 2 // 更新frontend-v1的pod到frontend-v2 3 $ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 4 // 更新frontend的pods,不更改replication controller的名稱 5 $ kubectl rolling-update frontend --image=image:v2
例如運行一個1.7.9版本的nginx
1 apiVersion: v1 2 kind: ReplicationController 3 metadata: 4 name: my-nginx 5 spec: 6 replicas: 5 7 template: 8 metadata: 9 labels: 10 app: nginx 11 spec: 12 containers: 13 - name: nginx 14 image: nginx:1.7.9 15 ports: 16 - containerPort: 80
更新到1.9.1版本
1 ]# kubectl rolling-update my-nginx --image=nginx:1.9.1
更新過程如圖:
如果遇到問題可以使用--rollback 回滾。
如果你不僅僅是需要更新鏡像,(例如,更新命令參數,環境變量等),你可以創建一個新的replication controller配置文件,包含一個新的名稱和不同的標簽值,例如:
1 apiVersion: v1 2 kind: ReplicationController 3 metadata: 4 name: my-nginx-v4 5 spec: 6 replicas: 5 7 selector: 8 app: nginx 9 deployment: v4 10 template: 11 metadata: 12 labels: 13 app: nginx 14 deployment: v4 15 spec: 16 containers: 17 - name: nginx 18 image: nginx:1.9.2 19 args: ["nginx", "-T"] 20 ports: 21 - containerPort: 80
1 ]# kubectl rolling-update my-nginx -f ./nginx-rc.yaml
注:
如果更新過程中,達到超時時長timeout
后還沒更新完成,則更新會失敗。這時,一些pod會屬於新的replication controller,一些會屬於舊的。
如果更新失敗,可以嘗試使用同樣的命令來繼續更新過程。
在嘗試更新之前如果需要回滾到之前的狀態,可在之前的命令后面添加--rollback=true
參數,這將回退所有的更改。