すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:StatefulSet でのクラウドディスク永続ストレージの設定

最終更新日:Oct 13, 2025

データベースやメッセージキューなどのステートフルアプリケーションにおいて、Kubernetes の StatefulSet は volumeClaimTemplates フィールドを使用し、各 Pod に専用の永続ボリューム要求 (PVC) を動的に作成・アタッチします。この PVC は独立した永続ボリューム (PV) にバインドされます。Pod が再作成または再スケジュールされた場合でも、PVC は自動的に元の PV に再マウントされるため、データの永続化とサービスの継続性が保証されます。

以下は、volumeClaimTemplates の設定例です。

apiVersion: apps/v1
kind: StatefulSet
# ...
spec:
  # ...
  volumeClaimTemplates:
  - metadata:
      name: data-volume                        # PVC テンプレートの名前
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "alicloud-disk-essd"   # ストレージタイプを指定
      resources:
        requests:
          storage: 20Gi                        # 要求されたストレージ容量

仕組み

  • 作成とスケールアウト

    初回作成時またはスケールアウト時に、StatefulSet コントローラーは volumeClaimTemplates を使用して、各 Pod レプリカに一意の名前を持つ PVC を作成してバインドします。PVC は [template-name]-[pod-name] のパターンに従って命名されます。たとえば、テンプレート名が data-volume の場合、コントローラーは Pod web-0web-1 に対して、それぞれ data-volume-web-0data-volume-web-1 という名前の PVC を作成し、Pod とそのストレージ間に安定したマッピングを確立します。

    テンプレート内のパラメーター (storageClassNamestorageaccessModes など) に基づいて、Container Storage Interface (CSI) は、タイプ、サイズ、アクセスモードが一致する PV を自動的に作成し、その PV をバインドしてマウントします。

  • スケールイン

    StatefulSet がスケールインされると、コントローラーは Pod 自体のみを削除します。関連付けられた PVC と基盤となる PV は、データを保護するために保持されます。

  • 再スケールと障害回復

    再度スケールアウト (レプリカ数を増やす) する場合や、障害回復 (Pod が削除されてから再作成) の際に、コントローラーは以前に保持されていた同じ名前の PVC を自動的に見つけて再利用します。

    • PVC が存在する場合、同じ名前の新しい Pod は既存の PV を自動的にマウントし、状態とデータを迅速に回復できます。

    • PVC が存在しない場合 (例えば、スケールアウト操作が過去のピークレプリカ数を超えた場合など)、新しい PVC とそれに対応する PV が作成されます。

ステップ 1: 永続ストレージを持つ StatefulSet のデプロイ

この例では、Service と 2 つのレプリカを持つ StatefulSet をデプロイします。StatefulSet は volumeClaimTemplates を使用して、各レプリカに 20 GiB のクラウドディスクを自動的に作成します。

  1. statefulset.yaml という名前のファイルを作成します。

    次の表に、volumeClaimTemplates のパラメーターを説明します。

    パラメーター

    説明

    accessModes

    ボリュームのアクセスモードです。ReadWriteOnce は、ボリュームが一度に 1 つのノードによって読み取り/書き込みとしてマウントできることを意味します。

    storageClassName

    使用するストレージクラスの名前です。

    alicloud-disk-essd は、デフォルトのパフォーマンスレベル (PL) が PL1 のエンタープライズ SSD (ESSD) を作成するために Container Service for Kubernetes (ACK) が提供するデフォルトのストレージクラスです。

    これらのディスクは従量課金制を使用します。詳細については、「ブロックストレージの課金」および「ブロックストレージの価格」をご参照ください。

    storage

    ディスクボリュームの容量。

    YAML テンプレート

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      # Headless Service を示すために clusterIP を "None" に設定
      clusterIP: None
      selector:
        app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx
      # serviceName は上記で定義された Headless Service の名前と一致する必要があります
      serviceName: "nginx"
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
              name: web
            # PV をコンテナー内の指定されたパスにマウント
            volumeMounts:
            - name: disk-essd
              mountPath: /data
      # StatefulSet が各 Pod の PVC を作成するために使用する PVC テンプレート
      volumeClaimTemplates:
      - metadata:
          name: disk-essd
        spec:
          # ボリュームのアクセスモードを定義
          accessModes: [ "ReadWriteOnce" ]
          # 動的 PV プロビジョニング用のストレージクラスを指定
          storageClassName: "alicloud-disk-essd"
          resources:
            requests:
              # 各 PVC に要求されるストレージ容量を定義
              storage: 20Gi
  2. StatefulSet をデプロイします。

    kubectl create -f statefulset.yaml
  3. Pod が実行中であることを確認します。

    kubectl get pod -l app=nginx
  4. PVC を表示し、システムが各 Pod に対応する PVC を自動的に作成してバインドしたことを確認します。

    kubectl get pvc

    期待される出力:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 3m31s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 48s

ステップ 2: ストレージのライフサイクルの検証

スケールアウト、スケールイン、そして再度スケールアウトを行うことで、関連する PVC の作成、保持、再利用を観察します。

アプリケーションのスケールアウト

  1. StatefulSet のレプリカ数を 3 に増やします。

    kubectl scale sts web --replicas=3
  2. Pod が実行中であることを確認します。

    kubectl get pod -l app=nginx
  3. PVC を表示して、システムが Pod web-2 とそれに対応する PVC disk-essd-web-2 を自動的に作成したことを確認します。

    kubectl get pvc

    期待される出力:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 4m1s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 78s
    disk-essd-web-2   Bound    d-m5ee2cvzx4dog1lounjn   20Gi       RWO            alicloud-disk-essd   <unset>                 16s

アプリケーションのスケールイン

  1. StatefulSet のレプリカ数を 2 に減らします。

    kubectl scale sts web --replicas=2
  2. ポッドが実行中であることを確認します。

    kubectl get pod -l app=nginx
  3. PVC を表示します。

    kubectl get pvc

    期待される出力:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 4m21s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 98s
    disk-essd-web-2   Bound    d-m5ee2cvzx4dog1lounjn   20Gi       RWO            alicloud-disk-essd   <unset>                 36s

    この時点で、Pod web-2 は削除されましたが、PVC disk-essd-web-2 はデータの永続性を確保するためにまだ保持されます。

アプリケーションの再度スケールアウト

  1. StatefulSet のレプリカ数を再び 3 に増やします。

    kubectl scale sts web --replicas=3
  2. Pod が実行中であることを確認します。

    kubectl get pod -l app=nginx
  3. PVC を表示します。

    kubectl get pvc

    期待される出力:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 4m50s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 2m7s
    disk-essd-web-2   Bound    d-m5ee2cvzx4dog1lounjn   20Gi       RWO            alicloud-disk-essd   <unset>                 65s

    新しく作成された Pod web-2 は、以前保持されていた PVC disk-essd-web-2 を自動的に再利用します。

ステップ 3: Pod 障害後のデータ永続性の検証

Pod の再作成後もデータが永続することを確認するため、Pod にデータを書き込んでから削除し、再度データを確認します。

  1. Pod にテストデータを書き込みます。

    Pod web-1 を例として、マウントされたディスクパス /datatest ファイルを作成します。

    kubectl exec web-1 -- touch /data/test
    kubectl exec web-1 -- ls /data

    期待される出力:

    lost+found
    test
  2. Pod を削除して、Pod の障害をシミュレートします。

    kubectl delete pod web-1

    kubectl get pod -l app=nginx を再度実行すると、web-1 という名前の新しい Pod が自動的に作成されていることがわかります。

  3. 新しい Pod のデータを確認します。

    新しい web-1 Pod の /data ディレクトリを確認します。

    kubectl exec web-1 -- ls /data

    作成した test ファイルはまだ存在しています。これにより、Pod が削除されて再作成された場合でもデータが永続することが確認できます。

    lost+found
    test

本番運用時の注意点

  • コストとリソースの管理: StatefulSet をスケールインまたは削除すると、関連する PVC とディスクはデフォルトで保持されます。これらの保持されたリソースには引き続き料金が発生し続けます。不要な料金を回避するために、未使用の PVC と PV を手動でクリーンアップしてください。

  • データセキュリティとバックアップ: 永続ストレージは Pod の障害時に高可用性を確保しますが、データバックアップソリューションではありません。重要なデータについては、バックアップセンターを使用して定期的なバックアップを実行してください。

  • 高可用性と災害復旧: ディスクはゾーンリソースであり、ゾーンをまたいでマウントすることはできません。クロスゾーン災害復旧には、リージョン ESSD など、クロスゾーンのデータレプリケーションをサポートするディスクタイプを使用してください。

関連ドキュメント

トラブルシューティングについては、「ディスクボリュームに関する FAQ」をご参照ください。