Kubernetes で Spanner Omni のマルチクラスタ デプロイを作成する

このドキュメントでは、複数の Kubernetes クラスタに Spanner Omni デプロイを設定する方法について説明します。Spanner Omni は、TLS 暗号化の有無にかかわらずデプロイできます。暗号化を使用する場合、Spanner Omni は Transport Layer Security(TLS)1.3 を使用して、デプロイ内およびクライアントとの通信を暗号化して認証します。

TLS 暗号化を使用しないデプロイには、次のようなセキュリティ リスクがあります。

  • IP アドレスにアクセスできるユーザーは誰でもデプロイにアクセスできます。
  • クライアントとサーバー間、または Pod 間でネットワーク暗号化が行われません。

このようなリスクがあるため、本番環境では TLS 暗号化で構成されていないデプロイは避けてください。

Spanner Omni のプレビュー版では TLS 暗号化がサポートされておらず、デプロイの作成から 90 日後にデータの書き込みが停止します。すべての機能を備えたエディションに早期アクセスするには、 Google にお問い合わせください

始める前に

デプロイの準備として、次の要件を満たしてください。

  • デプロイするロケーションごとに複数の Kubernetes クラスタを作成します。 クラスタ内の 1 つのゾーンにのみデプロイする場合は、クラスタをゾーンに配置できます。 Spanner Omni は、Google Kubernetes Engine(GKE)環境と Amazon Elastic Kubernetes Service(Amazon EKS)環境の Helm チャート構成をサポートしています。他の環境では、カスタム構成が必要になる場合があります。

  • Artifact Registry でホストされているコンテナ イメージにアクセスします。

  • kubectl コマンドライン ツールHelm をインストールして構成します。

  • vSphere 仮想化プラットフォーム マシンに Kubernetes 環境を設定する場合は、仮想マシンの .vmx 構成ファイルに monitor_control.virtual_rdtsc = FALSE を追加して、タイムスタンプ カウンタ(TSC)の仮想化を無効にします。これにより、TrueTime が正しく動作します。

  • 1 つのクラスタ内の Pod が別のクラスタ内の Pod と接続できるように、Kubernetes クラスタ ネットワークを構成します。デフォルトでは、Spanner Omni は内部通信に TCP ポート 15000 ~ 15025 を使用します。これらのクラスタ内の Pod 間の通信を有効にするには、これらのポートをトラフィック用に開きます。

  • クラスタ DNS を構成して、Pod のホスト名(spanner-a-0.pod.spanner-ns-r1 など)を IP アドレスに解決します。 Spanner Omni では、異なるクラスタ内の Pod 間の TCP 接続にホスト名解決が必要です。

Helm チャート構成を準備する

Helm 構成を作成します。詳細については、 Helm 構成を作成するをご覧ください。

整合性のためのクォーラムを確保するには、ゾーンあたりのルートサーバーの数を 1 ~ 9 の奇数にする必要があります。サーバーの数が偶数の場合、デプロイが失敗する可能性があります。ゾーンを構成するときに、サーバーをルートサーバーとして指定します。開発またはテストには 1 つ、高可用性の本番環境ゾーンには 3 つを使用することをおすすめします。

これはマルチクラスタ デプロイであるため、Helm 構成 YAML ファイルに次のものが含まれていることを確認してください。

# This is required for a multi-cluster deployment setup.

deployment:
  multiCluster: true

マルチクラスタ デプロイの Helm チャート構成の例

Spanner Omni マルチクラスタ デプロイ用に構成された Helm チャートの例を次に示します。この構成では、 Google Cloud 3 つのリージョンにデプロイが作成されます。us-west1us-west2、 および us-west3デプロイは 5 つのゾーンに分散され、各ゾーンはレプリカを表します。us-west1us-west2 のレプリカは読み取り / 書き込みですが、us-west3 の単一レプリカはウィットネス レプリカです。

# The platform of the deployment
global:
  platform: gke

# This is required for a multi-cluster deployment setup.
deployment:
  multiCluster: true

# Locations and zones where clusters are created for the deployment
locations:
  - name: us-west1
    namespace: spanner-ns-usw1
    zones:
      - name: "us-west1-a"
        shortName: "a"
      - name: "us-west1-b"
        shortName: "b"
  - name: us-west2
    namespace: spanner-ns-usw2
    zones:
      - name: "us-west2-a"
        shortName: "a"
      - name: "us-west2-b"
        shortName: "b"
  - name: us-west3
    namespace: spanner-ns-usw3
    zones:
      - name: "us-west3-a"
        shortName: "a"
        replicaType: WITNESS

# Remaining configuration like storage, resources, isn't included in this sample.

複数のクラスタに接続するように kubectl を構成する

続行する前に、kubectl コンテキストを使用してクラスタを作成します。たとえば、 Helm 構成 YAML ファイルで、ロケーションに基づいてコンテキストに 名前を付けることができます(ctx-usw1ctx-usw2ctx-usw3 など)。

TLS 暗号化を構成する

暗号化なしでデプロイを設定する場合は、 クラスタごとに Helm チャートをインストールするに進みます。

マルチクラスタ デプロイで TLS 暗号化を構成するには、認証局(CA)を作成し、クラスタごとに証明書を生成する必要があります。詳細については、 Kubernetes デプロイに TLS 暗号化を追加するをご覧ください。

証明書を生成する

サーバーと API の CA と証明書を作成します。サーバー証明書と API 証明書には、すべてのクラスタのホストを含める必要があります。

Spanner Omni サーバー証明書を作成する

Spanner Omni サーバーは、サーバー証明書を使用してサーバー間の通信を暗号化します。

サーバー証明書を作成するには、次のコマンドを実行します。 SERVER_LIST は、 Spanner Omni サーバー Pod の FQDN のカンマ区切りリストに置き換えるか、ワイルドカードを使用します。

SERVER_NAMES=*.pod.spanner-ns-usw1,*.pod.spanner-ns-usw2,*.pod.spanner-ns-usw3
Spanner Omni CLI certificates create-server --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

API 証明書を作成する

API 証明書は、デプロイとやり取りするシステムからの通信を暗号化します。

API 証明書を作成するには、次のコマンドを実行します。 OMNI_ENDPOINT は、クラスタごとのサービス エンドポイントに置き換えます。

OMNI_ENDPOINT=spanner.spanner-ns-usw1,spanner.spanner-ns-usw2,spanner.spanner-ns-usw3
Spanner Omni CLI certificates create-server --filename-prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output-directory certs

証明書を各 Kubernetes クラスタに push する

クラスタごとに、Namespace と証明書を含む汎用 Secret を作成します。

# Repeat for each context (for example, ctx-usw1, ctx-usw2, ctx-usw3)
# Replace NAMESPACE with the appropriate namespace for each region

kubectl create namespace <var>NAMESPACE</var> --context <var>CONTEXT</var>
kubectl create secret generic tls-certs \
  --from-file=ca.crt="certs/ca.crt" \
  --from-file=ca-api.crt="certs/ca-api.crt" \
  --from-file=server.crt="certs/server.crt" \
  --from-file=server.key="certs/server.key" \
  --from-file=api.crt="certs/api.crt" \
  --from-file=api.key="certs/api.key" \
  -n <var>NAMESPACE</var> \
  --context <var>CONTEXT</var>

クラスタごとに Helm チャートをインストールする

Helm 構成を作成します。詳細については、 Helm 構成を作成するをご覧ください。

マルチクラスタ デプロイの場合は、Helm 構成ファイルの Helm 構成を各 Kubernetes クラスタに適用します。各コマンドで、特定のロケーションとその Namespace をターゲットにして、Spanner Omni デプロイにバインドします。Helm 構成ファイルに記載されているのと同じ順序で、各ロケーションに構成を適用します。最後のロケーションに構成を適用すると、そのクラスタにデプロイ ブートストラップ ジョブが作成されます。

クラスタごとに Helm をインストールする前に、オブザーバビリティ スタックをホストするクラスタにモニタリング Namespace を作成します。

kubectl create namespace monitoring --context ctx-usw1

Helm チャートのインストール コマンドの例

次のコマンドは、クラスタに Helm チャートをインストールします。各コマンドで、 PATH_TO_HELM_CONFIG_FILE は、デプロ M 用に作成した Helm チャート構成 YAML ファイルのパスです。

モニタリングを有効にして us-west1 にチャートをインストールする

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 0.1.0 \
  -f PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw1 \
  --set currentLocation=us-west1 \
  --set monitoring.enabled=true \
  --create-namespace \
  --kube-context ctx-usw1

モニタリングなしで us-west2 にチャートをインストールする

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 0.1.0 \
  -f  PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw2 \
  --set currentLocation=us-west2 \
  --create-namespace \
  --kube-context ctx-usw2

モニタリングなしで us-west3 にチャートをインストールする

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 0.1.0 \
  -f  PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw3 \
  --set currentLocation=us-west3 \
  --create-namespace \
  --kube-context ctx-usw3

デプロイの進行状況を確認する

Helm チャート構成を適用すると、各 Kubernetes クラスタでブートストラップ ジョブが開始されます。最後のクラスタでブートストラップ ジョブが開始されたら、次のコマンドを実行してデプロイ プロセスを確認します。

kubectl logs -n spanner-ns-usw3 -l app.kubernetes.io/component=bootstrap -f

ログに、デプロイがすべてのサーバーに到達できないことが示されている場合は、各 クラスタの DNS サービスが正しく構成されていることを確認してください

クラスタ DNS サービスを構成する

Kubernetes クラスタで 外部 DNS を使用していて、 ヘッドレス サービスの DNS エントリを管理している場合は、 この手順をスキップできます。

Spanner は、すべての内部通信に Pod ホスト名を使用します。 Pod が異なる Kubernetes クラスタで実行されている場合でもホスト名を解決できるように DNS を構成します。これを行うには、他のクラスタが dns-setup.sh スクリプトを実行してアクセスできるように、各クラスタで kube-dns サービスを公開します。

このスクリプトは、kube-dns アプリケーション用に各クラスタにロードバランサ サービスをデプロイし、ロードバランサ サービスを参照するように DNS 構成を更新します。dns-setup.sh は GKE と Amazon EKS で kube-dnsCoreDNS を構成しますが、環境に合わせて構成する必要がある場合があります。

クラスタ DNS サービスを構成するには:

  1. まだダウンロードしていない場合は、spanner-omni Cloud Storage バケットから dns-setup.sh スクリプトをダウンロードします。

    Spanner Omni バケットに移動

  2. dns-setup.sh スクリプトを実行します。

    dns-setup.sh -n CSV_NAME_SPACE_LIST CONTEXTS
    
    • CSV_NAME_SPACE_LIST は、Namespace のカンマ区切りのリストに置き換えます。

    • CONTEXTS は、コンテキストのリストに置き換えます。

    dns-setup.sh スクリプトの使用例を次に示します。

    dns-setup.sh -n spanner-ns-usw1,spanner-ns-usw2,spanner-ns-usw3 ctx-usw1 ctx-usw2 ctx-usw3
    

スクリプトを実行したら、デプロイ ジョブのログを確認します。デプロイが進行中であることを示すメッセージが表示され、Deployment created successfully メッセージが表示されます。

API 証明書を更新する

TLS 暗号化なしでデプロイを設定する場合は、 Spanner Omni を操作するに進みます。

TLS 暗号化を実装するには、クラスタごとにロードバランサの外部 IP アドレスまたは DNS 名を使用して API 証明書を更新する必要があります。これにより、クライアントは安全なチャネルでデプロイに接続できます。

  1. クラスタごとにサービスの詳細を取得します。

    kubectl get service spanner -n spanner-ns-usw1 --context ctx-usw1
    kubectl get service spanner -n spanner-ns-usw2 --context ctx-usw2
    kubectl get service spanner -n spanner-ns-usw3 --context ctx-usw3
    
  2. 外部 IP アドレスを使用して API 証明書を更新します。

    # Replace <var>EXTERNAL_IP_USW1</var>, <var>EXTERNAL_IP_USW2</var>, and <var>EXTERNAL_IP_USW3</var>
    # with the actual external IP addresses or DNS names.
    
    OMNI_ENDPOINT=<var>EXTERNAL_IP_USW1</var>,<var>EXTERNAL_IP_USW2</var>,<var>EXTERNAL_IP_USW3</var>,spanner.spanner-ns.svc
    Spanner Omni CLI certificates update --filename_prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output_directory certs --overwrite
    
  3. 新しい API 証明書を使用して、各 Kubernetes クラスタの Secret を更新します。

    # Repeat for each context
    kubectl patch secret tls-certs -n spanner-ns-usw1 --context ctx-usw1 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    kubectl patch secret tls-certs -n spanner-ns-usw2 --context ctx-usw2 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    kubectl patch secret tls-certs -n spanner-ns-usw3 --context ctx-usw3 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    

Spanner Omni を操作する

マルチクラスタ設定の各クラスタには、1 つのロードバランサ サービスがあります。サービスの外部 IP アドレスを使用して、Spanner Omni を操作できます。書き込みと強力な読み取りには、リーダー リージョンとして機能するアドレスを使用します。ステイル読み取りリクエストの場合は、アプリケーションに最も近いリージョンを使用して、最適なパフォーマンスを実現します。

  1. 次のコマンドを実行して、緊急対応用住所を取得します。

    kubectl get service spanner -n spanner-ns-usw1 --context ctx-usw1
    

    EXTERNAL-IP:PORT は、DEPLOYMENT_ENDPOINT です。

  2. まだダウンロードしていない場合は、spanner-omni Cloud Storage バケットから Spanner Omni CLI をダウンロードします。

    Spanner Omni バケットに移動

  3. TLS 暗号化を使用してデプロイを作成した場合は、暗号化された接続を確立するために、各コマンドに CA 証明書を含める必要があります。クライアントで mTLS を有効にした場合は、クライアント証明書ディレクトリも追加します。

    • --ca-certificate-file=certs/ca-api.crt
    • --client-certificate-directory=clientcerts
  4. Spanner Omni CLI を使用して、GoogleSQL または PostgreSQL データベースを作成して操作します。

    GoogleSQL

    GoogleSQL データベースを作成して操作するには、次のコマンドを実行します。

    Spanner Omni CLI databases create DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    Spanner Omni CLI sql --database=DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    

    PostgreSQL

    PostgreSQL データベースを作成して操作するには、次のコマンドを実行します。

    Spanner Omni CLI databases create POSTGRESQL_DATABASE_NAME \
      --database_dialect POSTGRESQL \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    Spanner Omni CLI sql --database=POSTGRESQL_DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    

    PGAdapter を使用して接続する の手順に沿って PGAdapter を構成し、PostgreSQL 言語データベースで psqlなどの PostgreSQL ツールを使用することで、PostgreSQL データベースを操作することもできます。

次のステップ