部署有狀態應用程式

本頁面說明如何使用 Google Kubernetes Engine (GKE) 部署有狀態應用程式。

總覽

有狀態應用程式會將資料儲存至永久磁碟儲存空間,供伺服器、用戶端和其他應用程式使用。有狀態應用程式的例子包括資料庫或鍵/值儲存庫,其他應用程式會將資料儲存至這些儲存庫,並從中擷取資料。

永久儲存空間可以動態佈建,因此基礎磁碟區會視需求建立。在 Kubernetes 中,您可以建立 StorageClass 來設定動態佈建。在 GKE 中,預設 StorageClass 可讓您動態佈建 Compute Engine 永久磁碟。

Kubernetes 會使用 StatefulSet 控制器,將有狀態應用程式部署為 StatefulSet 物件。StatefulSet 中的 Pod 無法互換:每個 Pod 都有專屬 ID,無論排程在哪裡,都會保留這個 ID。

有狀態應用程式與無狀態應用程式不同,後者不會在工作階段之間將用戶端資料儲存至伺服器。

您可以進一步瞭解多可用區和區域叢集中的永久儲存空間。

事前準備

開始之前,請確認您已執行下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 確認容器化應用程式儲存在映像檔存放區,例如 Artifact Registry。

您可以按照快速入門導覽課程的指示,啟用 GKE API、建立叢集,並進一步瞭解 GKE。

在 StatefulSet 中要求永久儲存空間

應用程式可以透過 PersistentVolumeClaim 要求永久儲存空間。

一般來說,除了建立 Pod 之外,您還必須建立 PersistentVolumeClaim 物件。不過,StatefulSet 物件包含 volumeClaimTemplates 陣列,會自動產生 PersistentVolumeClaim 物件。每個 StatefulSet 副本都有自己的 PersistentVolumeClaim 物件。

您也可以在 StatefulSet 中使用現有磁碟。

動態拓撲繫結

建立使用可用區 PersistentVolume 的 StatefulSet 時,最佳做法是使用 volumeBindingMode: WaitForFirstConsumer 欄位值組合設定 StorageClass 定義。這項設定可確保系統延遲佈建磁碟區,直到 Pod 排定至可用區中運算容量充足的健康節點。如果使用預設的立即繫結,Pod 的磁碟區可能會在 Pod 排定前,鎖定至運算能力不足的可用區,導致 Pod 陷入 Pending 狀態。

建立 StatefulSet

如要建立 StatefulSet 資源,請使用 kubectl apply 指令。

kubectl apply 指令會使用資訊清單檔案,在叢集中建立、更新及刪除資源。這是物件設定的宣告式方法。這種方法保留對使用中物件所做的寫入,而不會將變更併回物件設定檔。

Linux

以下資訊清單檔案是無頭服務及其管理的 StatefulSet 範例:

apiVersion: v1
kind: Service
metadata:
  name: SERVICE_NAME
  labels:
    app: APP_NAME
spec:
  ports:
  - port: 80
    name: PORT_NAME
  clusterIP: None
  selector:
    app: APP_NAME
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  selector:
    matchLabels:
      # Selects Pods with this label.
      app: APP_NAME
  # Headless Service for network identity.
  serviceName: "SERVICE_NAME"
  replicas: 3
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: APP_NAME
    spec:
      containers:
      - name: CONTAINER_NAME
        image: IMAGE
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: MOUNT_PATH
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
      annotations:
        KEY: VALUE
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

更改下列內容:

  • STATEFULSET_NAME:StatefulSet 的名稱,例如 web。
  • SERVICE_NAME:Service 的名稱,例如 nginx。
  • APP_NAME:在 Pod 中執行的應用程式名稱,例如 nginx。
  • CONTAINER_NAME:Pod 中的容器名稱,例如 nginx。
  • IMAGE:容器映像檔,例如 nginx:stable。
  • PORT_NAME:StatefulSet 開啟的通訊埠名稱,例如 web。
  • PVC_NAME:PersistentVolumeClaim 的名稱,例如 www。
  • MOUNT_PATH:容器中掛接儲存空間的路徑,例如 /usr/share/nginx/html。
  • KEY 和 VALUE:要套用至 PersistentVolumeClaim 中繼資料的註解鍵/值組合。您可以使用註解,將不含識別資訊的任意中繼資料附加至物件,以便工具和程式庫等用戶端擷取。詳情請參閱「註解」。

在這個檔案中,kind 欄位指定應使用檔案中定義的規格建立 StatefulSet 物件。這個範例 StatefulSet 會產生三個複製的 Pod,並開啟通訊埠 80,將 StatefulSet 公開至網際網路。

Windows

使用具有 Windows Server 節點集區的叢集時,您必須建立 StorageClass,因為預設 StorageClass 會使用 ext4 做為檔案系統類型,而這僅適用於 Linux 容器。如果您使用的是 Compute Engine 永久磁碟,則必須使用 NTFS 做為檔案儲存空間類型,如以下範例所示:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  # Defines a name for this StorageClass.
  name: STORAGECLASS_NAME
parameters:
  # Specifies the type of Google Compute Engine persistent disk.
  type: pd-standard
  # Uses NTFS file system, which is crucial for Windows nodes
  fstype: NTFS
# The provisioner for Google Compute Engine persistent disks.
provisioner: kubernetes.io/gce-pd
# Specifies that the PersistentVolume will be deleted if the PersistentVolumeClaim is deleted.
reclaimPolicy: Delete
# Delays volume binding until a Pod using the PVC is scheduled.
volumeBindingMode: WaitForFirstConsumer

下列 StatefulSet 資訊清單會使用上述定義的 StorageClass。這項指令會建立四個 PersistentVolume 和 PersistentVolumeClaim 配對,代表四個 Compute Engine 永久磁碟。StatefulSet 中的每個 Pod 都會耗用一個永久磁碟。

為確保 Pod 正確排程至 Windows Server 節點,您必須在 Pod 規格中新增節點選取器。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  replicas: 4
  selector:
    matchLabels:
      # Selects Pods with this label.
      app: APP_NAME
  template:
    metadata:
      labels:
        # Labels applied to the Pods created by the StatefulSet.
        app: APP_NAME
      name: CONTAINER_NAME
    spec:
      nodeSelector:
        # Ensures Pods are scheduled on Windows nodes.
        kubernetes.io/os: windows
      containers:
      - name: CONTAINER_NAME
        image: IMAGE
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: MOUNT_PATH
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
    spec:
      # Specifies the StorageClass to use, which is crucial for Windows nodes.
      storageClassName: STORAGECLASS_NAME
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

更改下列內容:

  • STATEFULSET_NAME:StatefulSet 的名稱,例如 web-windows。
  • APP_NAME:在 Pod 中執行的應用程式名稱,例如 iis。
  • CONTAINER_NAME:Pod 中的容器名稱,例如 iis。
  • IMAGE:容器映像檔,例如 mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019。
  • PORT_NAME:StatefulSet 開啟的通訊埠名稱,例如 http。
  • PVC_NAME:PersistentVolumeClaim 的名稱,例如 iis-state。
  • MOUNT_PATH:容器中掛接儲存空間的路徑,例如 C:\mnt\state。
  • STORAGECLASS_NAME:StorageClass 的名稱,例如 my-storage-class。

如要建立 StatefulSet 資源,請執行下列指令,並將 STATEFULSET_FILE 替換為資訊清單檔案名稱:

kubectl apply -f STATEFULSET_FILE

您也可以使用 kubectl apply -f DIRECTORY/,建立儲存在目錄中的設定檔所定義的所有物件 (現有物件除外)。

檢查 StatefulSet

kubectl

如要檢查 StatefulSet,請執行下列指令:

kubectl get statefulset STATEFULSET_NAME -o yaml

這個指令會以 YAML 格式顯示 StatefulSet 資源的即時設定。

如要列出由 StatefulSet 建立的 Pod,請執行下列指令:

kubectl get pods -l app=APP_NAME

在這個指令中,-l 旗標會指示 kubectl 取得APP_NAME標籤的所有 Pod。

輸出結果會與下列內容相似:

NAME                                READY     STATUS    RESTARTS   AGE
pod-name                            1/1       Running   0          1m
pod-name                            1/1       Running   0          1m

如要取得 StatefulSet 的詳細資訊,請執行下列指令:

kubectl describe statefulset STATEFULSET_NAME

如要取得特定 Pod 的資訊,請執行下列指令:

kubectl describe pod POD_NAME

如要列出已建立的 PersistentVolumeClaim 物件,請執行下列指令:

kubectl get pvc

輸出結果會與下列內容相似:

NAME                            STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
STATEFULSET_NAME-PVC_NAME-0     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800002   1G         RWO            standard        9s
STATEFULSET_NAME-PVC_NAME-1     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800003   1G         RWO            standard        9s
STATEFULSET_NAME-PVC_NAME-2     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800004   1G         RWO            standard        9s

如要取得特定 PersistentVolumeClaim 的資訊,請執行下列指令:

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

如要取得特定 PersistentVolume 的資訊,請執行下列指令:

kubectl describe pv PV_NAME

控制台

如要檢查 StatefulSet,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 在工作負載清單中,按一下要檢查的 StatefulSet 名稱。

  3. 在「Stateful Set details」(StatefulSet 詳細資料) 頁面中,執行下列任一操作:

    • 點選「修訂版本記錄」分頁標籤,查看 StatefulSet 的修訂版本記錄。
    • 點選「事件」分頁標籤,查看與 StatefulSet 相關的所有事件。
    • 按一下「記錄」分頁標籤,查看 StatefulSet 的容器記錄。
    • 按一下「YAML」YAML分頁標籤,即可查看、複製或下載 StatefulSet 的設定 YAML。

更新 StatefulSet

有多種方式可以更新 StatefulSet, kubectl apply 是常見的宣告式方法。如要直接從殼層或偏好的編輯器更新 StatefulSet,可以使用 kubectl edit。您也可以在 Google Cloud 控制台的 GKE「Workloads」(工作負載) 選單中使用 YAML 編輯器。

您可以對 StatefulSet 資源的 Pod 規格推出更新,例如映像檔、資源用量/要求或設定。

kubectl apply

您可以套用新的或更新後的資訊清單檔案,藉此更新 StatefulSet。這項功能在您需要對 StatefulSet 進行各種變更時非常實用,例如調整資源配置或指定新版應用程式。

如要更新 StatefulSet,請執行下列指令:

kubectl apply -f STATEFULSET_FILE

將 STATEFULSET_FILE 替換為更新後的資訊清單檔案。

kubectl apply 指令會將資訊清單檔案套用至資源。如果指定的資源不存在,則這個指令會建立該資源。

如要進一步瞭解 kubectl apply,請參閱 kubectl 參考文件。

控制台

如要編輯 StatefulSet 的使用中設定,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 在工作負載清單中,按一下要修改的 StatefulSet 名稱。

  3. 按一下「Edit」(編輯)。

  4. 視需要變更 YAML 設定。

  5. 按一下 [儲存]。

檢查更新發佈作業

執行下列指令,檢查 StatefulSet 的推出作業:

kubectl rollout status statefulset STATEFULSET_NAME

如要查看 StatefulSet 的推出記錄,請執行下列指令:

kubectl rollout history statefulset STATEFULSET_NAME

如要復原推出作業,請執行下列指令:

kubectl rollout undo statefulset STATEFULSET_NAME

更新策略

StatefulSet 的 updateStrategy 欄位可讓您設定及停用容器、標籤、資源要求、限制和 StatefulSet 中 Pod 註解的自動滾動式更新。

如要進一步瞭解 StatefulSet 的更新策略,請參閱 Kubernetes 說明文件。

調整 StatefulSet 的資源配置

kubectl

您隨時可以使用 kubectl scale 指令來調度 StatefulSet。

如要手動調整 StatefulSet 的資源配置,請執行下列指令:

kubectl scale statefulset STATEFULSET_NAME --replicas NUMBER_OF_REPLICAS

將 NUMBER_OF_REPLICAS 替換為所需的複製 Pod 數量。

控制台

如要調整 StatefulSet 的資源配置,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 在工作負載清單中,按一下要修改的 StatefulSet 名稱。

  3. 依序點選 「Actions」(動作) >「Scale」(規模) >「Edit replicas」(編輯副本)。

  4. 輸入 StatefulSet 的新副本數量。

  5. 按一下 [Scale] (擴充)。

刪除 StatefulSet

kubectl

如要刪除 StatefulSet,請執行下列指令:

kubectl delete statefulset STATEFULSET_NAME

主控台

如要刪除 StatefulSet,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 在工作負載清單中,選取一或多個要刪除的 StatefulSet。

  3. 按一下「刪除」圖示 。

  4. 當系統提示時,按一下「Delete」(刪除)。

後續步驟