このページでは、Kubernetes StatefulSet オブジェクトと Google Kubernetes Engine での使用方法について説明します。
StatefulSet とは
StatefulSet は、スケジュールされた場所にかかわらず GKE が保持する一意で永続的な ID と固有のホスト名を持つ「ポッド」のセットを表します。任意の StatefulSet ポッドの状態情報やその他の復元データは、StatefulSet に関連付けられた永続ディスク ストレージに保持されます。
StatefulSet は、ポッドの ID と順序付けに序数インデックスを使用します。デフォルトで、StatefulSet ポッドは、順番にデプロイされ、逆順で終了します。たとえば、web
という名前の StatefulSet には、web-0
、web-1
、および web-2
という名前のポッドが含まれています。web
ポッド仕様が変更されると、そのポッドが正常に停止され、順序に従って再作成されます。この例では、web-2
が最初に終了して、次に web-1
が終了し、という順序で行われます。また、他のポッドが稼働状態になるまで待機するか、他のポッドが停止するまで停止を待機することなく、すべてのポッドを StatefulSet で一斉に起動または終了するように podManagementPolicy: Parallel
フィールドを指定することもできます。
StatefulSets ではポッド テンプレートが使用されます。これには、そのポッドの仕様が組み込まれています。ポッドの仕様によって、各ポッドの外観、つまり、コンテナ内で実行するアプリケーション、マウントするボリューム、ラベルとセレクタなどが決定されます。
使用パターン
StatefulSet は、Google Compute Engine の永続ディスクなどの永続ストレージにデータを保存するステートフル アプリケーションやクラスタ化されたアプリケーションをデプロイするように設計されています。StatefulSet は、Kafka、MySQL、Redis、ZooKeeper などの一意で永続的な ID と固有のホスト名が必要なアプリケーションのデプロイに適しています。ステートレス アプリケーションには、Deployment を使用します。
StatefulSet の作成
kubectl apply
を使用して、StatefulSet を作成できます。
StatefulSet が作成されると、指定された数のポッドが実行されており、いつでも利用できることが保証されます。StatefulSet は、障害が起きたポッドやノードから削除されたポッドを自動的に置き換え、新しいポッドを StatefulSet のポッド仕様で定義されたストレージ リソース、リソースの要求と制限、およびその他の設定に自動的に関連付けます。
サービスと StatefulSet のマニフェスト ファイルの例を以下に示します。
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 # Label selector that determines which Pods belong to the StatefulSet # Must match spec: template: metadata: labels serviceName: "nginx" replicas: 3 template: metadata: labels: app: nginx # Pod template's label selector spec: terminationGracePeriodSeconds: 10 containers: - name: nginx image: gcr.io/google_containers/nginx-slim:0.8 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi
この例では、次のようになります。
metadata: name
フィールドで指定された、nginx
という名前のサービス オブジェクトが作成されます。このサービスは、labels: app: nginx
とselector: app: nginx
で指定された、nginx
という名前のアプリをターゲットとします。また、ポート 80 を公開し、その名前をweb
にします。このサービスは、ネットワーク ドメインを制御し、StatefulSet によってデプロイされたコンテナ化されたアプリケーションにインターネット トラフィックをルーティングします。- 3 つの複製されたポッド(
replicas: 3
)を使用して、web
という名前の StatefulSet が作成されます。 - ポッド テンプレート(
spec: template
)は、そのポッドにapp: nginx
というラベルが付けられることを指定します。 - ポッド仕様(
template: spec
)は、StatefulSet のポッドが 1 つのコンテナnginx
を実行し、そのコンテナがバージョン0.8
のnginx-slim
イメージを実行するように指定します。コンテナ イメージは Container Registry によってホストされます。 - ポッド仕様では、サービスによって開かれた
web
ポートが使用されます。 template: spec: volumeMounts
は、www
という名前が付けられたmountPath
を指定します。mountPath
は、ストレージ ボリュームをマウントする必要のあるコンテナ内のパスです。- StatefulSet は、1 GB のストレージがプロビジョニングされた
www
という PersistentVolumeClaim をプロビジョニングします。
要約すると、ポッド仕様には次の手順が含まれています。
- 各ポッドに
app: nginx
というラベルを付けます。 - 各ポッドで、
nginx
という名前の 1 つのコンテナを実行します。 - バージョン
0.8
のnginx-slim
イメージを実行します。 - ポッドにポート
80
を使用するように指示します。 - データをマウントパスに保存します。
StatefulSet 設定の詳細については、StatefulSet API リファレンスをご覧ください。
StatefulSet の更新
StatefulSet を更新するには、コンテナのイメージとボリュームを含むポッド仕様を変更します。また、オブジェクトのリソースの要求と制限、ラベル、および注釈を更新することもできます。StatefulSet の更新には、kubectl
、Kubernetes API、Google Cloud Platform Console の GKE ワークロードのメニューを使用できます。
StatefulSet は、spec: updateStrategy
で定義された更新戦略に基づいて更新の処理方法を決定します。OnDelete
と RollingUpdate
の 2 つの戦略があります。
OnDelete
ではオブジェクトの構成の変更時に、自動的にはポッドの削除と再作成が行われません。代わりに、古いポッドを手動で削除することにより、更新されたポッドをコントローラに作成させる必要があります。RollingUpdate
では、オブジェクトの構成の変更時に、自動的にポッドが削除され、再作成されます。古いポッドが削除される前に、新しいポッドが Running かつ Ready の状態になる必要があります。この戦略では、ポッド仕様を変更すると自動的にロールアウトがトリガーされます。これは、StatefulSet のデフォルトの更新戦略です。
StatefulSet は、逆順でポッドを更新します。次のコマンドを実行することにより、更新ロールアウトを監視できます。
kubectl rollout status statefulset [STATEFULSET_NAME]
ローリング更新のパーティショニング
ローリング更新をパーティショニングすることができます。パーティショニングは、更新をステージングしたり、カナリアをロールアウトしたり、段階的ロールアウトを実行したりする場合に便利です。
更新をパーティショニングすると、StatefulSet のポッド仕様が更新されたときに、序数がパーティション値以上のすべてのポッドが更新されます。序数がパーティション値未満のポッドは更新されず、削除されても、以前のバージョンの仕様を使用して再作成されます。パーティション値がレプリカ数を上回っている場合は、更新がポッドに伝播されません。