はじめに
StatefulSetは、ステートフルなアプリケーションを管理するうえで強力なKubernetesリソースです。一方で構成が複雑になりやすく、バックアップが難しいという課題もあり、障害発生時のデータ損失につながりかねません。
2022年、GoogleはGKE向けの新しいアドオン機能として Backup for GKE を発表しました。コンテナ化されたアプリケーションとデータをまとめて保護・管理・復元できる、シンプルかつクラウドネイティブなソリューションです。
本記事では、Backup for GKEの構成要素と、GKEクラスタ上にデプロイしたMySQL StatefulSetのボリュームをバックアップする手順を紹介します。
アーキテクチャ
Backup for GKEは、主に2つのコンポーネントで構成されています。
- Google Cloud上で動作し、リソースベースのREST APIを提供する サービス。Backup for GKEのコントロールプレーンとして機能し、Google CloudコンソールのUIもこのAPI経由で連携します。
- バックアップやリストアを実行する各クラスタ上で動作する エージェント。Backup for GKE APIと連携し、クラスタ内でバックアップ・リストア処理を実行します。
Backup for GKEは、GKEのUI、Google Cloud CLI、REST APIと統合されており、開発・運用を通じて一貫したワークフローを実現します。バックアップでは次の2種類のデータが取得されます。
- Configバックアップ:バックアップ対象クラスタのAPIサーバーから取得したKubernetesリソースマニフェストの集合で、クラスタの状態を表します。
- ボリュームバックアップ:configバックアップ内の
PersistentVolumeClaimリソースに対応するボリュームバックアップの集合です。
バックアップやリストアの対象とするworkloadsは個別に選ぶことも、すべてを一括で対象にすることもできます。あるクラスタでバックアップしたworkloadsを別のクラスタに復元することも可能です。バックアップをスケジュール実行に設定しておけば、インシデント発生時にもworkloadsを迅速に復旧できます。
実践
ここからは、ゾーンGKEクラスタを作成し、MySQLのStatefulSetをデプロイしたうえで、DBのバックアップ作成とリストアを実際に試していきます。
変数を定義する
作業をシンプルにするため、いくつかの環境変数を用意しておきましょう。
export PROJECT_ID=felipe-playground-378415
export REGION=us-east1
export LOCATION=us-east1-c
export CLUSTER=backup-for-gke
export BK_PLAN_ALL_NAMESPACES=mysql-bk-plan-all-ns
export RESTORE_PLAN_ALL_NAMESPACES=mysql-bk-plan-all-ns
export BK_ALL_NAMESPACES=mysql-bk-all-namespaces
export RESTORE_ALL_NAMESPACES=mysql-restore-all-namespaces
GKEクラスタを作成する
コマンドを扱いやすくするため、変数を設定します。PROJECT_ID はご自身のプロジェクトIDに置き換えてください。本演習では us-east1-c ゾーンにゾーンクラスタを作成します。ゾーンクラスタは単一のゾーンにコントロールプレーンを 1つ 持つ構成です。本番のworkloadsには、リージョン内の複数ゾーンでコントロールプレーンを冗長化でき、可用性に優れたリージョナルクラスタの利用をおすすめします。本演習ではVPCやサブネット、ノード数、サービスアカウントなどをすべてデフォルト値で構成していますが、本番環境ではデフォルト値の使用は推奨しません。
コマンドには必ず --addons=BackupRestore フラグを付けてください。これによりバックアップコントローラーと関連するCRDがまとめてデプロイされます。
gcloud container clusters create ${CLUSTER} \
--release-channel stable \
--zone ${LOCATION} \
--node-locations ${LOCATION} \
--project ${PROJECT_ID} \
--addons=BackupRestore
続いて、クラスタに接続します。
gcloud container clusters get-credentials ${CLUSTER} \
--zone ${LOCATION} \
--project ${PROJECT_ID}
StatefulSetをインストールする
それではStatefulSetを作成しましょう。本演習では、Helmで手軽にインストールできるMySQL operatorを使用します。
helm repo add mysql-operator https://mysql.github.io/mysql-operator/
helm repo update
helm install my-mysql-operator mysql-operator/mysql-operator \
--namespace mysql-operator --create-namespace
MySQLをインストールする
HelmでMySQLをインストールします。パスワードは必ず変更してください。
helm install mycluster mysql-operator/mysql-innodbcluster \
--set tls.useSelfSigned=true \
--set credentials.root.user=safeuser \
--set credentials.root.password=notsupersafepassword \
--set credentials.root.host="%"
kubectl get pods,pvc を実行すると、次のような出力が確認できるはずです。
NAME READY STATUS RESTARTS AGE
pod/mycluster-0 2/2 Running 0 23m
pod/mycluster-1 2/2 Running 0 23m
pod/mycluster-2 2/2 Running 0 23m
pod/mycluster-router-67585969f6-m9nd7 1/1 Running 0 22m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/datadir-mycluster-0 Bound pvc-d5214172-9b81-4d29-9bf0-9e0dcdc8f691 2Gi RWO standard-rwo 23m
persistentvolumeclaim/datadir-mycluster-1 Bound pvc-df8e188a-51aa-4c4f-acb1-73daa72bc721 2Gi RWO standard-rwo 23m
persistentvolumeclaim/datadir-mycluster-2 Bound pvc-defb5e6e-5946-4183-99d2-c168b05a3d6c 2Gi RWO standard-rwo 23m
準備ができました。次は、このクラスタ向けにBackup for GKEのリソースを設定していきます。
Backup for GKEには、構成と制御のための2種類のリソースがあります。
BackupPlan:一連のバックアップを表すBackupリソースの親リソースです。ソースクラスタ、バックアップ対象のworkloadsの選択、このプランで生成されたBackupアーティファクトの保存先リージョンなど、バックアップ設定を保持します。RestorePlan:再利用可能なリストアテンプレートを提供します。リストア先のターゲットクラスタ、ソースとなるバックアッププラン、リストアの範囲、コンフリクトの扱い、置換ルールなど、リストア設定を保持します。
全ネームスペース対象のバックアッププランを作成する
gcloud beta container backup-restore backup-plans create ${BK_PLAN_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--cluster=projects/${PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER} \
--all-namespaces \
--include-secrets \
--include-volume-data
全ネームスペース対象のリストアプランを作成する
gcloud beta container backup-restore restore-plans create ${RESTORE_PLAN_ALL_NAMESPACES}\
--all-namespaces \
--project=${PROJECT_ID} \
--location=${REGION} \
--backup-plan=projects/${PROJECT_ID}/locations/${REGION}/backupPlans/${BK_PLAN_ALL_NAMESPACES} \
--cluster=projects/${PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER} \
--cluster-resource-conflict-policy=use-existing-version \
--namespaced-resource-restore-mode=delete-and-restore \
--volume-data-restore-policy=restore-volume-data-from-backup \
--cluster-resource-restore-scope="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"
上記のコマンドが問題なく実行できれば、必要なプランはすべて整いました。
全ネームスペースを対象にバックアップを作成する
gcloud beta container backup-restore backups create ${BK_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--backup-plan=${BK_PLAN_ALL_NAMESPACES} \
--wait-for-completion
ボリュームのサイズによっては時間がかかる場合がありますが、完了すると次のメッセージが表示されます。
Backup completed. Backup state: SUCCEEDED
バックアップからのリストアをテストする
gcloud beta container backup-restore restores create ${RESTORE_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--restore-plan=${RESTORE_PLAN_ALL_NAMESPACES} \
--backup=projects/$PROJECT_ID/locations/${REGION}/backupPlans/${BK_PLAN_ALL_NAMESPACES}/backups/${BK_ALL_NAMESPACES} \
--wait-for-completion
Restore Completed. Restore stat: SUCCEEDED
これで問題なく動作します。
Backup for GKEでは、CRDの ProtectedApplication を使って作成した単一のアプリケーションバンドルをバックアップすることもできますが、こちらは別の記事で取り上げます。
IaC
2023年6月時点では、GKEバックアッププランを作成できるTerraformリソースは google_gke_backup_backup_plan の1つのみで、Googleプロバイダー 4.5.0 で追加されました。詳細はこちらをご覧ください。今後、対応リソースが拡充されることに期待しましょう。
料金
Backup for GKEの料金は2つの軸で発生します。1つ目は保護対象のGKE Pod数に応じたGKEバックアップ管理料、2つ目は保存データ量(GB)に応じたバックアップストレージ料です。いずれもGKEの他機能と同様に月単位で計算されます。
たとえば、アイオワ(us-central1)で1つのバックアッププランを運用し、月平均20個のPodをバックアップしながら同リージョンに200GBのバックアップデータを保管するケースでは、料金は$25.60となります。内訳は、GKEバックアップ管理料が$20(20 × $1.00 / Pod・月)、バックアップストレージ料が$5.60(200 × $0.028 / GB・月)です。
2023年6月26日からは、ソースGKEクラスタとは異なるリージョンに保管するバックアップに対し、新たにネットワーク下り料金が導入されます。料金は、ソースおよび宛先リージョンと、こうした「クロスリージョン」バックアップ操作ごとの転送バイト数に基づいて算出されます。
クリーンアップ
クラスタを削除します。
gcloud container clusters delete ${CLUSTER} --project $PROJECT_ID --zone ${LOCATION}
バックアップとプランの削除も忘れずに行いましょう。
# Delete backup
gcloud beta container backup-restore backups delete ${BK_ALL_NAMESPACES} \
--location=${REGION} \
--backup-plan=${BK_PLAN_ALL_NAMESPACES}
# Delete backup plan
gcloud beta container backup-restore backup-plans delete ${BK_PLAN_ALL_NAMESPACES} \
--location=${REGION}
# Delete restore plan
gcloud beta container backup-restore restore-plans delete ${RESTORE_PLAN_ALL_NAMESPACES} \
--location=${REGION}
本記事がお役に立てば幸いです。ご質問があればお気軽にお寄せください。
Backup for GKEは、StatefulSetのデータ保護に役立つ強力なツールです。KubernetesでStatefulSetを運用しているなら、Backup for GKEの導入を検討する価値は十分にあります。
参考リソース:
Pricing | Google Kubernetes Engine (GKE) | Google Cloud \ Review pricing for GKE\ cloud.google.com