手動 Envoy インジェクションを使用して Google Kubernetes Engine の Pod を設定する

このガイドでは、Google Kubernetes Engine または Kubernetes Pod ホストと、Cloud Service Mesh に必要なロード バランシング コンポーネントを構成する方法について説明します。

このガイドの手順に進む前に、Envoy とプロキシレス ワークロードを使用したサービス ルーティング API の設定の準備で説明されている前提条件のタスクを完了します。

Cloud Service Mesh は、Compute Engine ロード バランシング SDK または REST API を使用して構成できます。負荷分散 API と gcloud のリファレンスをご覧ください。

Cloud Service Mesh 用の GKE/Kubernetes クラスタの構成

このセクションでは、GKE / Kubernetes クラスタで Cloud Service Mesh を使用できるようにする手順について説明します。

GKE クラスタの作成

GKE クラスタは次の要件を満たす必要があります。

次の例は、us-central1-a ゾーンに traffic-director-cluster という GKE クラスタを作成する方法を示しています。

Console

Google Cloud コンソールを使用してクラスタを作成するには、次の手順を行います。

  1. Google Cloud コンソールで Google Kubernetes Engine のメニューに移動します。

    Google Kubernetes Engine のメニューに移動

  2. [クラスタを作成] をクリックします。

  3. 次のフィールドに値を入力します。

    • 名前:traffic-director-cluster」と入力します。
    • ロケーション タイプ: Zonal
    • ゾーン: us-central1-a
  4. ナビゲーション ペインの [ノードプール] で [default-pool] をクリックします。

  5. [サイズ] フィールドは、クラスタ内に作成するノードの数を示します。ノードとそのリソース(ファイアウォール ルートなど)に使用できるリソース割り当てが必要です。

  6. ナビゲーション パネルの [default-pool] の下の [ノード] をクリックします。

  7. [マシンタイプ] フィールドは、インスタンスに使用する Compute Engine のマシンタイプを示します。マシンタイプごとに課金方法は異なります。マシンタイプごとの料金については、Compute Engine の料金のページをご覧ください。

  8. ナビゲーション パネルの [default-pool] で [セキュリティ] をクリックします。

  9. [アクセス スコープ] で、[すべての Cloud API に完全アクセス権を許可] をクリックします。

  10. 必要に応じてクラスタをカスタマイズします。

  11. [作成] をクリックします。

Google Cloud コンソールでクラスタを作成したら、クラスタとやり取りするように kubectl を構成する必要があります。詳細については、kubeconfig エントリの生成をご覧ください。

gcloud

gcloud container clusters create traffic-director-cluster \
  --zone us-central1-a \
  --scopes=https://www.googleapis.com/auth/cloud-platform \
  --enable-ip-alias

必要な GKE クラスタ権限の取得

GKE の場合は、次のコマンドを実行して、作成したクラスタ(2)に切り替えます。これにより、kubectl は正しいクラスタを指すようになります。

gcloud container clusters get-credentials traffic-director-cluster \
    --zone us-central1-a

GKE / Kubernetes Service の構成

このセクションでは、Cloud Service Mesh と連携するための Kubernetes Deployment 仕様の準備方法について説明します。これは、NEG を使用したサービスの構成と、Cloud Service Mesh によって管理されるサービスへのアクセスを必要とする Pod へのサイドカー プロキシの挿入で構成されます。

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

バックエンド Pod が実行されていることを確認するには、ヘルスチェッカーの IP アドレス範囲を許可するファイアウォール ルールを構成する必要があります。

コンソール

  1. Google Cloud コンソールの [ファイアウォール ポリシー] ページに移動します。
    [ファイアウォール ポリシー] ページに移動
  2. [ファイアウォール ルールを作成] をクリックします。
  3. ファイアウォール ルールの作成ページで、次の情報を入力します。
    • 名前: ルールの名前を指定します。この例では、fw-allow-health-checks を使用します。
    • ネットワーク: VPC ネットワークを選択します。
    • 優先度: 優先度の数値を入力します。数字が小さいほど優先度が高くなります。このファイアウォール ルールには、上りトラフィックを拒否する可能性があるその他のルールよりも高い優先度を設定してください。
    • トラフィックの方向: [内向き(上り)] を選択します。
    • 一致したときのアクション: [許可] を選択します。
    • ターゲット: [ネットワーク内のすべてのインスタンス] を選択します。
    • ソースフィルタ: 正しい IP 範囲タイプを選択します。
    • ソース IP の範囲: 35.191.0.0/16,130.211.0.0/22
    • 送信先フィルタ: IP のタイプを選択します。
    • プロトコルとポート: [指定したプロトコルとポート] をクリックして、tcp のチェックボックスをオンにします。TCP は、すべてのヘルスチェック プロトコルの基礎となるプロトコルです。
    • [作成] をクリックします。

gcloud

  1. 次の gcloud コマンドを使用して、fw-allow-health-checks という名前のファイアウォール ルールを作成します。このルールは allow-health-checks タグを持つネットワーク内のインスタンスに対する受信接続を許可します。NETWORK_NAME はネットワーク名に置き換えてください。

    gcloud compute firewall-rules create fw-allow-health-checks \
        --network NETWORK_NAME \
        --action ALLOW \
        --direction INGRESS \
        --source-ranges 35.191.0.0/16,130.211.0.0/22 \
        --rules tcp

詳細については、ヘルスチェックのファイアウォール ルールの構成をご覧ください。

NEG を使用した GKE / Kubernetes Services の構成

GKE サービスは、Cloud Service Mesh バックエンド サービスのバックエンドとして構成できるように、ネットワーク エンドポイント グループ(NEG)で公開されている必要があります。Kubernetes サービス仕様に NEG アノテーションを追加し、後で簡単に見つけられるように名前を選択します(以下のサンプルで NEG-NAME と置き換えます)。この名前は、NEG を Cloud Service Mesh バックエンド サービスに接続するときに必要となります。NEG のアノテーションの詳細については、NEG に名前を付けるをご覧ください。

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG-NAME"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

各サービスに対して、Pod の IP アドレスとポートであるエンドポイントを含むスタンドアロンの NEG が作成されます。詳細と例については、スタンドアロンのネットワーク エンドポイント グループをご覧ください。

デモ目的で、HTTP を介してポート 80 でホスト名を提供するサンプル サービスをデプロイできます。

wget -q -O - \
https://storage.googleapis.com/traffic-director/demo/trafficdirector_service_sample.yaml \
| kubectl apply -f -

新しいサービスホスト名が作成され、アプリケーション Pod が実行されていることを確認します。

kubectl get svc

次の結果が返されます。

NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service-test     ClusterIP   10.71.9.71   none          80/TCP    41m
[..skip..]

kubectl get pods

次の結果が返されます。

NAME                        READY     STATUS    RESTARTS   AGE
app1-6db459dcb9-zvfg2       1/1       Running   0          6m
[..skip..]

NEG の名前を保存する

上記の例で作成された NEG を見つけて、NEG の名前を記録します。

Console

ネットワーク エンドポイント グループのリストを表示するには、Google Cloud Console の [ネットワーク エンドポイント グループ] ページに移動します。
[ネットワーク エンドポイント グループ] ページに移動

gcloud

gcloud compute network-endpoint-groups list

これにより、次の結果が返されます。

NAME                 LOCATION          ENDPOINT_TYPE      SIZE
NEG-NAME           us-central1-a     GCE_VM_IP_PORT      1

NEG の名前を NEG_NAME 変数に保存します。次に例を示します。

NEG_NAME=$(gcloud compute network-endpoint-groups list \
| grep service-test | awk '{print $1}')

Cloud Service Mesh 用の Google Cloud 負荷分散コンポーネントの構成

このセクションの手順では、他の Google Cloud Load Balancing プロダクトと同様の負荷分散構成を使用して、Cloud Service Mesh が負荷分散を行っているサービス VIP の GKE サービスにアクセスできるようにします。

以下のコンポーネントを構成する必要があります。

次の Cloud Service Mesh 構成例では、次のことを前提としています。

  1. NEG と他のすべてのリソースは、ゾーン us-central1-a 内の default ネットワークに自動モードで作成されます。
  2. クラスタの NEG 名は ${NEG_NAME} 変数に格納されます。

ヘルスチェックの作成

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

コンソール

  1. Google Cloud コンソールの [ヘルスチェック] ページに移動します。
    [ヘルスチェック] ページに移動
  2. [ヘルスチェックを作成] をクリックします。
  3. [名前] に「td-gke-health-check」と入力します。
  4. プロトコルとして [HTTP] を選択します。
  5. [作成] をクリックします。

gcloud

gcloud compute health-checks create http td-gke-health-check \
  --use-serving-port

バックエンド サービスの作成

INTERNAL_SELF_MANAGED のロード バランシング方式でグローバル バックエンド サービスを作成します。Google Cloud コンソールでは、ロード バランシング方式は暗黙的に設定されます。ヘルスチェックをバックエンド サービスに追加します。

コンソール

  1. Google Cloud コンソールで [Cloud Service Mesh] ページに移動します。

    [Cloud Service Mesh] ページに移動

  2. [サービス] タブで、[サービスを作成] をクリックします。

  3. [続行] をクリックします。

  4. サービス名に「td-gke-service」と入力します。

  5. [バックエンド タイプ] で [ネットワーク エンドポイント グループ] を選択します。

  6. 作成したネットワーク エンドポイント グループを選択します。

  7. [最大 RPS] を 5 に設定します。

  8. [完了] をクリックします。

  9. [ヘルスチェック] で、作成したヘルスチェック(td-gke-health-check)を選択します。

  10. [続行] をクリックします。

gcloud

  1. バックエンド サービスを作成し、バックエンド サービスにヘルスチェックを関連付けます。

    gcloud compute backend-services create td-gke-service \
     --global \
     --health-checks td-gke-health-check \
     --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  2. バックエンド サービスにバックエンド NEG を追加します。

    gcloud compute backend-services add-backend td-gke-service \
     --global \
     --network-endpoint-group ${NEG_NAME} \
     --network-endpoint-group-zone us-central1-a \
     --balancing-mode RATE \
     --max-rate-per-endpoint 5
    

ルーティング ルール マップの作成

以下の手順で Cloud Service Mesh 構成にルートルール、転送ルール、内部 IP アドレスを作成します。

内部 IP アドレスに送信されたトラフィックは、Envoy プロキシによってインターセプトされ、ホストとパスのルールに従って適切なサービスに送信されます。

転送ルールは、load-balancing-schemeINTERNAL_SELF_MANAGED に設定されたグローバル転送ルールとして作成されます。

転送ルールのアドレスを 0.0.0.0 に設定できます。このように設定すると、トラフィックは、ホスト名が解決される実際の IP アドレスに関係なく、URL マップで構成された HTTP ホスト名とパス情報に基づいてルーティングされます。この場合、ホストルールで構成されたサービスの URL(ホスト名と URL パス)は、サービス メッシュ構成内で一意である必要があります。つまり、バックエンドのセットが異なる二つのサービスを、両方とも同じホスト名とパスの組み合わせで使用することはできません。

また、サービスの実際の宛先 VIP に基づいてルーティングを有効にすることもできます。サービスの VIP を転送ルールの address パラメータとして構成した場合、その IP アドレスを宛先とするリクエストのみが、URL マップに指定された HTTP パラメータに基づいてルーティングされます。

コンソール

Console では、ターゲット プロキシは転送ルールと組み合わされます。転送ルールを作成すると、Google Cloud によってターゲット HTTP プロキシが自動的に作成され、URL マップに接続されます。

ルートルールは、転送ルールおよびホストとパスのルール(URL マップ)で構成されます。

  1. Google Cloud コンソールで [Cloud Service Mesh] ページに移動します。

    [Cloud Service Mesh] ページに移動

  2. [ルーティング ルール マップ] をクリックします。

  3. [ルーティング ルールを作成] をクリックします。

  4. URL マップの [名前] に「td-gke-url-map」と入力します。

  5. [転送ルールを追加] をクリックします。

  6. 転送ルール名に「td-gke-forwarding-rule」と入力します。

  7. ネットワークを選択します。

  8. [内部 IP] を選択します。

  9. [保存] をクリックします。

  10. 必要に応じて、カスタムホストとパスのルールを追加するか、パスルールをデフォルトのままにします。

  11. ホストを service-test に設定します。

  12. [保存] をクリックします。

gcloud

  1. バックエンド サービスを使用する URL マップを作成します。

    gcloud compute url-maps create td-gke-url-map \
       --default-service td-gke-service
    
  2. ホスト名とパスに基づいてサービスのトラフィックをルーティングする URL マップのパスマッチャーとホストルールを作成します。この例では、サービス名として service-test を使用し、このホスト(/*)のすべてのパスリクエストに一致するデフォルトのパスマッチャーを使用します。service-test は、上記のサンプル構成で使用されている Kubernetes Service の構成名でもあります。

    gcloud compute url-maps add-path-matcher td-gke-url-map \
       --default-service td-gke-service \
       --path-matcher-name td-gke-path-matcher
    
    gcloud compute url-maps add-host-rule td-gke-url-map \
       --hosts service-test \
       --path-matcher-name td-gke-path-matcher
    
  3. ターゲット HTTP プロキシを作成します。

    gcloud compute target-http-proxies create td-gke-proxy \
       --url-map td-gke-url-map
    
  4. 転送ルールを作成します。

    gcloud compute forwarding-rules create td-gke-forwarding-rule \
      --global \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --address=0.0.0.0 \
      --target-http-proxy=td-gke-proxy \
      --ports 80 --network default
    

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

ネットワークでのマイクロサービスの分散方法によっては、URL マップに転送ルールまたはホストとパスのルールを追加することが必要な場合があります。

テスト用のサンプル クライアントをデプロイして構成を確認する

このセクションでは、クライアント アプリケーションから Cloud Service Mesh バックエンドにアクセスする方法について説明します。

機能を示すために、Busybox を実行しているサンプル Pod をデプロイできます。Pod は、前のセクションで作成した service-test へのアクセス権を持ち、Cloud Service Mesh によってロード バランシングされたトラフィックを受信します。

GKE / Kubernetes Pod へのサイドカー プロキシの挿入

Cloud Service Mesh によって管理されているサービスにアクセスするには、Pod に xDS API 互換のサイドカー プロキシがインストールされている必要があります。

この例では、リファレンス仕様に従ってデプロイメントに Istio プロキシ サイドカーと init コンテナを追加して、Buybox クライアントをデプロイします。

古い API を使用している場合は、PROJECT_NUMBER 変数と NETWORK_NAME 変数をプロジェクト番号とネットワーク名に置き換えます。

wget -q -O - https://storage.googleapis.com/traffic-director/demo/trafficdirector_client_sample_xdsv3.yaml
sed -i "s/PROJECT_NUMBER/PROJECT_NUMBER/g" trafficdirector_client_sample_xdsv3.yaml
sed -i "s/NETWORK_NAME/NETWORK_NAME/g" trafficdirector_client_sample_xdsv3.yaml
kubectl apply -f trafficdirector_client_sample_xdsv3.yaml

新しいサービス ルーティング API(現在はプレビュー版)を使用している場合は、PROJECT_NUMBER 変数と MESH_NAME 変数をプロジェクト番号と Mesh 名前に置き換えます。

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
kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml

Busybox Pod では 2 つのコンテナが実行されています。1 つ目のコンテナは Busybox イメージに基づくクライアントであり、2 番目のコンテナはサイドカーとして挿入された Envoy プロキシです。次のコマンドを実行すると、Pod に関する詳細情報を取得できます。

kubectl describe pods -l run=client

バックエンド サービスへのアクセス

構成が完了すると、サイドカー プロキシが挿入された Pod 上のアプリケーションは、Cloud Service Mesh サービスが管理するサービスにアクセスできます。構成を確認するには、いずれかのコンテナのシェルにアクセスします。

このガイドで提供されているデモ構成を使用した場合は、次の確認コマンドを実行して、サービング Pod のホスト名が返されることを確認できます。

# Get name of the Pod  with busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the Pod .
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

サイドカー プロキシによるトラフィックのインターセプトについて

この例では、Busybox クライアントがバックエンド サービスにリクエストを送信すると、各リクエストはサイドカー プロキシによってプロキシされます。

このデモ アプリケーションでは Envoy プロキシを使用します。そのため、クライアントではサーバー レスポンスのヘッダーに「server: envoy」と表示されます。

これを確認するには、次のコマンドを使用します。

# Get the name of the Pod  with Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to send a request to service-test and output server response headers.
TEST_CMD="wget -S --spider service-test; echo"

# Execute the test command on the Pod .
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

この例では、VIP アドレス 0.0.0.0 を使用して転送ルールを作成しました。つまり、Cloud Service Mesh は Host ヘッダーのみに基づいてリクエストをバックエンドに転送します。この場合、リクエスト ホストヘッダーが URL マップ service-test で定義されたホストと一致する限り、宛先 IP アドレスは任意のアドレスにできます。

これを確認するには、次のテストコマンドを実行します。

# Get name of the Pod  with Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to send a request to service-test setting the Host header and using a random IP address.
TEST_CMD="wget -q --header 'Host: service-test' -O - 1.2.3.4; echo"

# Execute the test command on the Pod .
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

次のステップ