天天看點

Kubernetes彈性伸縮全場景解讀(九)- 彈性負載kubernetes-elastic-workload釋出

前言

彈性伸縮是Kubernetes中比較常用的功能。在Kubernetes中,彈性是分為兩個層次的,一個是排程層(Pod)彈性,一個是資源層(Node)彈性。通常會通過HPA、CronHPA、VPA等模型進行Pod的橫向或者縱向的伸縮,再通過

cluster-autoscaler

或者

virtual-kubelet

進行資源層伸縮。兩層之間是通過無法排程的

Pod

進行解耦,這樣設計的好處是兩層職責明确,壞處是解耦後互相結合的政策過于簡單,一旦當我們需要更精細的排程政策就無能為力了,因為在Kubernetes中最小的生命周期管理單元是一個Pod,而傳統的Kubernetes負載控制器(例如:Deployment、StatefulSet)管理的Pod是共享相同的排程政策的。是以,當你希望控制一個負載在不同資源上的細粒度配置設定時,就無能為力了。然而這種場景又是在彈性伸縮中經常遇到的。是以,為了解決應用負載彈性場景下精細化排程的訴求,

kubernetes-elastic-workload

應運而生了。

彈性伸縮精細化排程的問題分析

假設:有一個應用經過容量規劃,預計最多有4個副本運作在ECS上,平時低峰時保留2個副本,超過4個副本的場景彈性伸縮到虛拟節點,防止幹擾其他正常容量規劃的應用。

在Kubernetes中,任何一種負載都要解決兩個問題,一個是排程問題,一個是生命周期管理問題。要想實作上面描述的場景,我們核心要解決的問題是兩個:

  1. 如何控制副本到達一個數目後,排程政策的變化。
  2. 如何在生命周期管理時,優先處理某些Pod。

彈性負載kubernetes-elastic-workload介紹

接下來,我們針對上面的問題介紹下彈性負載的使用方式與解決方法。

# 一個簡單的應用,預設使用2副本
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nginx-deployment-basic
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9 
        ports:
        - containerPort: 80           

那麼這個場景如何用彈性負載表達呢?

# 彈性負載定義
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: ElasticWorkload
metadata:
  name: elasticworkload-sample
spec:
  sourceTarget:
    name: nginx-deployment-basic
    kind: Deployment
    apiVersion: apps/v1
    min: 2
    max: 4
  replicas: 6
  elasticUnit:
  - name: virtual-kubelet
    labels:
      virtual-kubelet: "true"
    annotations:
      virtual-kubelet: "true"
    nodeSelector:
      type: "virtual-kubelet"
    tolerations:
    - key: "virtual-kubelet.io/provider"
      operator: "Exists"
    # min: 0 每個單元也可以指定自己的上下限
    # max: 10           

上面就是這個場景的彈性負載定義,彈性負載的使用方式特别像HPA,他是通過外部挂載的方式使用,對原有的業務無侵入。一個典型的彈性負載主要分為兩個部分:

  1. SourceTarget部分主要定義原始負載的類型、副本數目可變化的範圍。
  2. elasticUnit部分是一個數組,定義彈性單元的排程政策,如果有多個彈性單元,則按照模闆的順序定義。

在上面的例子中,SourceTarget的副本上下限位2-4,表示當ElasticWorkload的replicas為2-4個副本時,會配置設定到sourceTarget,當超過4個副本時,會分為給彈性單元virtual-kubelet,而在彈性單元virtual-kubelet中可以定義這個單元所獨有的排程政策,包含

label

annotation

nodeSelector

affinity

toleration

等。

Kubernetes彈性伸縮全場景解讀(九)- 彈性負載kubernetes-elastic-workload釋出

簡單的了解就是,彈性負載會監聽原始負載,并根據彈性單元設定的排程政策,克隆并生成彈性單元的負載,并且根據彈性負載中副本的變化,動态的配置設定原始負載和彈性單元上面的副本數目。執行彈性負載模闆後,我們可以通過指令行檢視目前的狀态,其中status中的每個單元的

Desired Replicas

表示彈性負載的配置設定副本數目。

kubectl describe ew elasticworkload-sample   # same as kubectl get elasticworkload

Name:         elasticworkload-sample
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  autoscaling.alibabacloud.com/v1beta1
Kind:         ElasticWorkload
Metadata:
  Creation Timestamp:  2020-05-06T03:43:41Z
  Generation:          27
  Resource Version:    20635284
  Self Link:           /apis/autoscaling.alibabacloud.com/v1beta1/namespaces/default/elasticworkloads/elasticworkload-sample
  UID:                 0e9205ff-38b8-43b7-9076-ffa130f26ef4
Spec:
  Elastic Unit:
    Annotations:
      Virtual - Kubelet:  true
    Labels:
      Virtual - Kubelet:  true
    Name:                 demo
    Node Selector:
      Type:  virtual-kubelet
    Tolerations:
      Key:       virtual-kubelet.io/provider
      Operator:  Exists
  Replicas:      6
  Source Target:
    API Version:  apps/v1
    Kind:         Deployment
    Max:          2
    Min:          0
    Name:         nginx-deployment-basic
Status:
  Elastic Units Status:
    Desired Replicas:  4
    Name:              nginx-deployment-basic-unit-virtual-kubelet
    Update Timestamp:  2020-05-07T12:38:27Z
  Replicas:            6
  Selector:            app=nginx
  Source Target:
    API Version:       apps/v1
    Desired Replicas:  2
    Kind:              Deployment
    Name:              nginx-deployment-basic
    Update Timestamp:  2020-05-07T12:38:27Z
Events:                <none>           

當我們下發彈性負載的模闆後,可以檢視Pod的情況。可以發現彈性負載克隆出了新的Deployment與Pod,并且Deployment的Pod副本數目是根據上述的規則進行動态配置設定的。

kubectl get pod -o wide

 NAME                                               READY   STATUS    RESTARTS   AGE    IP             NODE                     NOMINATED NODE   READINESS GATES
nginx-deployment-basic-7ff9955f89-djxwv            1/1     Running   0          138m   172.20.1.151   cn-hangzhou.10.0.5.212   <none>           <none>
nginx-deployment-basic-7ff9955f89-hrw2z            1/1     Running   0          138m   172.20.1.27    cn-hangzhou.10.0.5.208   <none>           <none>
nginx-deployment-basic-unit-demo-8bb586568-4f8xt   1/1     Running   0          138m   10.1.76.63     virtual-node-eci-1       <none>           <none>
nginx-deployment-basic-unit-demo-8bb586568-bl5pd   1/1     Running   0          138m   10.1.76.65     virtual-node-eci-0       <none>           <none>
nginx-deployment-basic-unit-demo-8bb586568-ndbp8   1/1     Running   0          138m   10.1.76.64     virtual-node-eci-0       <none>           <none>
nginx-deployment-basic-unit-demo-8bb586568-vx9jx   1/1     Running   0          138m   10.1.76.62     virtual-node-eci-2       <none>           <none>           

此外,彈性負載也支援與HPA配合使用,可以将HPA作用在彈性負載上,如下圖,彈性負載會根據HPA的狀态動态調整每個單元的副本分布,例如如果目前是從6個副本縮容到4個副本,那麼會優先将彈性單元的副本進行縮容。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: elastic-workload-demo
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: autoscaling.alibabacloud.com/v1beta1
    kind: ElasticWorkload
    name: elasticworkload-sample
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50           

總結一下,首先彈性負載是通過克隆和覆寫排程政策的方式生成多個Deployment,實作了排程政策的管理。其次,通過上層的副本計算,調整原始負載和彈性單元的副本配置設定,實作了針對一部分Pod的優先處理。進而解決了上述的問題。

彈性負載的安裝與使用

彈性負載在阿裡雲容器服務控制台已經預設內建,可以通過應用市場進行安裝,在應用目錄中搜尋

ack-kubernetes-elastic-workload

即可。

Kubernetes彈性伸縮全場景解讀(九)- 彈性負載kubernetes-elastic-workload釋出

無需修改參數,點選建立即可。

最後

彈性負載所能解決的問題還遠不止文中提到的這些,如果我們從更抽象的角度來看到彈性負載,實際上,彈性負載主要是解決了精細化排程和控制器順序的問題,是以開發者可以基于彈性負載在例如故障恢複、可用區容災等等場景下進行進一步的開發和使用。在下一篇文章中,我們會來介紹彈性負載的彈性政策,如何通過彈性政策的設定實作容災。

繼續閱讀