ゲートウェイ TLS ルーティングを設定する

このガイドでは、Gateway リソースと TLSRoute リソースを使用して Envoy プロキシベースの Ingress ゲートウェイを設定する方法について説明します。TLSRoute リソースを Mesh リソースに接続して、サイドカー プロキシで TLS パススルー ルーティングを設定することもできます。

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

Ingress ゲートウェイでの TLS パススルー
Ingress ゲートウェイでの TLS パススルー(クリックして拡大)

始める前に

デプロイが、次のガイドに記載されている前提条件を満たしていることを確認します。

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

このセクションでは、ネットワーク内の VM インスタンスへのヘルスチェック接続の受信を許可するファイアウォール ルールを作成します。

  1. ファイアウォール ルールを作成します。

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

    gcloud compute firewall-rules create allow-gateway-ingress-traffic \
      --network=NETWORK_NAME \
      --direction=INGRESS \
      --action=ALLOW \
      --rules=tcp:443 \
      --source-ranges="0.0.0.0/0" \
      --target-tags=gateway-proxy
    

Identity and Access Management の権限を構成する

このセクションでは、ゲートウェイ プロキシのサービス アカウントを指定し、そのサービス アカウントに正しい 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. gateway443.yaml という名前のファイルで、HTTP トラフィックの Gateway 仕様を作成します。

    name: gateway443
    scope: gateway-proxy
    ports:
    - 443
    type: OPEN_MESH
    
  2. gateway443.yaml 仕様を使用して Gateway リソースを作成します。

    gcloud network-services gateways import gateway443 \
        --source=gateway443.yaml \
        --location=global
    

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

このセクションでは、Ingress ゲートウェイに関連付けられた Envoy プロキシを作成します。

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

    gcloud beta compute instance-templates create gateway-proxy \
      --machine-type=n1-standard-1 \
      --boot-disk-size=10GB \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=gateway-proxy \
      --network-interface=network=NETWORK_NAME,no-address \
      --service-account="gateway-proxy@PROJECT_ID.iam.gserviceaccount.com" \
      --service-proxy=enabled,scope=gateway-proxy
    
  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:443 \
      --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)'
    

    この IP アドレスは、この設定ガイドの後半で変数 IP_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=443 \
      --backend-service=xnlb-REGION \
      --backend-service-region=REGION
    

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

デモ用に、自動スケーリングされた VM を使用するバックエンド サービスをマネージド インスタンス グループに作成します。VM は、ポート 443 で HTTPS プロトコルを使用して、ウェブ リクエストの詳細をエコーします。

  1. ポート 443 で公開する 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-10 \
      --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 443: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:443 \
      --zone=ZONE
    
  4. ヘルスチェックを作成します。

    gcloud compute health-checks create https https-helloworld-health-check \
      --port=443
    
  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:443
    
  6. INTERNAL_SELF_MANAGED のロード バランシング方式でグローバル バックエンド サービスを作成し、ヘルスチェックを追加します。

    gcloud compute backend-services create https-helloworld-service \
      --global \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --port-name=https \
      --health-checks 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 \
      --global
    

TLSRoute リソースでルーティングを設定する

前のセクションでは、Gateway リソースと HTTPS サーバーを構成しました。次に、SNI ホスト名をバックエンド サービスに関連付ける TLSRoute リソースを使用して接続します。

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

    name: helloworld-tls-route
    gateways:
    - projects/PROJECT_NUMBER/locations/global/gateways/gateway443
    rules:
    - matches:
      - sniHost:
        - example.com
        alpn:
        - h2
      action:
       destinations:
       - serviceName: projects/PROJECT_NUMBER/locations/global/backendServices/https-helloworld-service
    

    前の手順では、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=global
    

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

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

このセクションでは、外部パススルー ネットワーク ロードバランサと Traffic Director Gateway リソースを介して、外部クライアントからサービスにアクセスできることを確認します。

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

    curl https://example.com --resolve example.com:443:IP_ADDRESS -k
    

このコマンドは、マネージド インスタンス グループ内のいずれかの VM からレスポンスを返します。次のような出力が表示されます。

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

否定的検証で確認する

否定的検証も行うことができます。このセクションのコマンドを実行すると、リクエストは TLSRoute 一致基準と一致しないため、ドロップされます。

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

curl https://invalid-server.com --resolve invalid-server.com:443:IP_ADDRESS -k

次のコマンドでは、ALPN が h2(HTTP2 プロトコル)と一致しないため、Gateway が接続を拒否します。

curl https://example.com --resolve example.com:443:IP_ADDRESS -k --http1.1

次のコマンドでは、クライアントは書式なしテキスト(暗号化なし)の接続を作成しているので、Gateway は接続を拒否します。

curl example.com:443 --resolve example.com:443:IP_ADDRESS -k

これらのコマンドはすべて次のエラーを返します。

curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection.