背景
本来、Pod はエフェメラルです。つまり、GKE は、Pod が削除、強制排除、または再スケジュールされると、Pod に保存されている状態と値を破棄します。
アプリケーション オペレータとしてステートフル ワークロードを維持したい場合があります。このようなワークロードの例には、WordPress の記事を処理するアプリ、メッセージ アプリ、ML オペレーションを処理するアプリなどがあります。
GKE で Filestore を使用すると、次の操作を行えます。
- スケーラブルなステートフル ワークロードをデプロイする。
- 複数の Pod が同じストレージに対して同時に読み書きできるように、複数の Pod で
ReadWriteMany
をaccessMode
として使用できるるようにする。 - 同時に複数の Pod へ Volume をマウントするように GKE を設定する。
- Pod が削除されてもストレージを保持する。
- Pod がデータを共有し、簡単にスケールできるようにする。
CSI を使用して Filestore でマネージド ファイル ストレージを構成する
GKE では、クラスタに Kubernetes Filestore CSI ドライバを自動でデプロイして管理できます。Filestore CSI を使用すると、Filestore インスタンスを動的に作成または削除でき、さらに StorageClass
や Deployment
と一緒に Kubernetes ワークロードで使用できます。
Filestore インスタンスと PV を動的にプロビジョニングする PVC を作成することで新しい Filestore インスタンス作成することも、Kubernetes ワークロードに事前にプロビジョニングされた Filestore インスタンスにアクセスすることも可能です。
新しいインスタンス
ストレージ クラスを作成する
volumeBindingMode
がImmediate
に設定されていると、Volume のプロビジョニングをすぐに開始できます。- Filestore インスタンスの作成時間を短縮するため、
tier
はstandard
に設定されています。高可用性のある NFS ストレージ、データ バックアップ用のスナップショット、複数のゾーンにわたるデータ レプリケーション、その他のエンタープライズ レベルの機能が必要な場合は、代わりにtier
をenterprise
に設定します。注:StorageClass
でreclaimPolicy
が設定されていない場合、動的に作成された PV の再利用ポリシーのデフォルトはDelete
になります。
StorageClass
リソースを作成します。kubectl create -f filestore-storageclass.yaml
ストレージ クラスが作成されていることを確認する
kubectl get sc
出力は次のようになります。
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE filestore-sc filestore.csi.storage.gke.io Delete Immediate true 94m
事前プロビジョニングされたインスタンス
ストレージ クラスを作成する
volumeBindingMode
が Immediate
に設定されると、Volume のプロビジョニングをすぐに開始できます。
StorageClass
リソースを作成します。kubectl create -f preprov-storageclass.yaml
ストレージ クラスが作成されていることを確認する
kubectl get sc
出力は次のようになります。
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE filestore-sc filestore.csi.storage.gke.io Delete Immediate true 94m
Filestore インスタンス用の永続ボリュームを作成する
既存の Filestore インスタンスの準備ができていることを確認します。
gcloud filestore instances list
出力は次のようになります。ここで、
STATE
値はREADY
です。INSTANCE_NAME: stateful-filestore LOCATION: us-central1-a TIER: ENTERPRISE CAPACITY_GB: 1024 FILE_SHARE_NAME: statefulpath IP_ADDRESS: 10.109.38.98 STATE: READY CREATE_TIME: 2022-04-05T18:58:28
Filestore インスタンスの
INSTANCE_NAME
、LOCATION
、FILE_SHARE_NAME
、IP_ADDRESS
をメモします。Filestore インスタンスのコンソール変数を設定します。
INSTANCE_NAME=INSTANCE_NAME LOCATION=LOCATION FILE_SHARE_NAME=FILE_SHARE_NAME IP_ADDRESS=IP_ADDRESS
プレースホルダ変数を上記で取得したコンソール変数に置き換えて、
preprov-pv.yaml
ファイルにします。sed "s/<INSTANCE_NAME>/$INSTANCE_NAME/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml sed "s/<LOCATION>/$LOCATION/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml sed "s/<FILE_SHARE_NAME>/$FILE_SHARE_NAME/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml sed "s/<IP_ADDRESS>/$IP_ADDRESS/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml
PV を作成します。
kubectl apply -f preprov-pv.yaml
PV の
STATUS
がBound
に設定されていることを確認します。kubectl get pv
出力は次のようになります。
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE fileserver 1Ti RWX Delete Bound default/fileserver filestore-sc 46m
PersistentVolumeClaim を使用して Volume にアクセスする
次の pvc.yaml
マニフェストでは、filestore-sc
という名前の Filestore CSI ドライバの StorageClass
を参照しています。
複数の Pod での Volume の読み取り / 書き込みを可能にするため、accessMode
は ReadWriteMany
に設定します。
PVC をデプロイします。
kubectl create -f pvc.yaml
PVC が作成されていることを確認します。
kubectl get pvc
出力は次のようになります。
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE fileserver Bound pvc-aadc7546-78dd-4f12-a909-7f02aaedf0c3 1Ti RWX filestore-sc 92m
新しく作成された Filestore インスタンスの準備ができていることを確認します。
gcloud filestore instances list
出力は次のようになります。
INSTANCE_NAME: pvc-5bc55493-9e58-4ca5-8cd2-0739e0a7b68c LOCATION: northamerica-northeast2-a TIER: STANDARD CAPACITY_GB: 1024 FILE_SHARE_NAME: vol1 IP_ADDRESS: 10.29.174.90 STATE: READY CREATE_TIME: 2022-06-24T18:29:19
読み取り Pod と書き込み Pod を作成する
このセクションでは、読み取り Pod と書き込み Pod を作成します。このチュートリアルでは、Kubernetes Deployment を使用して Pod を作成します。Deployment は、クラスタ内のノードに分散された Pod の複数のレプリカを実行できる Kubernetes API オブジェクトです。
読み取り Pod を作成する
読み取り Pod は、書き込み Pod が書き込んでいるファイルを読み取ります。読み取り Pod は、どの書き込み Pod レプリカが、いつファイルに書き込んだかを確認します。
読み取り Pod は、すべての Pod 間で共有されるパス /usr/share/nginx/html
から読み取ります。
読み取り Pod をデプロイします。
kubectl apply -f reader-fs.yaml
Pod のリストをクエリして、読み取りレプリカが実行されていることを確認します。
kubectl get pods
出力は次のようになります。
NAME READY STATUS RESTARTS AGE reader-66b8fff8fd-jb9p4 1/1 Running 0 3m30s
書き込み Pod を作成する
書き込み Pod は、他の書き込み Pod や読み取り Pod がアクセスできる共有ファイルに定期的に書き込みます。書き込み Pod は、ホスト名を共有ファイルに書き込むことで、自身の存在を記録します。
書き込み Pod に使用されるイメージは、ユーティリティや本番環境アプリケーションに使用される Alpine Linux のカスタム イメージです。これには、最新の書き込み Pod のメタデータを取得して、すべての一意の書き込み Pod と合計書き込み数をカウントするスクリプト indexInfo.html
が含まれます。
このチュートリアルでは、書き込み Pod が 30 秒ごとにパス /html/index.html
に書き込みます。sleep
の数値を変更すると、書き込みの頻度が変わります。
書き込み Pod をデプロイします。
kubectl apply -f writer-fs.yaml
Pod のリストをクエリして、書き込み Pod が実行されていることを確認します。
kubectl get pods
出力は次のようになります。
NAME READY STATUS RESTARTS AGE reader-66b8fff8fd-jb9p4 1/1 Running 0 3m30s writer-855565fbc6-8gh2k 1/1 Running 0 2m31s writer-855565fbc6-lls4r 1/1 Running 0 2m31s
読み取り Pod を Service Load Balancer に公開してアクセスする
ワークロードをクラスタ外部に公開するには、LoadBalancer
タイプの Service を作成します。このタイプの Service は、インターネット経由で到達可能な IP アドレスを持つ外部ロードバランサを作成します。
LoadBalancer
タイプの Service をreader-lb
という名前で作成します。kubectl create -f loadbalancer.yaml
Deployment を watch して、GKE が
reader-lb
Service にEXTERNAL-IP
を割り当てていることを確認します。kubectl get svc --watch
Service
の準備が整うと、EXTERNAL-IP
列にロードバランサのパブリック IP アドレスが表示されます。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.8.128.1 <none> 443/TCP 2d21h reader-lb LoadBalancer 10.8.131.79 34.71.232.122 80:32672/TCP 2d20h
Ctrl+C キーを押して watch プロセスを終了します。
ウェブブラウザで、ロードバランサに割り当てられた
EXTERNAL-IP
に移動します。このページは 30 秒ごとに更新されます。書き込み Pod が多く、更新間隔が短いほど、表示されるエントリは多くなります。
ロードバランサ Service の詳細を確認するには、loadbalancer.yaml
をご覧ください。
書き込みをスケールアップする
PV の accessMode
が ReadWriteMany
に設定されているため、GKE は、より多くの書き込み Pod がこの共有ボリュームに書き込めるように(あるいは、より多くの読み取り Pod が読み取れるように)、Pod の数をスケールアップできます。
writer
を 5 つのレプリカにスケールアップします。kubectl scale deployment writer --replicas=5
出力は次のようになります。
deployment.extensions/writer scaled
実行中のレプリカの数を確認します。
kubectl get pods
出力は次のようになります。
NAME READY STATUS RESTARTS AGE reader-66b8fff8fd-jb9p4 1/1 Running 0 11m writer-855565fbc6-8dfkj 1/1 Running 0 4m writer-855565fbc6-8gh2k 1/1 Running 0 10m writer-855565fbc6-gv5rs 1/1 Running 0 4m writer-855565fbc6-lls4r 1/1 Running 0 10m writer-855565fbc6-tqwxc 1/1 Running 0 4m
ウェブブラウザで、ロードバランサに割り当てられた
EXTERNAL-IP
に再度移動します。
この時点で、5 つのステートフル書き込み Pod をサポートするようにクラスタを構成してスケールしました。複数の書き込み Pod は、同じファイルに同時に書き込みを行います。読み取り Pod のスケールアップも簡単です。
省略可: 書き込み Pod からデータにアクセスする
このセクションでは、コマンドライン インターフェースを使用して読み取り Pod や書き込み Pod にアクセスする方法について説明します。書き込み Pod が書き込み、読み取り Pod が読み取る対象の共有コンポーネントを確認できます。
書き込み Pod 名を取得します。
kubectl get pods
出力は次のようになります。
NAME READY STATUS RESTARTS AGE writer-5465d65b46-7hxv4 1/1 Running 0 20d
書き込み Pod のホスト名をメモします(例:
writer-5465d65b46-7hxv4
)。次のコマンドを実行して、書き込み Pod にアクセスします。
kubectl exec -it WRITER_HOSTNAME -- /bin/sh
indexData.html
ファイルの共有コンポーネントを確認します。cd /html cat indexData.html
indexData.html
ファイルを消去します。echo '' > indexData.html
EXTERNAL-IP
アドレスをホストするウェブブラウザを更新して、変更を確認します。環境を終了します。
exit