StatefulSetでVolumeClaimTemplateを設定することで、各ポッドに永続ボリューム (PV) と永続ボリューム要求 (PVC) のペアを作成できます。 ポッドが削除またはスケールインされた場合、StatefulSetアプリケーションのPVおよびPVCは削除されません。 このトピックでは、VolumeClaimTemplateを設定して、StatefulSetが永続ストレージをサポートできるようにする方法について説明します。
前提条件
シナリオ
StatefulSetを使用する場合:
定義済みのデプロイ順序: ポッドは0からN-1まで順番にデプロイまたはスケールアウトされます。 システムは、前のすべてのポッドが [実行中] または [準備完了] 状態になるまで待機してから、別のポッドをデプロイできます。
事前定義されたスケールイン順序: ポッドは、順番にN-1から0にスケールインまたは削除されます。 前のポッドがすべて削除されるまで待機してから、別のポッドを削除する必要があります。
一貫したネットワーク識別子: ポッドが再スケジュールされた後、そのPodName値とHostName値は変更されません。
安定したデータ永続性: ポッドが再スケジュールされた後も、ポッドは同じ永続データにアクセスできます。
StatefulSetの作成
PVCおよびPVは、VolumeClaimTemplates
に基づいて自動的に作成できます。
volumeClaimTemplatesは、システムがPVCを作成するために使用するテンプレートのタイプを表します。 PVCの数は、StatefulSetアプリケーション用にデプロイされているレプリカの数と同じです。 これらのPVCの構成は、PVCの名前を除いて同じです。
次のテンプレートを使用して、statefulset.yamlという名前のファイルを作成します。
ServiceとStatefulSetをデプロイし、StatefulSetに2つのポッドをプロビジョニングします。
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web volumeMounts: - name: disk-ssd mountPath: /data volumeClaimTemplates: - metadata: name: disk-ssd spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "alicloud-disk-ssd" resources: requests: storage: 20Gi
レプリカ
: この例では、パラメーターは2に設定されています。 これは、2つのポッドが作成されることを示します。mountPath
: コンテナー内のディスクをマウントするパス。accessModes
: StatefulSetのアクセスモード。storageClassName
: この例では、パラメーターはalicloud-disk-ssd
に設定されています。 これは、Alibaba Cloud標準SSDが使用されていることを示します。storage
: アプリケーションが必要とするストレージを指定します。
次のコマンドを実行して、StatefulSetを作成します。
kubectl create -f statefulset.yaml
次のコマンドを実行して、デプロイされたポッドを照会します。
kubectl get pod
期待される出力:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 6m web-1 1/1 Running 0 6m
次のコマンドを実行して、PVCを照会します。
kubectl get pvc
期待される出力:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 7m disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 6m
PVCがStatefulSetアプリケーションと一緒にスケールアウトされていることを確認する
次のコマンドを実行して、StatefulSetアプリケーションを3つのポッドにスケールアウトします。
kubectl scale sts web --replicas=3
期待される出力:
statefulset.apps/web scaled
次のコマンドを実行して、StatefulSetアプリケーションのスケールアウト後にポッドを表示します。
kubectl get pod
期待される出力:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 34m web-1 1/1 Running 0 33m web-2 1/1 Running 0 26m
次のコマンドを実行して、StatefulSetアプリケーションのスケールアウト後にPVCを表示します。
kubectl get pvc
期待される出力:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 35m disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 34m disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 27m
出力は、StatefulSetアプリケーションが3つのポッドにスケーリングされた後に、3つのPVCがStatefulSetアプリケーションにプロビジョニングされることを示します。
StatefulSetアプリケーションのスケールイン後も、PVCが変更されないことを確認する
次のコマンドを実行して、StatefulSetアプリケーションを2つのポッドにスケーリングします。
kubectl scale sts web --replicas=2
期待される出力:
statefulset.apps/web scaled
次のコマンドを実行して、StatefulSetアプリケーションのスケーリング後にポッドを表示します。
kubectl get pod
期待される出力:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 38m web-1 1/1 Running 0 38m
StatefulSetアプリケーションには2つのポッドのみがデプロイされます。
次のコマンドを実行して、StatefulSetアプリケーションのスケーリング後にPVCを表示します。
kubectl get pvc
期待される出力:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 39m disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 39m disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 31m
StatefulSetアプリケーションが2つのポッドにスケーリングされた後も、StatefulSetアプリケーションには3つのPVCがあります。 これは、PVCがStatefulSetアプリケーションと一緒にスケールインされないことを示します。
StatefulSetアプリケーションが再びスケールアウトされたときにPVCが変更されないことを確認する
StatefulSetが再びスケールアウトされたら、PVCが変更されないことを確認します。
次のコマンドを実行して、StatefulSetアプリケーションを3つのポッドにスケールアウトします。
kubectl scale sts web --replicas=3
期待される出力:
statefulset.apps/web scaled
次のコマンドを実行して、StatefulSetアプリケーションのスケールアウト後にポッドを表示します。
kubectl get pod
期待される出力:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 1h web-1 1/1 Running 0 1h web-2 1/1 Running 0 8s
次のコマンドを実行して、StatefulSetアプリケーションのスケールアウト後にPVCを表示します。
kubectl get pvc
期待される出力:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 1h
新しく作成されたポッドは既存のPVCを使用します。
StatefulSetアプリケーションのポッドが削除されたときにPVCが変更されないことを確認する
次のコマンドを実行して、web-1という名前のポッドで使用されるPVCを表示します。
kubectl describe pod web-1 | grep ClaimName
期待される出力:
ClaimName: disk-ssd-web-1
次のコマンドを実行して、web-1という名前のポッドを削除します。
kubectl delete pod web-1
期待される出力:
pod "web-1" deleted
次のコマンドを実行してポッドを表示します。
kubectl get pod
期待される出力:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 1h web-1 1/1 Running 0 25s web-2 1/1 Running 0 9m
再作成されたポッドは、削除されたポッドと同じ名前を使用します。
次のコマンドを実行して、PVCを表示します。
kubectl get pvc
期待される出力:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 1h
再作成されたポッドは既存のPVCを使用します。
StatefulSetアプリケーションが永続ストレージをサポートしていることを確認する
次のコマンドを実行して、/dataパスのファイルを表示します。
kubectl exec web-1 -- ls /data
期待される出力:
lost+found
次のコマンドを実行して、/dataパスにstatefulsetという名前のファイルを作成します。
kubectl exec web-1 -- touch /data/statefulset
次のコマンドを実行して、/dataパスのファイルを表示します。
kubectl exec web-1 -- ls /data
期待される出力:
lost+found statefulset
次のコマンドを実行して、web-1という名前のポッドを削除します。
kubectl delete pod web-1
期待される出力:
pod "web-1" deleted
次のコマンドを実行して、/dataパスのファイルを表示します。
kubectl exec web-1 -- ls /data
期待される出力:
lost+found statefulset
statefulsetファイルはまだ /dataパスに存在します。 これは、データがディスクに永続化されることを示します。