全部產品
Search
文件中心

Container Service for Kubernetes:建立有狀態工作負載StatefulSet

更新時間:Jul 18, 2025

StatefulSet,又稱“有狀態工作負載”。與Deployment不同,它會為Pod儲存狀態,因此適用於資料庫、訊息佇列、分布式儲存系統等情境。通過本文,您可瞭解StatefulSet的特點、通過控制台及kubectl建立StatefulSet的方法以及驗證保持Pod狀態的樣本。

StatefulSet介紹

與Deployment相似,StatefulSet也會保證有既定數量的Pod在正常運行。但不同的是,StatefulSet會通過以下措施保留Pod的身份:

  • 有序、固定的名稱:StatefulSet的每個Pod會按順序命名為<StatefulSet名稱>-<序號>。例如,StatefulSet的名稱為db-app,則Pod名稱為db-app-0、db-app-1。刪除並重建Pod時,建立Pod會繼承原有的名稱。

  • 穩定的網路標識:StatefulSet通常需要關聯一個Headless Service(通過spec.serviceName指定)。這個Headless Service並不像ClusterIP提供Pod的負載平衡,而僅用於為Pod提供固定的網域名稱(對Headless Service進行DNS查詢時,DNS會返回所有匹配的Pod的IP地址)。指定Headless Service後,Pod的網域名稱格式為<Pod名稱>.<Headless Service名稱>.<namespace>.svc.<ClusterDomain>,例如db-app-01.db-app.default.svc.cluster.local。Pod重建後,網域名稱會自動被解析到新Pod。

  • 穩定的持久化儲存:在StatefulSet中,可以指定PVC模板(通過spec.volumeClaimTemplates指定)。StatefulSet會根據此模板為每個Pod產生獨立的PersistentVolumeClaim(PVC),PVC名稱為<PVC模板名稱>-<Pod名稱>。當Pod被刪除時,PVC會被保留並自動關聯到使用相同序號的新Pod。

以上的這些措施保證了StatefulSet的Pod在重建後能繼承原有的網路和儲存狀態,使應用從持久化資料中恢複運行。關於StatefulSet的更多資訊,請參見官方文檔

重要

本文樣本使用的鏡像為公網鏡像,拉取時叢集或節點需具備公網訪問能力:

  • 為叢集開啟訪問公網的能力(推薦):為叢集所在的VPC建立公網NAT Gateway,叢集中的所有資源均可訪問公網。

  • 為節點分配固定公網IP:擁有公網IP的節點可拉取公網鏡像,但需要為部署工作負載的每個節點都分配公網IP。

建立StatefulSet

通過控制台建立

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集列表

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 有狀態

  3. 有狀態頁面,單擊使用鏡像建立

  4. 應用基本資料設定精靈頁面,設定應用的基本資料。然後單擊下一步,進入容器配置嚮導頁面。

  5. 容器配置地區,完成容器的鏡像名稱連接埠基本配置。其餘設定均為可選設定,保持預設即可。然後單擊下一步,進入進階配置嚮導頁面。鏡像地址如下所示。

    重要

    拉取此鏡像前,您需要為叢集開啟公網訪問能力。如果您在建立叢集時,為專用網路配置SNAT選擇保持預設勾選,則叢集已擁有公網訪問能力。如果未選擇,請參見為叢集開啟訪問公網的能力

    registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest

    image

  6. 進階配置嚮導頁面中設定訪問、伸縮、調度和標籤註解。在訪問設定地區,建立一個虛擬叢集IP(ClusterIP)類型的Service,並勾選執行個體間服務發現(Headless Service),單擊確定。然後,單擊最下方的建立

    image

  7. 建立StatefulSet時,控制台上的配置項(應用基本資料容器配置進階配置)與Deployment完全相同。其餘配置項的說明,請參見配置項說明

通過kubectl建立

重要
  1. 複製下方的YAML檔案,並儲存到statefulset.yaml中。下方的YAML中定義了:

    • 用於提供穩定網域名稱的Headless Service nginx

    • 為Pod關聯了hostPath儲存的StatefulSet。

    • 用於對外暴露StatefulSet的LoadBalancer類型Service,在本樣本中僅作為驗證Nginx頁面的一種方式。

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      clusterIP: None  # Headless Service
      selector:
        app: nginx
      ports:
      - port: 80
        name: http
    ---
    apiVersion: apps/v1
    kind: StatefulSet   # 工作負載類型
    metadata:
      name: nginx-test
      namespace: default  # 根據需要更改命名空間
      labels:
        app: nginx
    spec:
      serviceName: "nginx" # 選擇前面建立的Headless Service
      replicas: 2  # 指定-Pod數量
      selector:
        matchLabels:
          app: nginx
      template: # Pod配置
        metadata:
          labels: # Pod標籤
            app: nginx 
        spec:
          containers:
          - name: nginx  # 容器名稱
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6  # 使用特定版本的 Nginx 鏡像
            ports:
            - containerPort: 80  # 容器暴露的連接埠
              protocol: TCP  # 指定協議為 TCP/UDP
            volumeMounts:
            - name: node-dir-volume  # 卷名稱,需與下方volumes名稱相同
              mountPath: /tmp  # 容器內的掛載路徑
          volumes:
          - name: node-dir-volume
            hostPath:
              path: /local_storage  # 節點本地的目錄路徑
              type: DirectoryOrCreate     # 如果目錄不存在則自動建立
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-test-svc
      namespace: default  # 根據需要更改命名空間
      labels:
        app: nginx
    spec:
      selector:
        app: nginx  # 匹配標籤,確保服務指向正確的 Pods
      ports:
        - port: 80           # Service 在叢集內提供的連接埠
          targetPort: 80     # 指向容器內部應用程式監聽的連接埠 (containerPort)
          protocol: TCP      # 協議,預設是 TCP
      type: LoadBalancer      # 服務類型,預設是 ClusterIP,內部訪問
  2. 執行以下命令,建立StatefulSet及Service。

    kubectl apply -f statefulset.yaml

    預期輸出:

    service/nginx created
    statefulset.apps/nginx-test created
    service/nginx-test-svc created
  3. 執行以下命令,查看Service的公網IP地址。

    kubectl get svc

    預期輸出:

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
    kubernetes      ClusterIP      172.16.**.***    <none>          443/TCP        4h47m
    nginx           ClusterIP      None             <none>          80/TCP         1h10m
    nginx-test-svc  LoadBalancer   172.16.**.***    106.14.**.***   80:31130/TCP   1h10m
  4. 在瀏覽器中輸入nginx的公網IP(106.14.**.***),即可訪問工作負載所屬的Nginx容器。image

驗證StatefulSet特性

  1. 執行以下命令,查看Pod狀態。

    kubectl get pod nginx-test-0

    預期輸出如下。

    NAME           READY   STATUS    RESTARTS   AGE
    nginx-test-0   1/1     Running   0          7m41s
  2. 執行以下命令刪除Pod。

    kubectl delete pod nginx-test-0

    預期輸出:

    pod "nginx-test-0" deleted
  3. 執行以下命令,查看Pod狀態。

    kubectl get pod nginx-test-0

    預期輸出如下,STATUSRunning時,表示新Pod已正常運行,繼承了原有名稱。

    NAME           READY   STATUS    RESTARTS   AGE
    nginx-test-0   1/1     Running   0          20s

相關文檔