1. 程式人生 > >kubernetes資源物件--Horizontal Pod Autoscaling(HPA)

kubernetes資源物件--Horizontal Pod Autoscaling(HPA)

下文基於kubernetes 1.5.2版本編寫

概念

HPA全稱Horizontal Pod Autoscaling,即pod的水平自動擴充套件。自動擴充套件主要分為兩種,其一為水平擴充套件,針對於例項數目的增減;其二為垂直擴充套件,即單個例項可以使用的資源的增減。HPA屬於前者。

HPA的操作物件是RC、RS或Deployment對應的Pod,根據觀察到的CPU等實際使用量與使用者的期望值進行比對,做出是否需要增減例項數量的決策。

原理

它根據Pod當前系統的負載來自動水平擴容,如果系統負載超過預定值,就開始增加Pod的個數,如果低於某個值,就自動減少Pod的個數。目前K8S的HPA只能根據CPU等資源使用情況去度量系統的負載,而且目前還依賴heapster去收集CPU的使用情況。

條件

HPA通過定期(定期輪詢的時間通過–horizontal-pod-autoscaler-sync-period選項來設定,預設的時間為30秒)通過Status.PodSelector來查詢pods的狀態,獲得pod的CPU使用率。然後,通過現有pods的CPU使用率的平均值(計算方式是最近的pod使用量(最近一分鐘的平均值,從heapster中獲得)除以設定的每個Pod的CPU使用率限額)跟目標使用率進行比較,並且在擴容時,還要遵循預先設定的副本數限制:MinReplicas <= Replicas <= MaxReplicas。

計算擴容後Pod的個數:sum(最近一分鐘內某個Pod的CPU使用率的平均值)/CPU使用上限的整數+1

流程

1、建立HPA資源,設定目標CPU使用率限額,以及最大、最小例項數
2、收集一組中(PodSelector)每個Pod最近一分鐘內的CPU使用率,並計算平均值
3、讀取HPA中設定的CPU使用限額
4、計算:平均值之和/限額,求出目標調整的例項個數
5、目標調整的例項數不能超過1中設定的最大、最小例項數,如果沒有超過,則擴容;超過,則擴容至最大的例項個數
6、回到2,不斷迴圈

例外

考慮到自動擴充套件的決策可能需要一段時間才會生效,甚至在短時間內會引入一些噪聲。例如當pod所需要的CPU負荷過大,從而執行一個新的pod進行分流,在建立過程中,系統的CPU使用量可能會有一個攀升的過程。所以,在每一次作出決策後的一段時間內,將不再進行擴充套件決策。對於ScaleUp而言,這個時間段為3分鐘,Scaledown為5分鐘。

HPA允許一定範圍內的CPU使用量的不穩定,只有avg(CurrentPodsConsumption) / Target小於90%或者大於110%時才會觸發擴容或縮容,避免頻繁擴容、縮容造成顛簸。

為什麼選擇相對比率

為了簡便,選用了相對比率(90%的CPU資源)而不是0.6個CPU core來描述擴容、縮容條件。如果選擇使用絕對度量,使用者需要保證目標(限額)要比請求使用的低,否則,過載的Pod未必能夠消耗那麼多,從而自動擴容永遠不會被觸發:假設設定CPU為1個核,那麼這個pod只能使用1個核,可能Pod在過載的情況下也不能完全利用這個核,所以擴容不會發生。在修改申請資源時,還有同時調整擴容的條件,比如將1個core變為1.2core,那麼擴容條件應該同步改為1.2core,真是太麻煩了,與自動擴容的目標相悖。

例項

建立Deployment

kubectl delete -f lykops-hpa-deploy.yaml
cat << EOF > lykops-hpa-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: lykops-hpa-deploy
  labels:
    software: apache
    project: lykops
    app: hpa
    version: v1      
spec:
  replicas: 1 
  selector:
    matchLabels:
      name: lykops-hpa-deploy
      software: apache
      project: lykops
      app: hpa
      version: v1
  template:
    metadata:
      labels:
        name: lykops-hpa-deploy
        software: apache
        project: lykops
        app: hpa
        version: v1
    spec:
      containers:
      - name: lykops-hpa-deploy
        image: web:apache
        command: [ "sh", "/etc/run.sh" ]
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        resources:
          requests:
            cpu: 0.001
            memory: 4Mi
          limits:
            cpu: 0.01
            memory: 16Mi
EOF
kubectl create -f lykops-hpa-deploy.yaml --record

建立service

cat << EOF > lykops-hpa-deploy-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: lykops-hpa-svc
  labels:
    software: apache
    project: lykops
    app: hpa
    version: v1
spec:
  selector:
    software: apache
    project: lykops
    app: hpa
    version: v1
    name: lykops-hpa-deploy
  ports:
  - name: http
    port: 80
    protocol: TCP
EOF
kubectl create -f lykops-hpa-deploy-svc.yaml

建立HPA

kubectl delete -f lykops-hpa.yaml
cat << EOF > lykops-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: lykops-hpa
  labels:
    software: apache
    project: lykops
    app: hpa
    version: v1
spec:
  scaleTargetRef:
    apiVersion: v1
    kind: Deployment
    name: lykops-hpa-deploy
    #這裡只能為這三項
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 5
EOF
kubectl create -f lykops-hpa.yaml

測試

多臺機器不斷訪問service的clusterIP地址,然後可以看出是否增加pod數了