リージョン Cloud Service Mesh

リージョン分離を使用すると、Cloud Service Mesh コントロール プレーンの特定のリージョンに接続しているクライアントは、そのリージョン内のリソースのみにアクセスできます。同様に、特定のリージョン内の API リソースは、そのリージョン内の他のリソースのみを参照できます。

リージョン Cloud Service Mesh には、次の制限事項があります。

  • Istio API はサポートされていません。リージョン Traffic Director を使用して、Istio API で Kubernetes を使用することはできません。このプレビューでは Google Cloud API のみがサポートされています。
  • グローバル サービス ルーティング API の既存の考慮事項と制限事項が適用されます。
  • xdSTP 命名スキームをサポートする Envoy の最小バージョンは v1.31.1 です。
  • Gateway for Mesh API はサポートされていません。
  • gRPC の最小バージョンは v1.65 です。
  • 次のリージョンのみがサポートされています。

    africa-south1
    asia-east1
    asia-east2
    asia-northeast1
    asia-northeast2
    asia-northeast3
    asia-south1
    asia-south2
    asia-southeast1
    asia-southeast2
    australia-southeast1
    australia-southeast2
    europe-central2
    europe-north1
    europe-north2
    europe-southwest1
    europe-west10
    europe-west12
    europe-west1
    europe-west2
    europe-west3
    europe-west4
    europe-west6
    europe-west8
    europe-west9
    me-central1
    me-central2
    me-west1
    northamerica-northeast1
    northamerica-northeast2
    northamerica-south1
    southamerica-east1
    southamerica-west1
    us-central1
    us-east1
    us-east4
    us-east5
    us-south1
    us-west1
    us-west2
    us-west3
    us-west4
    

料金

この機能が一般提供されると、リージョン Cloud Service Mesh がサポートされている各リージョンでリージョン SKU が提供されます。現在のところ、料金はグローバルと同じです。

Cloud Service Mesh 用に xDS クライアントを準備する

Compute VM Envoy xDS

手動

手動の手順は、手動 Envoy デプロイを使用して VM を設定するに基づいています。主な違いは、ENVOY_CONTROL_PLANE_REGION を設定し、ブートストラップに挿入することです。

  1. インスタンス テンプレートを作成します。

    gcloud compute instance-templates create td-vm-templategcloud compute instance-templates create td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=http-td-tag,http-server,https-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script='#! /usr/bin/env bash
    
    # Set variables
    export ENVOY_CONTROL_PLANE_REGION="us-central1"
    export ENVOY_USER="envoy"
    export ENVOY_USER_UID="1337"
    export ENVOY_USER_GID="1337"
    export ENVOY_USER_HOME="/opt/envoy"
    export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
    export ENVOY_PORT="15001"
    export ENVOY_ADMIN_PORT="15000"
    export ENVOY_TRACING_ENABLED="false"
    export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
    export ENVOY_ACCESS_LOG="/dev/stdout"
    export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
    export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
    export GCE_METADATA_SERVER="169.254.169.254/32"
    export INTERCEPTED_CIDRS="*"
    export GCP_PROJECT_NUMBER=PROJECT_NUMBER
    export VPC_NETWORK_NAME=mesh:sidecar-mesh
    export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
    
    # Create system user account for Envoy binary
    sudo groupadd ${ENVOY_USER} \
      --gid=${ENVOY_USER_GID} \
      --system
    sudo adduser ${ENVOY_USER} \
      --uid=${ENVOY_USER_UID} \
      --gid=${ENVOY_USER_GID} \
      --home=${ENVOY_USER_HOME} \
      --disabled-login \
      --system
    # Download and extract the Cloud Service Mesh tar.gz file
    cd ${ENVOY_USER_HOME}
    sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
      -C bootstrap_template.yaml \
      --strip-components 1
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
      -C iptables.sh \
      --strip-components 1
    sudo rm traffic-director-xdsv3.tar.gz
    
    # Generate Envoy bootstrap configuration
    cat "${BOOTSTRAP_TEMPLATE}" \
      | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
      | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
      | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
      | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
      | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
      | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
      | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
      | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
      | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
      | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
      | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
      | sudo tee "${ENVOY_CONFIG}"
    
    # Install Envoy binary
    wget -O envoy_key https://apt.envoyproxy.io/signing.key
    cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
    sudo apt-get update
    sudo apt-get install envoy
    
    # Run Envoy as systemd service
    sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
      --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
      bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
    
    # Configure iptables for traffic interception and redirection
    sudo ${ENVOY_USER_HOME}/iptables.sh \
      -p "${ENVOY_PORT}" \
      -u "${ENVOY_USER_UID}" \
      -g "${ENVOY_USER_GID}" \
      -m "REDIRECT" \
      -i "${INTERCEPTED_CIDRS}" \
      -x "${GCE_METADATA_SERVER}"
    

Compute VM gRPC xDS

グローバル Cloud Service Mesh と同様に、gRPC クライアントでは、リージョン Cloud Service Mesh への接続方法を指示するためにブートストラップを構成する必要があります。

このブートストラップを生成するには、gRPC ブートストラップ生成ツールを使用します。リージョン Cloud Service Mesh を使用するように設定するには、新しいフラグ --xds-server-region を指定します。

この例では、xds-server-regionus-central1 に設定すると、リージョン Cloud Service Mesh エンドポイント trafficdirector.us-central1.rep.googleapis.com:443. が自動的に決定されます。

K8s 手動 Envoy インジェクション

手動の手順は、手動 Envoy インジェクションを使用して Google Kubernetes Engine Pod を設定するに基づいています。ただし、手動 Pod インジェクションに関するセクションのみ変更する必要があります。

  1. コントロール プレーンをグローバルからリージョンに変更します。

    wget -q -O - https://storage.googleapis.com/traffic-director/demo/trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s/PROJECT_NUMBER/PROJECT_NUMBER/g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s/MESH_NAME/MESH_NAME/g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s|trafficdirector.googleapis.com|trafficdirector.${REGION}.rep.googleapis.com|g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s|gcr.io/google-containers/busybox|busybox:stable|g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    1. 変更を適用します。

      kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml
        ```
      

設定ガイド

このセクションでは、5 つの独立した構成およびデプロイモデルについて説明します。これらはすべて、既存のグローバル サービス ルーティング API 設定ガイドのリージョン版です。

リージョン GRPCRoute とリージョン Cloud Service Mesh を使用してプロキシレス gRPC サービスを構成する

このセクションでは、リージョン Cloud Service Mesh リソースとリージョン GRPCRoute リソースを使用してプロキシレス gRPC サービス メッシュを構成する方法について説明します。

操作を容易にするため、このガイドのすべての例をコマンドラインにコピーして貼り付けられるように、構成を行う Google Cloud プロジェクト番号を格納してください。

export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"

PROJECT_NUMBER は、プロジェクト番号に置き換えます。

必要に応じて、次のように置き換えます。

  • us-central1 は、使用する別のリージョンに置き換えます。
  • us-central1-a は、使用する別のゾーンに置き換えます。
  • default は、別の VPC_NAME に置き換えます。

Mesh の構成

プロキシレス gRPC アプリケーションが xds://hostname に接続すると、gRPC クライアント ライブラリは Cloud Service Mesh への接続を確立し、ホスト名へのリクエストのルーティングに必要なルーティング構成を取得します。

  1. Mesh 仕様を作成し、mesh.yaml ファイルに保存します。

    cat <<EOF > mesh.yaml
    name: grpc-mesh
    EOF
    
  2. mesh.yaml 仕様を使用して Mesh を作成します。

    gcloud network-services meshes import grpc-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

    リージョン メッシュが作成されたら、Cloud Service Mesh が構成を提供する準備は完了です。ただし、サービスがまだ定義されていないため、構成は空です。

gRPC サービスの構成

デモ用に、自動スケーリングされた VM を含むリージョン バックエンド サービスを作成します(マネージド インスタンス グループ(MIG)を使用)。このサービスは、ポート 50051 で gRPC プロトコルを使用して hello world を出力します。

  1. ポート 50051 で公開されている helloworld gRPC サービスを使用して、Compute Engine VM インスタンス テンプレートを作成します。

    gcloud compute instance-templates create grpc-td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -e
    cd /root
    sudo apt-get update -y
    sudo apt-get install -y openjdk-11-jdk-headless
    curl -L https://github.com/grpc/grpc-java/archive/v1.38.0.tar.gz | tar -xz
    cd grpc-java-1.38.0/examples/example-hostname
    ../gradlew --no-daemon installDist
    # Server listens on 50051
    sudo systemd-run ./build/install/hostname-server/bin/hostname-server')
    
  2. テンプレートに基づいて MIG を作成します。

    gcloud compute instance-groups managed create grpc-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=grpc-td-vm-template
    
  3. gRPC サービスの名前付きポートを構成します。これは、gRPC サービスがリクエストをリッスンするように構成されているポートです。

    gcloud compute instance-groups set-named-ports grpc-td-mig-us-central1 \
      --named-ports=grpc-helloworld-port:50051 \
      --zone=${ZONE}
    

    この例では、ポートは 50051 です。

  4. gRPC ヘルスチェックを作成します。

    gcloud compute health-checks create grpc grpc-helloworld-health-check \
      --use-serving-port --region=${REGION}
    

    gRPC ヘルスチェックが正常に機能するように、サービスで gRPC ヘルスチェック プロトコルを実装する必要があります。詳細については、ヘルスチェックを作成するをご覧ください。

  5. ネットワーク内のインスタンスへの受信ヘルスチェック接続を許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create grpc-vm-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \
      --target-tags allow-health-checks \
      --rules tcp:50051
    
  6. ロード バランシング スキームが INTERNAL_SELF_MANAGED のリージョン バックエンド サービスを作成し、先ほど作成したヘルスチェックとマネージド インスタンス グループをバックエンド サービスに追加します。port-name で指定されたポートは、マネージド インスタンス グループ内の VM への接続に使用されます。

    gcloud compute backend-services create grpc-helloworld-service \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=GRPC \
        --port-name=grpc-helloworld-port \
      --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/grpc-helloworld-health-check" \
        --region=${REGION}
    
  7. マネージド インスタンス グループを BackendService に追加します。

    gcloud compute backend-services add-backend grpc-helloworld-service \
      --instance-group=grpc-td-mig-us-central1 \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

リージョン GRPCRoute を使用してルーティングを設定する

これで、リージョン メッシュと gRPC サーバー サービスの構成が完了しました。次に、必要なルーティングを設定できます。

  1. リージョン GRPCRoute 仕様を作成し、grpc_route.yaml ファイルに保存します。

    cat <<EOF > grpc_route.yaml
    name: helloworld-grpc-route
    hostnames:
    - helloworld-gce
    meshes:
    - projects/${PROJECT_NUMBER}/locations/${REGION}/meshes/grpc-mesh
    rules:
    - action:
        destinations:
        - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/grpc-helloworld-service
    EOF
    
  2. grpc_route.yaml 仕様を使用してリージョン GRPCRoute を作成します。

    gcloud network-services grpc-routes import helloworld-grpc-route \
        --source=grpc_route.yaml \
        --location=${REGION}
    

    これで、gRPC Route で指定されたサービスのトラフィックをマネージド インスタンス グループのバックエンド間でロード バランシングするように、Cloud Service Mesh が構成されました。

gRPC クライアント サービスを作成する

構成を確認するには、プロキシレス gRPC データプレーンを使用してクライアント アプリケーションをインスタンス化します。このアプリケーションは、ブートストラップ ファイルでメッシュの名前を指定する必要があります。

構成が完了すると、このアプリケーションは xds:///helloworld-gce サービス URI を使用して、helloworld-gce に関連付けられているインスタンスまたはエンドポイントにリクエストを送信できます。

次の例では、grpcurl ツールを使用して gRPC サービスをテストします。

  1. クライアント VM を作成します。

    gcloud compute instances create grpc-client \
      --zone=${ZONE}\
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -ex
    export PROJECT=PROJECT_NUMBER
    export REGION=us-central1
    export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json
    echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh
    curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.18.0.tar.gz | tar -xz
    ./td-grpc-bootstrap-0.18.0/td-grpc-bootstrap --config-mesh=grpc-mesh --xds-server-uri=trafficdirector.${REGION}.rep.googleapis.com:443 --gcp-project-number=${PROJECT} | sudo tee $GRPC_XDS_BOOTSTRAP
    sudo sed -i "s|\"authorities\": {|\"authorities\": {\n    \"traffic-director.${REGION}.xds.googleapis.com\": {\"xds_servers\":[{\"server_uri\": \"trafficdirector.${REGION}.rep.googleapis.com:443\", \"channel_creds\": [ { \"type\": \"google_default\" } ], \"server_features\": [ \"xds_v3\", \"ignore_resource_deletion\" ]}], \"client_listener_resource_name_template\": \"xdstp://traffic-director.${REGION}.xds.googleapis.com/envoy.config.listener.v3.Listener/${PROJECT}/mesh:grpc-mesh/%s\"},|g" $GRPC_XDS_BOOTSTRAP
    sudo sed -i "s|\"client_default_listener_resource_name_template\": \"xdstp://traffic-director-global.xds.googleapis.com|\"client_default_listener_resource_name_template\": \"xdstp://traffic-director.${REGION}.xds.googleapis.com|g" $GRPC_XDS_BOOTSTRAP')
    

環境変数とブートストラップ ファイルを設定する

クライアント アプリケーションには、ブートストラップ構成ファイルが必要です。前のセクションの起動スクリプトは、GRPC_XDS_BOOTSTRAP 環境変数を設定し、ヘルパー スクリプトを使用してブートストラップ ファイルを生成します。生成されたブートストラップ ファイル内の TRAFFICDIRECTOR_GCP_PROJECT_NUMBER とゾーンの値は、Compute Engine VM インスタンスの詳細を把握しているメタデータ サーバーから取得されます。

これらの値をヘルパー スクリプトに手動で指定するには、-gcp-project-number オプションを使用します。-config-mesh-experimental オプションを使用して、メッシュ リソースと一致するメッシュ名を指定する必要があります。

  1. 構成を確認するには、クライアントにログインします。

    gcloud compute ssh grpc-client --zone=${ZONE}
    
  2. grpcurl ツールをダウンロードしてインストールします。

    curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.9.3/grpcurl_1.9.3_linux_x86_64.tar.gz | tar -xz
    
  3. grpcurl ツールを実行します。サービス URI として xds:///helloworld-gce、サービス名および呼び出すメソッドとして helloworld.Greeter/SayHello を指定します。

    ./grpcurl --plaintext \
      -d '{"name": "world"}' \
      xds:///helloworld-gce helloworld.Greeter/SayHello
    

    SayHello メソッドのパラメータは -d オプションを使用して渡されます。

    出力は次のようになります。ここで、INSTANCE_NAME は VM インスタンスの名前です。

    Greeting: Hello world, from INSTANCE_HOSTNAME
    

これにより、プロキシレス gRPC クライアントが Cloud Service Mesh に正常に接続され、xDS 名前リゾルバを使用して helloworld-gce サービスのバックエンドの詳細を把握したことを確認できます。クライアントは、IP アドレスの確認や DNS の解決を行うことなく、サービスのバックエンドの一つにリクエストを送信しました。

リージョン HTTPRoute とリージョン Mesh を使用して HTTP サービスで Envoy サイドカー プロキシ構成を構成する

このセクションでは、リージョン メッシュ リソースとリージョン HTTPRoute リソースを使用して Envoy プロキシベースのサービス メッシュを構成する方法について説明します。

操作を容易にするため、このガイドのすべての例をコマンドラインにコピーして貼り付けられるように、構成を行う Google Cloud プロジェクト番号を格納してください。

export PROJECT_ID="PROJECT_ID"
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"

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

  • PROJECT_ID: プロジェクト ID。
  • PROJECT_NUMBER: プロジェクト番号。

必要に応じて、次のように置き換えます。

  • us-central1 は、使用する別のリージョンに置き換えます。
  • us-central1-a は、使用する別のゾーンに置き換えます。

Mesh の構成

サイドカー Envoy プロキシは、Cloud Service Mesh からサービス ルーティング構成を受け取ります。サイドカーは、構成された特定のサービス メッシュを識別するために、リージョン メッシュ リソースの名前を提示します。Cloud Service Mesh から受け取ったルーティング構成は、Route リソースで構成されたリクエスト パラメータ(ホスト名やヘッダーなど)に応じて、サイドカー プロキシを通過するトラフィックを各リージョン バックエンド サービスに転送するために使用されます。

サイドカー プロキシがこのメッシュに関連付けられた構成をリクエストするために使用するキーは、メッシュ名です。

  1. リージョン メッシュ仕様を作成し、mesh.yaml ファイルに保存します。

    cat <<EOF > mesh.yaml
    name: sidecar-mesh
    EOF
    

    指定しない場合、インターセプト ポートはデフォルトの 15001 になります。

  2. mesh.yaml 仕様を使用してリージョン メッシュを作成します。

    gcloud network-services meshes import sidecar-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

    リージョン メッシュが作成されたら、Cloud Service Mesh が構成を提供する準備は完了です。ただし、サービスがまだ定義されていないため、構成は空になります。

HTTP サーバーの構成

デモ用に、自動スケーリングされた VM を含むリージョン バックエンド サービスを作成します(マネージド インスタンス グループ(MIG)を使用)。このサービスは、ポート 80 で gRPC プロトコルを使用して「hello world」を出力します。

  1. ポート 80 で公開されている helloworld HTTP サービスを使用して、Compute Engine VM インスタンス テンプレートを作成します。

    gcloud compute instance-templates create td-httpd-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=http-td-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script="#! /bin/bash
    
    sudo apt-get update -y
    sudo apt-get install apache2 -y
    sudo service apache2 restart
    echo '<!doctype html><html><body><h1>'\`/bin/hostname\`'</h1></body></html>' | sudo tee /var/www/html/index.html"
    
  2. テンプレートに基づいて MIG を作成します。

    gcloud compute instance-groups managed create http-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=td-httpd-vm-template
    
  3. ヘルスチェックを作成します。

    gcloud compute health-checks create http http-helloworld-health-check --region=${REGION}
    
  4. ネットワーク内のインスタンスへの受信ヘルスチェック接続を許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create http-vm-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \
      --target-tags http-td-server \
      --rules tcp:80
    
  5. ロード バランシング スキームが INTERNAL_SELF_MANAGED のリージョン バックエンド サービスを作成します。

    gcloud compute backend-services create http-helloworld-service \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=HTTP \
    --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/http-helloworld-health-check" \
        --region=${REGION}
    
  6. ヘルスチェックとマネージド インスタンス グループまたは非マネージド インスタンス グループをバックエンド サービスに追加します。

    gcloud compute backend-services add-backend http-helloworld-service \
      --instance-group=http-td-mig-us-central1 \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

    この例では、先ほど作成したサンプル HTTP サービスを実行する Compute Engine VM テンプレートで、マネージド インスタンス グループを使用します。

リージョン HTTPRoute を使用してルーティングを設定する

メッシュ リソースと HTTP サーバーの構成が完了しました。次に、ホスト名をバックエンド サービスに関連付ける HTTPRoute リソースを使用してこれらを接続できます。

  1. HTTPRoute 仕様を作成し、http_route.yaml として保存します。

    cat <<EOF > http_route.yaml
    name: helloworld-http-route
    hostnames:
    - helloworld-gce
    meshes:
    - projects/${PROJECT_NUMBER}/locations/${REGION}/meshes/sidecar-mesh
    rules:
    - action:
        destinations:
        - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/http-helloworld-service
    EOF
    
  2. http_route.yaml 仕様を使用して HTTPRoute を作成します。

    gcloud network-services http-routes import helloworld-http-route \
        --source=http_route.yaml \
        --location=${REGION}
    

    これで、HTTPRoute で指定されたサービスのトラフィックをマネージド インスタンス グループのバックエンド間でロード バランシングするように、Cloud Service Mesh が構成されました。

Envoy サイドカーを使用して HTTP クライアントを作成する

このセクションでは、Envoy サイドカー プロキシを使用してクライアント VM をインスタンス化し、先ほど作成した Cloud Service Mesh 構成をリクエストします。Google Cloud CLI コマンドの mesh パラメータは、先ほど作成したメッシュ リソースを参照します。

gcloud compute instance-templates create td-vm-template \
  --scopes=https://www.googleapis.com/auth/cloud-platform \
  --tags=http-td-tag,http-server,https-server \
  --image-family=debian-11 \
  --image-project=debian-cloud \
  --metadata=startup-script='#! /usr/bin/env bash

# Set variables
export ENVOY_CONTROL_PLANE_REGION="us-central1"
export ENVOY_USER="envoy"
export ENVOY_USER_UID="1337"
export ENVOY_USER_GID="1337"
export ENVOY_USER_HOME="/opt/envoy"
export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
export ENVOY_PORT="15001"
export ENVOY_ADMIN_PORT="15000"
export ENVOY_TRACING_ENABLED="false"
export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
export ENVOY_ACCESS_LOG="/dev/stdout"
export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
export GCE_METADATA_SERVER="169.254.169.254/32"
export INTERCEPTED_CIDRS="*"
export GCP_PROJECT_NUMBER=PROJECT_NUMBER
export VPC_NETWORK_NAME=mesh:sidecar-mesh
export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)

# Create system user account for Envoy binary
sudo groupadd ${ENVOY_USER} \
  --gid=${ENVOY_USER_GID} \
  --system
sudo adduser ${ENVOY_USER} \
  --uid=${ENVOY_USER_UID} \
  --gid=${ENVOY_USER_GID} \
  --home=${ENVOY_USER_HOME} \
  --disabled-login \
  --system
# Download and extract the Cloud Service Mesh tar.gz file
cd ${ENVOY_USER_HOME}
sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
  -C bootstrap_template.yaml \
  --strip-components 1
sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
  -C iptables.sh \
  --strip-components 1
sudo rm traffic-director-xdsv3.tar.gz

# Generate Envoy bootstrap configuration
cat "${BOOTSTRAP_TEMPLATE}" \
  | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
  | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
  | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
  | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
  | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
  | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
  | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
  | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
  | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
  | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
  | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
  | sudo tee "${ENVOY_CONFIG}"

# Install Envoy binary
wget -O envoy_key https://apt.envoyproxy.io/signing.key
cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
sudo apt-get update
sudo apt-get install envoy

# Run Envoy as systemd service
sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
  --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
  bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"

# Configure iptables for traffic interception and redirection
sudo ${ENVOY_USER_HOME}/iptables.sh \
  -p "${ENVOY_PORT}" \
 -u "${ENVOY_USER_UID}" \
  -g "${ENVOY_USER_GID}" \
  -m "REDIRECT" \
  -i "${INTERCEPTED_CIDRS}" \
  -x "${GCE_METADATA_SERVER}"
'

gcloud compute instances create td-vm-client \
  --zone=${ZONE} \
  --source-instance-template td-vm-template
  1. 作成した VM にログインします。

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  2. 作成したテストサービスへの HTTP 接続を確認します。

    curl -H "Host: helloworld-gce" http://10.0.0.1/
    

    このコマンドは、マネージド インスタンス グループ内の VM の一つからレスポンスを返し、そのホスト名をコンソールに出力します。

リージョン TCPRoute を使用して TCP サービスを構成する

この構成フローは、HTTP サービスを使用して Envoy プロキシを設定すると非常によく似ています。ただし、バックエンド サービスが TCP サービスを提供し、HTTP プロトコルではなく TCP/IP パラメータに基づくルーティングが使用される点が異なります。

操作を容易にするため、このガイドのすべての例をコマンドラインにコピーして貼り付けられるように、構成を行う Google Cloud プロジェクト番号を格納してください。

export PROJECT_ID="PROJECT_ID"
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"

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

  • PROJECT_ID: プロジェクト ID。
  • PROJECT_NUMBER: プロジェクト番号。

必要に応じて、次のように置き換えます。

  • us-central1 は、使用する別のリージョンに置き換えます。
  • us-central1-a は、使用する別のゾーンに置き換えます。

Mesh の構成

  1. リージョン メッシュ仕様を作成し、mesh.yaml ファイルに保存します。

    cat <<EOF > mesh.yaml
    name: sidecar-mesh
    EOF
    
  2. mesh.yaml 仕様を使用してリージョン メッシュを作成します。

    gcloud network-services meshes import sidecar-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

TCP サーバーの構成

デモ用に、自動スケーリングされた VM を含むリージョン バックエンド サービスを作成します(マネージド インスタンス グループ(MIG)を使用)。このサービスは、ポート 10000 で gRPC プロトコルを使用して「hello world」を出力します。

  1. netcat ユーティリティを使用して、ポート 10000 でテストサービスを使用して Compute Engine VM インスタンス テンプレートを作成します。

    gcloud compute instance-templates create tcp-td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script="#! /bin/bash
    sudo apt-get update -y
    sudo apt-get install netcat -y
    while true;
      do echo 'Hello from TCP service' | nc -l -s 0.0.0.0 -p 10000;
    done &"
    
  2. テンプレートに基づいて MIG を作成します。

    gcloud compute instance-groups managed create tcp-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=1 \
      --template=tcp-td-vm-template
    
  3. 作成したマネージド インスタンス グループの名前付きポートを port 10000 に設定します。

    gcloud compute instance-groups set-named-ports tcp-td-mig-us-central1 \
      --zone=${ZONE} --named-ports=tcp:10000
    
  4. リージョン ヘルスチェックを作成します。

    gcloud compute health-checks create tcp tcp-helloworld-health-check --port 10000 --region=${REGION}
    
  5. ネットワーク内のインスタンスへの受信ヘルスチェック接続を許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create tcp-vm-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \
      --target-tags allow-health-checks \
      --rules tcp:10000
    
  6. ロード バランシング スキームが INTERNAL_SELF_MANAGED のリージョン バックエンド サービスを作成し、ヘルスチェックとマネージド インスタンス グループまたは非マネージド インスタンス グループをバックエンド サービスに追加します。

    gcloud compute backend-services create tcp-helloworld-service \
        --region=${REGION} \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=TCP \
        --port-name=tcp \
        --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/tcp-helloworld-health-check"
    
  7. MIG を BackendService に追加します。

    gcloud compute backend-services add-backend tcp-helloworld-service \
      --instance-group tcp-td-mig-us-central1 \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

リージョン TCPRoute を使用してルーティングを設定する

  1. TCPRoute 仕様を作成し、tcp_route.yaml ファイルに保存します。

    cat <<EOF > tcp_route.yaml
    name: helloworld-tcp-route
    meshes:
    - projects/$PROJECT_NUMBER/locations/$REGION/meshes/sidecar-mesh
    rules:
    - action:
        destinations:
        - serviceName: projects/$PROJECT_NUMBER/locations/$REGION/backendServices/tcp-helloworld-service
      matches:
      - address: '10.0.0.1/32'
        port: '10000'
    EOF
    
  2. tcp_route.yaml 仕様を使用して TCPRoute を作成します。

    gcloud network-services tcp-routes import helloworld-tcp-route \
        --source=tcp_route.yaml \
        --location=${REGION}
    

Envoy サイドカーを使用して TCP クライアントを作成する

  1. Cloud Service Mesh に接続された Envoy を使用して VM を作成します。

    gcloud compute instance-templates create td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=http-td-tag,http-server,https-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script='#! /usr/bin/env bash
    
    # Set variables
    export ENVOY_CONTROL_PLANE_REGION="us-central1"
    export ENVOY_USER="envoy"
    export ENVOY_USER_UID="1337"
    export ENVOY_USER_GID="1337"
    export ENVOY_USER_HOME="/opt/envoy"
    export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
    export ENVOY_PORT="15001"
    export ENVOY_ADMIN_PORT="15000"
    export ENVOY_TRACING_ENABLED="false"
    export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
    export ENVOY_ACCESS_LOG="/dev/stdout"
    export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
    export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
    export GCE_METADATA_SERVER="169.254.169.254/32"
    export INTERCEPTED_CIDRS="*"
    export GCP_PROJECT_NUMBER=PROJECT_NUMBER
    export VPC_NETWORK_NAME=mesh:sidecar-mesh
    
    export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
    
    # Create system user account for Envoy binary
    sudo groupadd ${ENVOY_USER} \
      --gid=${ENVOY_USER_GID} \
      --system
    sudo adduser ${ENVOY_USER} \
      --uid=${ENVOY_USER_UID} \
      --gid=${ENVOY_USER_GID} \
      --home=${ENVOY_USER_HOME} \
      --disabled-login \
      --system
    # Download and extract the Cloud Service Mesh tar.gz file
    cd ${ENVOY_USER_HOME}
    sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
      -C bootstrap_template.yaml \
      --strip-components 1
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
      -C iptables.sh \
      --strip-components 1
    sudo rm traffic-director-xdsv3.tar.gz
    
    # Generate Envoy bootstrap configuration
    cat "${BOOTSTRAP_TEMPLATE}" \
      | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
      | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
      | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
      | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
      | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
      | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
      | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
      | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
      | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
      | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
      | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
      | sudo tee "${ENVOY_CONFIG}"
    
    # Install Envoy binary
    wget -O envoy_key https://apt.envoyproxy.io/signing.key
    cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
    sudo apt-get update
    sudo apt-get install envoy
    
    # Run Envoy as systemd service
    sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
      --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
      bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
    
    # Configure iptables for traffic interception and redirection
    sudo ${ENVOY_USER_HOME}/iptables.sh \
      -p "${ENVOY_PORT}" \
    -u "${ENVOY_USER_UID}" \
      -g "${ENVOY_USER_GID}" \
      -m "REDIRECT" \
      -i "${INTERCEPTED_CIDRS}" \
      -x "${GCE_METADATA_SERVER}"
    '
    
    gcloud compute instances create td-vm-client \
      --zone=${ZONE} \
      --source-instance-template td-vm-template
    
  2. 作成した VM にログインします。

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  3. 作成したテストサービスへの接続を確認します。

    curl 10.0.0.1:10000 --http0.9 -v
    

    テキスト Hello from TCP service が返され、リモート VM で実行されている netcat サービスにより、入力したテキストが返されます。

ホスト プロジェクトのリージョン メッシュの構成

プロジェクトをホスト プロジェクトとして指定します。このプロジェクトでメッシュを作成、更新、削除する権限を持つサービス アカウントは、このプロジェクトのリージョン メッシュに接続されているルーティング構成を制御できます。

  1. この例全体で使用する変数を定義します。

    export REGION="us-central1"
    

    必要に応じて、us-central1 は、使用する別のリージョンに置き換えます。

  2. メッシュ仕様を作成し、mesh.yaml ファイルに保存します。

    cat <<EOF > mesh.yaml
    name: shared-mesh
    EOF
    
  3. このプロジェクトで、必要な構成を使用してメッシュ リソースを定義します。

    gcloud network-services meshes import shared-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

    このメッシュ リソースの完全な URI をメモします。サービス オーナーは、今後このメッシュにルートを接続する場合に、この ID が必要になります。

  4. このメッシュと、このメッシュにサービス情報を接続できるようにする必要があるクロス プロジェクト サービス アカウントに networkservices.meshes.use IAM 権限を付与します。

    gcloud projects add-iam-policy-binding HOST_PROJECT_NUMBER --member='HTTP_ROUTE_SERVICE_OWNER_ACCOUNT' --role='roles/compute.networkAdmin'
    

    これで、networkservices.meshes.use 権限が付与されたすべてのサービス オーナーは、このメッシュにルーティング ルールを追加できます。

サービス プロジェクトの Route の構成

HTTP サービスを使用して Envoy プロキシを設定すると同様に、各サービス オーナーは、プロジェクトにリージョン Backend Service リソースとリージョン Route リソースを作成する必要があります。ただし、各 HTTPRoute、GRPCRoute、TCPRoute の meshes フィールドに、ホスト プロジェクトのメッシュ リソースの URI を指定する点のみが異なります。

  1. sharedvpc-http-route を作成します。

    echo "name: sharedvpc-http-route
    hostnames:
    - helloworld-gce
    meshes:
    - /projects/HOST_PROJECT_NUMBER/locations/${REGION}/meshes/shared-mesh
    rules:
    - action:
        destinations:
        - serviceName: \"SERVICE_URL\"" | \
    gcloud network-services http-routes import sharedvpc-http-route \
        --source=- \
        --location=${REGION}
    

サービス プロジェクトでクライアント サービスを構成する

サービス プロジェクトに配置されている Cloud Service Mesh クライアント(Envoy プロキシまたはプロキシレス)を構成する際には、ブートストラップ構成でメッシュ リソースが配置されているプロジェクトの番号とメッシュ名を指定する必要があります。

TRAFFICDIRECTOR_GCP_PROJECT_NUMBER=HOST_PROJECT_NUMBER
TRAFFICDIRECTOR_MESH_NAME=MESH_NAME

ゲートウェイ TLS ルーティング

このセクションでは、リージョン Gateway リソースとリージョン TLSRoute リソースを使用して Envoy プロキシベースの Ingress ゲートウェイを設定する方法について説明します。

リージョン外部パススルー ネットワーク ロードバランサは、Ingress ゲートウェイとして機能する Envoy プロキシにトラフィックを転送します。Envoy プロキシは、TLS パススルー ルーティングを使用し、バックエンド VM インスタンスで実行されている HTTPS サーバーにトラフィックを転送します。

この例全体で使用する複数の変数を定義します。

export PROJECT_ID="PROJECT_ID"
export PROJECT_NUMBER="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-b"
export NETWORK_NAME = "default"

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

  • PROJECT_ID: プロジェクト ID。
  • PROJECT_NUMBER: プロジェクト番号。

必要に応じて、次のように置き換えます。

  • us-central1 は、使用する別のリージョンに置き換えます。
  • us-central1-b は、使用する別のゾーンに置き換えます。
  • default は、使用する別のネットワーク名に置き換えます。

マルチプロジェクトの共有 VPC 環境でリージョン メッシュ リソースとリージョン ルートリソースを相互参照させる

サービス メッシュ構成が、異なるプロジェクトが所有するサービスで構成されている場合があります。たとえば、共有 VPC デプロイメントやピアリングされた VPC デプロイメントでは、各プロジェクト オーナーが独自のサービスセットを定義して、これらのサービスを他のすべてのプロジェクトで利用できるようにすることができます。

この構成は「クロス プロジェクト」と呼ばれます。異なるプロジェクトで定義された複数のリソースを組み合わせて単一の構成を形成し、プロキシ クライアントまたはプロキシレス クライアントに提供できるためです。

ファイアウォール ルールを構成する

  1. 任意のソースからのトラフィックを許可するようにファイアウォール ルールを構成します。コマンドを編集して、使用するポートと送信元 IP アドレス範囲を設定します。

    gcloud compute firewall-rules create allow-gateway-health-checks \
    --network=${NETWORK_NAME} \
    --direction=INGRESS \
    --action=ALLOW \
    --rules=tcp \
    --source-ranges="35.191.0.0/16,209.85.152.0/22,209.85.204.0/22" \
    --target-tags=gateway-proxy
    

IAM 権限を構成する

  1. ゲートウェイ プロキシのサービス アカウント ID を作成します。

    gcloud iam service-accounts create gateway-proxy
    
  2. サービス アカウント ID に必要な IAM ロールを割り当てます。

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="serviceAccount:gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \
      --role="roles/trafficdirector.client"
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="serviceAccount:gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

リージョン Gateway を構成する

  1. gateway8443.yaml という名前のファイルで、HTTP トラフィックの Gateway 仕様を作成します。

    cat <<EOF > gateway8443.yaml
    name: gateway8443
    scope: gateway-proxy-8443
    ports:
    - 8443
    type: OPEN_MESH
    EOF
    
  2. gateway8443.yaml 仕様を使用して、リージョン Gateway リソースを作成します。

    gcloud network-services gateways import gateway8443 \
        --source=gateway8443.yaml \
        --location=${REGION}
    

Envoy プロキシを使用してマネージド インスタンス グループを作成する

このセクションでは、自動的にデプロイされた Envoy サービス プロキシを実行する VM のインスタンス テンプレートを作成します。Envoy のスコープは gateway-proxy に設定されています。サービスポートを --service-proxy フラグのパラメータとして渡さないでください。

  1. Envoy プロキシを使用してマネージド インスタンス グループを作成します。

    gcloud beta compute instance-templates create gateway-proxy \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=gateway-proxy,http-td-tag,http-server,https-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --network-interface=network=${NETWORK_NAME} \
      --service-account="gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \
      --metadata=startup-script='#! /usr/bin/env bash
    
    # Set variables
    export ENVOY_CONTROL_PLANE_REGION="us-central1"
    export GCP_PROJECT_NUMBER=PROJECT_NUMBER
    export VPC_NETWORK_NAME=scope:gateway-proxy-8443
    export ENVOY_USER="envoy"
    export ENVOY_USER_UID="1337"
    export ENVOY_USER_GID="1337"
    export ENVOY_USER_HOME="/opt/envoy"
    export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
    export ENVOY_PORT="15001"
    export ENVOY_ADMIN_PORT="15000"
    export ENVOY_TRACING_ENABLED="false"
    export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
    export ENVOY_ACCESS_LOG="/dev/stdout"
    export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
    export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
    export GCE_METADATA_SERVER="169.254.169.254/32"
    export INTERCEPTED_CIDRS="*"
    
    export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
    
    # Create system user account for Envoy binary
    sudo groupadd ${ENVOY_USER} \
      --gid=${ENVOY_USER_GID} \
      --system
    sudo adduser ${ENVOY_USER} \
      --uid=${ENVOY_USER_UID} \
      --gid=${ENVOY_USER_GID} \
      --home=${ENVOY_USER_HOME} \
      --disabled-login \
      --system
    # Download and extract the Cloud Service Mesh tar.gz file
    cd ${ENVOY_USER_HOME}
    sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
      -C bootstrap_template.yaml \
      --strip-components 1
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
      -C iptables.sh \
      --strip-components 1
    sudo rm traffic-director-xdsv3.tar.gz
    
    # Generate Envoy bootstrap configuration
    cat "${BOOTSTRAP_TEMPLATE}" \
      | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
      | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
      | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
      | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
      | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
      | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
      | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
      | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
      | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
      | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
      | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
      | sudo tee "${ENVOY_CONFIG}"
    
    # Install Envoy binary
    wget -O envoy_key https://apt.envoyproxy.io/signing.key
    cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
    sudo apt-get update
    sudo apt-get install envoy
    
    # Run Envoy as systemd service
    sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
      --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
      bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
    
    # Configure iptables for traffic interception and redirection
    sudo ${ENVOY_USER_HOME}/iptables.sh \
      -p "${ENVOY_PORT}" \
    -u "${ENVOY_USER_UID}" \
      -g "${ENVOY_USER_GID}" \
      -m "REDIRECT" \
      -i "${INTERCEPTED_CIDRS}" \
      -x "${GCE_METADATA_SERVER}"
    '
    
  2. インスタンス テンプレートからリージョン マネージド インスタンス グループを作成します。

    gcloud compute instance-groups managed create gateway-proxy \
      --region=${REGION} \
      --size=1 \
      --template=gateway-proxy
    
  3. マネージド インスタンス グループのサービスポート名を設定します。

    gcloud compute instance-groups managed set-named-ports gateway-proxy \
      --named-ports=https:8443 \
      --region=${REGION}
    

リージョン外部パススルー ネットワーク ロードバランサを設定する

  1. 静的外部リージョン IP アドレスを作成します。

    gcloud compute addresses create xnlb-${REGION} \
      --region=${REGION}
    
  2. 外部ロードバランサ用に予約されている IP アドレスを取得します。

    gcloud compute addresses describe xnlb-${REGION} \
      --region=${REGION} --format='value(address)'
    
  3. ゲートウェイ プロキシのヘルスチェックを作成します。

    gcloud compute health-checks create tcp xnlb-${REGION} \
      --region=${REGION} \
      --use-serving-port
    
  4. ゲートウェイ プロキシのバックエンド サービスを作成します。

    gcloud compute backend-services create xnlb-${REGION} \
      --health-checks=xnlb-${REGION} \
      --health-checks-region=${REGION} \
      --load-balancing-scheme=EXTERNAL \
      --protocol=TCP \
      --region=${REGION} \
      --port-name=https
    
  5. バックエンドとしてマネージド インスタンス グループを追加します。

    gcloud compute backend-services add-backend xnlb-${REGION} \
      --instance-group=gateway-proxy \
      --instance-group-region=${REGION} \
      --region=${REGION}
    
  6. ゲートウェイ プロキシにトラフィックをルーティングする転送ルールを作成します。

    gcloud compute forwarding-rules create xnlb-${REGION} \
      --region=${REGION} \
      --load-balancing-scheme=EXTERNAL \
      --address=${IP_ADDRESS} \
      --ip-protocol=TCP \
      --ports=8443 \
      --backend-service=xnlb-${REGION} \
      --backend-service-region=${REGION}
    

HTTPS サービスを実行するマネージド インスタンス グループを構成する

  1. ポート 8443 で公開されている HTTPS サービスを使用して、インスタンス テンプレートを作成します。

    gcloud compute instance-templates create td-https-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=https-td-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script='#! /bin/bash
    
    sudo rm -rf /var/lib/apt/lists/*
    sudo apt-get -y clean
    sudo apt-get -y update
    sudo apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
    sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
    sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
    sudo apt-get -y update
    sudo apt-get -y install docker-ce
    sudo which docker
    echo "{ \"registry-mirrors\": [\"https://mirror.gcr.io\"] }" | sudo tee -a /etc/docker/daemon.json
    sudo service docker restart
    sudo docker run -e HTTPS_PORT=9999 -p 8443:9999 --rm -dt mendhak/http-https-echo:22'
    
  2. インスタンス テンプレートに基づいてマネージド インスタンス グループを作成します。

    gcloud compute instance-groups managed create https-td-mig-us-${REGION} \
      --zone=${ZONE} \
      --size=2 \
      --template=td-https-vm-template
    
  3. マネージド インスタンス グループのサービスポート名を設定します。

    gcloud compute instance-groups managed set-named-ports https-td-mig-us-${REGION} \
      --named-ports=https:8443 \
      --zone=${ZONE}
    
  4. ヘルスチェックを作成します。

    gcloud compute health-checks create https https-helloworld-health-check \
      --port=8443 --region=${REGION}
    
  5. ネットワーク内のインスタンスへの受信ヘルスチェック接続を許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create https-vm-allow-health-checks \
      --network ${NETWORK_NAME} --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --target-tags https-td-server \
      --rules tcp:8443
    
  6. ロード バランシング スキームが INTERNAL_SELF_MANAGED のリージョン バックエンド サービスを作成し、ヘルスチェックを追加します。

    gcloud compute backend-services create https-helloworld-service \
      --region=${REGION} \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --port-name=https \
      --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/https-helloworld-health-check"
    
  7. マネージド インスタンス グループをバックエンドとしてバックエンド サービスに追加します。

    gcloud compute backend-services add-backend https-helloworld-service \
      --instance-group=https-td-mig-us-${REGION} \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

TLSRoute リソースを使用してルーティングを設定する

  1. tls_route.yaml という名前のファイルで、TLSRoute 仕様を作成します。

    cat <<EOF > tls_route.yaml
    name: helloworld-tls-route
    gateways:
    - projects/${PROJECT_NUMBER}/locations/${REGION}/gateways/gateway8443
    rules:
    - matches:
      - sniHost:
        - example.com
        alpn:
        - h2
      action:
        destinations:
        - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/https-helloworld-service
    EOF
    

    前の手順では、TLSRoute は SNI として example.com、ALPN として h2 を照合します。この照合が次のように変更された場合、TLSRoute は SNI または ALPN のいずれかを照合します。

    - matches:
      - sniHost:
        - example.com
      - alpn:
        - h2
    
  2. tls_route.yaml 仕様を使用して TLSRoute リソースを作成します。

    gcloud network-services tls-routes import helloworld-tls-route \
        --source=tls_route.yaml \
        --location=${REGION}
    

デプロイメントを検証する

  1. 次の curl コマンドを実行して、作成したテストサービスへの HTTP 接続を確認します。

    curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k
    
  2. このコマンドは、マネージド インスタンス グループ内の VM の一つからレスポンスを返します。出力は次のようになります。

    {
      "path": "/",
      "headers": {
        "host": "example.com:8443",
        "user-agent": "curl/8.16.0",
        "accept": "*/*"
      },
      "method": "GET",
      "body": "",
      "fresh": false,
      "hostname": "example.com",
      "ip": "::ffff:10.128.0.59",
      "ips": [],
      "protocol": "https",
      "query": {},
      "subdomains": [],
      "xhr": false,
      "os": {
        "hostname": "19cd7812e792"
      },
      "connection": {
        "servername": "example.com"
      }
    

否定的検証で確認する

  1. 次のコマンドでは、SNI が example.com に一致しないため、Gateway は接続を拒否します。

    curl https://invalid-server.com:8443 --resolve invalid-server.com:8443:${IP_ADDRESS} -k
    
  2. 次のコマンドでは、ALPN が h2(HTTP2 プロトコル)に一致しないため、Gateway は接続を拒否します。

    curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k --http1.1
    

    上記のコマンドはすべて次のエラーを返します。

    curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection.
    
  3. 次のコマンドでは、クライアントが書式なしテキスト(暗号化なし)の接続を作成しているため、Gateway は 404 Not Found エラーを返して接続を拒否します。

    curl example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k