Kubernetes Deployment をスケーリングする

Kubernetes 環境では、ワークロードの需要の変化に応じてデータベース リソースを動的にスケーリングできます。Helm チャートを使用して Spanner Omni をデプロイした場合は、次のスケーリング手順を使用します。

始める前に

Kubernetes デプロイメントをスケーリングする前に、次の操作を行う必要があります。

おすすめの方法として、水平スケーリングのためにサーバーを追加する前に、サーバーごとに少なくとも 32 GB のメモリまで垂直スケーリングすることをおすすめします。

制限事項

Kubernetes のスケーリングには次の制限があります。

  • ルート以外のサーバーのみ: 水平スケーリングはルート以外の インスタンスでサポートされています。ルートサーバーのスケーリングはサポートされていません。

  • StatefulSet ストレージの制約: Kubernetes volumeClaimTemplates は不変であるため、 単一の helm upgrade コマンドを使用して Pod ディスクを拡張することはできません。代わりに、ストレージのスケーリングには手動によるボリューム拡張の手順が必要です。

垂直スケーリング

サーバーの CPU またはメモリリソースを調整するには、Helm アップグレードを使用して構成を更新します。

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set resources.cpu=CPU_CORES \
  --set resources.memory=MEMORY_LIMIT \
  -n NAMESPACE

次のように置き換えます。

  • HELM_CHART_PATH: Helm チャートのパス(例: oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni)。
  • VERSION: Helm チャートのバージョン(例: 0.3.0)。
  • CPU_CORES: 各サーバー Pod に割り当てる vCPU コアの数(例: 8)。
  • MEMORY_LIMIT: 各サーバー Pod の RAM 上限(例: 32Gi)。
  • NAMESPACE: デプロイメントの Kubernetes Namespace(例: spanner-ns)。

水平スケーリング

水平スケーリングを行うには、デプロイメントにサーバーを追加します。水平スケーリングはルート以外のサーバーでサポートされています。

ルート以外のサーバーを追加する

ルート以外のサーバーを追加するには、Helm チャート構成でレプリカ数を増やします。すべてのゾーンを均一にスケーリングすることも、特定のゾーンをスケーリングすることもできます。

均一にスケーリングする

デプロイメント内の各ゾーンを 15 台のサーバーにスケーリングするには、次のコマンドを実行します。

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set deployment.replicasPerZone=REPLICAS \
  -n NAMESPACE

次のように置き換えます。

  • HELM_CHART_PATH: Helm チャートのパス(例: oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni)。
  • VERSION: Helm チャートのバージョン(例: 0.3.0)。
  • REPLICAS: ゾーンあたりのサーバー レプリカの目標数(例: 15)。
  • NAMESPACE: Kubernetes Namespace(例: spanner-ns)。

特定のゾーンをスケーリングする

初期デプロイメントで個々のゾーンに異なるサーバー数が構成されている場合は、単一のゾーンをターゲットにできます。たとえば、最初のロケーション内の最初のゾーンのレプリカを 15 に増やすには、次のコマンドを実行します。

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set locations[0].zones[0].replicas=REPLICAS \
  -n NAMESPACE

REPLICAS は、ターゲット ゾーンのレプリカ数(例: 15)に置き換えます。

新しいサーバーがデプロイメントに正常に参加したことを確認するには、 Spanner Omni CLI をクエリしてデプロイメント サーバーを一覧表示するか、 Grafana ダッシュボードを表示します。

spanner deployment servers list \
  --zone=ZONE \
  --deployment-endpoint=ENDPOINT

次のように置き換えます。

  • ZONE: 一覧表示するゾーン(例: us-central1-a)。
  • ENDPOINT: デプロイメントの外部エンドポイント(例: ${ENDPOINT}:15000)。

ルート以外のサーバーを削除する

サーバーをスケールダウンするには、追加の手順が必要です。システムは、使用停止になったサーバーからデータ パーティションを安全に再配置する必要があるためです。Kubernetes StatefulSet はインデックスの高い順に Pod を削除するため、最初に削除するターゲットはインデックスが最も高いルート以外のサーバーにする必要があります。

サーバーの数をスケールダウンする手順は次のとおりです。

  1. ゾーン内のサーバーを一覧表示して、削除候補を特定します。

    spanner deployment servers list \
      --zone=ZONE \
      --deployment-endpoint=ENDPOINT
    

    出力例:

    NAME                                                          HOST                        PORT_BASE  ROOT  STATE
    zones/us-central1-a/servers/spanner-a-0.pod.spanner-ns:15000  spanner-a-0.pod.spanner-ns  15000      true  -
    zones/us-central1-a/servers/spanner-a-1.pod.spanner-ns:15000  spanner-a-1.pod.spanner-ns  15000      -     -
    

    インデックスが最も高い使用停止のルート以外のサーバー(例: spanner-a-1.pod.spanner-ns:15000)を削除します。

    spanner deployment servers delete SERVER_NAME \
      --zone=ZONE \
      --deployment-endpoint=ENDPOINT
    

    SERVER_NAME は、サーバー ID(例: spanner-a-1.pod.spanner-ns:15000)に置き換えます。

    ターゲット サーバーがリストから削除されるまで、サーバーリストを確認します。 削除後、サーバーはシステム内で異常な状態に移行し、アクティブなサービスパスから削除されます。

  2. Helm アップグレード コマンドを実行して、ターゲット レプリカ数に合わせて Helm デプロイメントをスケールダウンします。たとえば、ゾーンあたりのレプリカ数を 1 Pod に減らすには、次のコマンドを実行します。

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set deployment.replicasPerZone=REPLICAS \
      -n NAMESPACE
    

    REPLICAS は、更新されたレプリカ数(例: 1)に置き換えます。

  3. 削除された Pod に関連付けられている Kubernetes 永続ボリューム要求(PVC)を削除します。誤ってデータが失われるのを防ぐため、StatefulSet をスケールダウンしても、Helm と Kubernetes は PVC を自動的に削除しません。PVC を手動で削除して、ストレージを完全に再利用します。

    kubectl delete pvc LOGS_PVC DATA_PVC -n NAMESPACE
    

    たとえば、Namespace spanner-nsspanner-a-1 のログとデータボリュームを削除するには、次のようにします。

    kubectl delete pvc logs-volume-spanner-a-1 data-volume-spanner-a-1 -n spanner-ns
    

ゾーンを追加する

デプロイメントに新しいゾーンを追加すると、可用性が向上し、単一ゾーンの停止からデータベースを保護できます。

たとえば、次のコマンドは、 Google Kubernetes Engine(GKE)で実行中の単一ゾーン デプロイメントを、us リージョンの us-east1-b ゾーンで初期化します。

helm upgrade --install spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --set resources.cpu=2 \
  --set resources.memory=8Gi \
  --set global.platform=gke \
  --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"}]}]' \
  -n NAMESPACE

次の手順で、ゾーン us-east1-c をこの構成に追加します。

  1. helm upgrade コマンドを実行し、新しいロケーション ゾーンを含む更新された JSON ブロックを渡して、新しいゾーンに Pod を起動します。

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"},{"name":"us-east1-c","shortName":"east-c"}]}]' \
      -n NAMESPACE
    
  2. Spanner Omni CLI を使用して新しいゾーンを追加します。新しく作成されたゾーンのルートサーバー Pod が Running 状態になり、準備が整うまで待ちます。次に、ゾーン作成コマンドを実行します。

    spanner deployment zones create NEW_ZONE \
      --location=LOCATION \
      --root-servers=ROOT_SERVERS_LIST \
      --deployment-endpoint=ENDPOINT
    

    次のように置き換えます。

    • NEW_ZONE: 追加するゾーンの ID(例: us-east1-c)。
    • LOCATION: デプロイメントのロケーション(例: us)。
    • ROOT_SERVERS_LIST: 新しいゾーンのルートサーバー エンドポイントのカンマ区切りのリスト(例: spanner-east-c-0.pod.spanner-ns:15000,spanner-east-c-1.pod.spanner-ns:15000,spanner-east-c-2.pod.spanner-ns:15000)。
    • ENDPOINT: 外部デプロイメント エンドポイント( 例: ${ENDPOINT}:15000)。
  3. ゾーンの作成が完了するまで待ちます。既存のデータベース スキーマとテーブルを新しいゾーンにレプリケートするには時間がかかります。デプロイメント ゾーンを一覧表示して、ゾーンの同期の進行状況をモニタリングします。

    spanner deployment zones list --deployment-endpoint=ENDPOINT
    

ゾーンを削除する

マルチゾーン デプロイメントからアクティブなゾーンを廃止して、リソースを削減したり、トポロジの変更に合わせたりできます。

次の手順で、前のセクションで作成したゾーン us-east1-c を削除します。

  1. ゾーンを削除し、Spanner Omni 内でゾーンの削除を開始します。

    spanner deployment zones delete ZONE --deployment-endpoint=ENDPOINT
    

    ZONE は、削除するゾーン(例: us-east1-c)に置き換えます。

  2. ゾーンが削除されたことを確認します。リスト コマンドを実行し、出力にゾーンが表示されなくなるまで待ちます。

    spanner deployment zones list --deployment-endpoint=ENDPOINT
    
  3. helm upgrade コマンドを実行し、削除されたゾーンを除外する更新されたロケーション JSON ブロックを渡して、Kubernetes クラスタからサーバーを削除します。

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"}]}]' \
      -n NAMESPACE
    

ストレージをスケーリングする

Kubernetes の volumeClaimTemplates は不変であるため、helm upgrade コマンドを直接使用して Pod ストレージ容量をスケールアップすることはできません。代わりに、手動でボリュームを拡張する必要があります。詳細については、 GKE StatefulSet ボリューム拡張ガイドをご覧ください。

ディスク ストレージを拡張する手順は次のとおりです。

  1. ボリューム拡張のパラメータをターミナルの環境変数として定義します。

    NEW_SIZE="NEW_SIZE"
    NAMESPACE="NAMESPACE"
    RELEASE_NAME="spanner-omni"
    STATEFULSET_NAMES="STATEFULSET_NAME_1 STATEFULSET_NAME_2 STATEFULSET_NAME_3"
    HELM_CHART_PATH="HELM_CHART_PATH"
    VERSION="VERSION"
    

    次のように置き換えます。

    • NEW_SIZE: ターゲット ストレージ容量サイズ(例: 200Gi)。
    • NAMESPACE: Kubernetes Namespace(例: spanner-ns)。
    • STATEFULSET_NAME_1, STATEFULSET_NAME_2, ...: デプロイメント内の StatefulSetsの名前。通常はゾーンの短い名前に対応します(例: 例: spanner-east-b spanner-east-c)。
    • HELM_CHART_PATH: Helm チャートのパス(例: oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni)。
    • VERSION: Helm チャートのバージョン(例: 0.3.0)。
  2. コマンドを実行して PVC にパッチを適用し、StatefulSet を削除(バックエンド Pod はそのまま)して、Helm デプロイメントをアップグレードします。

    # Patch all associated PVCs directly.
    for pvc in $(kubectl get pvc -n $NAMESPACE \
      -l app.kubernetes.io/instance=$RELEASE_NAME \
      -o name | grep "data-volume"); do
      kubectl patch $pvc -n $NAMESPACE -p "{\"spec\":{\"resources\":{\"requests\":{\"storage\":\"$NEW_SIZE\"}}}}"
    done
    
    # Delete the StatefulSet while leaving backend pods intact (orphan cascade).
    kubectl delete statefulset $STATEFULSET_NAMES -n $NAMESPACE --cascade=orphan
    
    # Run Helm upgrade to align the templates with the expanded size.
    helm upgrade $RELEASE_NAME $HELM_CHART_PATH \
      --version $VERSION \
      --reuse-values \
      --set storage.data.size=$NEW_SIZE \
      -n $NAMESPACE
    

次のステップ