昨天介紹完了,基礎的 Deployment 的應用,今天要來講講實務上 Deployment 的應用方式。

一般來說,我們都會系統可以高自動化,可以自動做擴展, ex 當 CPU 超過多少就幫我擴展 N 個 POD、當 RAM 超過多少時就增加 POD。

Horizontal Pod Autoscaler

其實設定的方式很簡單,我們只要透過下面語法就能做到,

$ kubectl --kubeconfig ~/.kube/k3s.yaml autoscale deployment nginx-deployment --min=5 --max=15 --cpu-percent=70
horizontalpodautoscaler.autoscaling/nginx-deployment autoscaled

## 上面意思為,我最小需求 POD 為 5 個,最大不能超過 15 個,只要 POD CPU使用率超過 70% 就做擴展。所以他啟動時會從 5 個,依照 loading 慢慢往上加。

也可以透過語法檢查目前 HPA 的設定。

$ kubectl --kubeconfig ~/.kube/k3s.yaml get hpa
NAME               REFERENCE                     TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   <unknown>/70%   5         15        10         2m27s

比較好的方式是直接在部署時決定要怎麼 scale 的策略,所以我們修改一下昨天部署過的 yaml 檔

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3 # 同時建立 3 個 nginx 的 pod
  # replicaset 的效果套用在帶有 app=nginx 的 pod 上
  # 必須要與下面的 pod label 有相符合
  selector:
    matchLabels:
      app: nginx
  # .spec.template 其實就是 pod 的定義
  template:
    # pod metadata
    metadata:
      # 設定給 pod 的 label 資訊
      labels:
        app: nginx
    spec:
      # 這邊可以看到,其實跟昨天的 nginx 是一樣的。
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        # 這邊加上資源限制,有了資源限制,後續才好評估超過時要怎麼 scale
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m

然後再透過 HPA yaml 就可以達成跟指令一樣的效果

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-deployment
spec:
  scaleTargetRef:
    apiVersion: apps/v1beta2
    kind: Deployment
    name: nginx-deployment
  minReplicas: 5
  maxReplicas: 15
  targetCPUUtilizationPercentage: 70

RollingUpdateStrategy

這個東西,也是在實務上很重要的一環,他可以決定你在更新當下,可以維持多少 POD 是正常運作的。

我們來看看下面這個設定檔,跟前幾天的有什麼不一樣。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3 
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      # 升級過程中最多可以比原先設定所多出的 pod 數量 ex 下面是指升級過程中 POD 總數可能會變到 4 個(上面設定 replicas 為 3)
      maxSurge: 1
      # 最多可以有幾個 pod 處在無法服務的狀態 ex 下面為最多一個 POD 為不可服務狀態。
      maxUnavailable: 1
  # 容器內應用程式的啟動時間,Kubernetes 會等待設定的時間後才繼續進行升級流程 (沒設定 POD 完成會直接啟動)
  minReadySeconds: 5
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

如果不想要 RollingUpdate 可以強制把 strategy.type 設定成 Recreate (就算不填預設是 RollingUpdate),這樣升級策略就會變成,他會一次把全部 POD 關閉,然後再一次把全部 POD 升級上來。這樣服務就無法做到無中斷更新。

總結

Deployment 是 k8s 裡面非常重要的元素,這邊只是用了少少的篇幅去介紹幾個我比較常用,以及我覺得入門時應該先學的幾個重點,如果行有餘力,建議還是參考官方的完整參數設定,會更了解 Deployment 的一切。