Kubernetes Deployment をスケーリングする

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

始める前に

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

ベスト プラクティスとして、水平方向にスケーリングするためにサーバーを追加する前に、サーバーあたり少なくとも 32 GB のメモリまで垂直方向にスケーリングすることをおすすめします。

制限事項

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

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

  • 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.2.0)。
  • CPU_CORES: 各サーバー Pod に割り当てる vCPU コアの数(例: 8)。
  • MEMORY_LIMIT: 各サーバー Pod の RAM 上限(32Gi など)。
  • NAMESPACE: デプロイの Kubernetes Namespace(例: spanner-ns)。

水平方向にスケーリングする

水平方向にスケーリングするには、デプロイメントにサーバーを追加します。水平スケーリングは、非ルート サーバーでサポートされています。

非ルート サーバーを追加する

非 root サーバーを追加するには、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.2.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 を削除するため、最初にインデックスが最も高い非 root サーバーを削除の対象にする必要があります。

サーバーの数をスケールダウンするには、次の操作を行います。

  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)廃止された非 root サーバーを削除します。

    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
    

    たとえば、名前空間 spanner-nsspanner-a-1 のログボリュームとデータ ボリュームを削除するには、次の操作を行います。

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

ゾーンを追加する

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

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

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: 追加するゾーンの識別子(例: 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 コマンドを実行し、削除されたゾーンを除外する更新された locations 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_1STATEFULSET_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.2.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
    

次のステップ