Cloud Service Mesh 用に従来のアプリケーション ロードバランサを構成する
概要
このドキュメントは、Istiod のマネージド コントロール プレーンを使用している既存の Cloud Service Mesh ユーザーで、従来のアプリケーション ロードバランサを Ingress ゲートウェイとして構成する必要があるユーザーを対象としています。従来のアプリケーション ロードバランサは、従来の外部アプリケーション ロードバランサとも呼ばれます。
Cloud Service Mesh を初めて利用される場合は、このドキュメントを使用しないでください。新しいユーザーは、Cloud Service Mesh マネージド コントロール プレーンで自動的に設定されます。Cloud Service Mesh マネージド コントロール プレーンでは、このドキュメントで説明する構成は使用できません。
Cloud Load Balancing では、グローバル エニーキャスト ロード バランシング、Google マネージド証明書、Identity and Access Management、Cloud Next Generation Firewall、Cloud Intrusion Detection System など、さまざまなクラウド マネージド エッジ機能を使用できます。Cloud Service Mesh は、次のメッシュ Ingress モデルでこれらのエッジ機能をシームレスに統合できます。サービス メッシュ クラウド ゲートウェイは、Kubernetes Gateway API を介して Cloud Load Balancing と同時に Cloud Service Mesh Ingress ゲートウェイを構成する、統合された方法を提供します。
以前のユーザーガイドであるエッジからメッシュへ: GKE Ingress によるサービス メッシュ アプリケーションの公開と比べると、サービス メッシュ クラウド ゲートウェイのこのモデルでは 1 つの Kubernetes Gateway リソースを介してデプロイできるようになり、クラウドとクラスタホスト型のロードバランシングを同時にデプロイするプロセスが簡素化されました。
プレビューの制限
この機能のプレビュー リリースには次の制限があります。
- マルチクラスタ Gateway はサポート対象外
- Autopilot クラスタはサポート対象外
- 従来のアプリケーション ロードバランサのみがサポートされています。グローバル外部アプリケーション ロードバランサ(高度なロードバランサとも呼ばれます)と内部アプリケーション ロードバランサはサポートされていません。
- 従来のアプリケーション ロードバランサと Cloud Service Mesh Ingress ゲートウェイ間のトラフィックは、TLS を使用して暗号化されます。ただし、従来のアプリケーション ロードバランサは、Cloud Service Mesh Ingress ゲートウェイから提供された証明書を検証しません。この制限は、Google Cloud HTTP(S) ロードバランサのユーザーすべてに適用されます。
- Cloud Service Mesh
GatewayClasses
がクラスタから削除された場合、再インストールは自動的に行われません。ただし、この機能のユーザビリティに影響はありません。 - ルート マッチング ロジックは Gateway API の仕様に準拠していないため、それに代わって
HTTPRoute
の順序で照合されます。これは、Gateway API の仕様に従って今後のバージョンで変更されます。
要件
- マネージド Cloud Service Mesh が、1.24 以降の Google Kubernetes Engine(GKE)クラスタにインストールされていること。他の GKE Enterprise クラスタはサポートされていません。
- Kubernetes Gateway API v1beta1 バージョンのみ。
前提条件
プロジェクトで次の API を有効にします。
- compute.googleapis.com
- container.googleapis.com
- certificatemanager.googleapis.com
- serviceusage.googleapis.com
gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ certificatemanager.googleapis.com \ serviceusage.googleapis.com
単一クラスタ メッシュ用のサービス メッシュ クラウド ゲートウェイをデプロイする
このセクションでは、従来のアプリケーション ロードバランサと Cloud Service Mesh Ingress ゲートウェイをデプロイする Kubernetes Gateway リソースのデプロイ方法について説明します。
マネージド Cloud Service Mesh を使用して Gateway API を有効にする
クラスタで Gateway API を有効にします。GKE クラスタはバージョン 1.24 以降である必要があります。
rapid
またはregular
をリリース チャンネルとするマネージド Cloud Service Mesh をインストールします。
Gateway リソースをデプロイする
サービス メッシュ クラウド ゲートウェイをデプロイする場合、Kubernetes Gateway リソースを使用して、Cloud Load Balancing と Cloud Service Mesh Ingress ゲートウェイの両方を 1 つのステップでデプロイします。Kubernetes Gateway リソースは Istio Gateway リソースとは異なることに注意してください。
この違いの詳細については、Kubernetes Gateway と Istio Gateway をご覧ください。すべての Kubernetes Gateway には、その種類と固有の機能を示す GatewayClass があります。サービス メッシュ クラウド ゲートウェイには、Cloud Load Balancing と Cloud Service Mesh Ingress ゲートウェイの両方をデプロイする機能を備えた GatewayClass があります。
次の GatewayClass マニフェストを
l7-gateway-class.yaml
という名前のファイルに保存します。apiVersion: gateway.networking.k8s.io/v1beta1 kind: GatewayClass metadata: name: asm-l7-gxlb spec: controllerName: mesh.cloud.google.com/gateway
クラスタに GatewayClass をデプロイします。
kubectl apply -f l7-gateway-class.yaml
インストール後に GatewayClass が存在することを確認します。
kubectl get gatewayclasses.gateway.networking.k8s.io
出力は次のようになります。
NAME CONTROLLER asm-l7-gxlb mesh.cloud.google.com/gateway gke-l7-rilb networking.gke.io/gateway gke-l7-gxlb networking.gke.io/gateway
リソースがすべてデプロイされるまでに数分かかることがあります。想定された出力が表示されない場合は、前提条件が正しく満たされていることを確認してください。
次の GatewayClass も表示されます。
gke-l7-gxlb networking.gke.io/gateway
これは、基盤となる Google Cloud の従来のアプリケーション ロードバランサをデプロイするために使用されます。
サービス メッシュ クラウド ゲートウェイ専用の Namespace を作成します。
kubectl create namespace istio-ingress
次の Gateway マニフェストを
gateway.yaml
という名前のファイルに保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All
istio-ingress Namespace のクラスタに Gateway をデプロイします。
kubectl apply -f gateway.yaml
Kubernetes Gateway API オブジェクトが作成されていることを確認します。
kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
出力は次のようになります。
NAME CLASS ADDRESS READY AGE asm-gw-gke-servicemesh-cloud-gw gke-l7-gxlb 34.111.114.64 True 9m40s asm-gw-istio-servicemesh-cloud-gw istio 9m44s servicemesh-cloud-gw asm-l7-gxlb 9m44s
この Kubernetes Gateway API オブジェクトがデプロイされると、次のようなことが起こります。
- 外部 HTTP(S) ロードバランサがデプロイされ、構成されます。起動までに数分かかることがありますが、その場合、Gateway は IP アドレスを表示し、作成された Compute Engine ロードバランサのリソースの名前がアノテーションとして表示されます。
- Cloud Service Mesh Ingress ゲートウェイの Deployment が istio-ingress Namespace に作成されます。これにより、ロードバランサからトラフィックを受信する Envoy プロキシ インスタンスが作成されます。
- ロードバランサがすべてのトラフィックを暗号化し、Cloud Service Mesh Ingress ゲートウェイに転送します。
これで、インターネット トラフィックをメッシュで受け入れるために必要なインフラストラクチャがすべて整いました。これは最も簡単な Gateway のデプロイです。以降のセクションでは、本番環境で使用するために必要なポリシーと機能を追加します。
アプリとルーティングのデプロイ
アプリケーションを Cloud Service Mesh にデプロイして、Gateway 経由でインターネット トラフィックを受信する場合を例にして、機能について詳しく説明します。
default
Namespace にラベルを付けてサイドカー インジェクションを有効にします。kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
次の Gateway マニフェストを
whereami.yaml
という名前のファイルに保存します。apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v1 spec: replicas: 2 selector: matchLabels: app: whereami-v1 template: metadata: labels: app: whereami-v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v1" --- apiVersion: v1 kind: Service metadata: name: whereami-v1 spec: selector: app: whereami-v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v2 spec: replicas: 2 selector: matchLabels: app: whereami-v2 template: metadata: labels: app: whereami-v2 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v2" --- apiVersion: v1 kind: Service metadata: name: whereami-v2 spec: selector: app: whereami-v2 ports: - port: 8080 targetPort: 8080
このマニフェストは、ID と位置を示す JSON を出力するシンプルなアプリケーションである whereami の
Service/whereami-v1
、Service/whereami-v2
、Deployment/whereami-v1
、Deployment/whereami-v2
を作成するものです。2 種類のバージョンをデプロイします。Service と Deployment を作成します。
kubectl apply -f whereami.yaml
準備が完了すると、クラスタ内で 4 つの whereami Pod が実行されます。
4 つの Pod すべてが稼働していることを確認します。
kubectl get pods
出力は次のようになります。
whereami-v1-7c76d89d55-qg6vs 2/2 Running 0 28s whereami-v1-7c76d89d55-vx9nm 2/2 Running 0 28s whereami-v2-67f6b9c987-p9kqm 2/2 Running 0 27s whereami-v2-67f6b9c987-qhj76 2/2 Running 0 27s
次の HTTPRoute マニフェストを
http-route.yaml
という名前のファイルに保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: where-route spec: parentRefs: - kind: Gateway name: servicemesh-cloud-gw namespace: istio-ingress hostnames: - "where.example.com" rules: - matches: - headers: - name: version value: v2 backendRefs: - name: whereami-v2 port: 8080 - backendRefs: - name: whereami-v1 port: 8080
クラスタに
http-route.yaml
をデプロイします。kubectl apply -f http-route.yaml
この HTTPRoute は
servicemesh-cloud-gw
を参照します。つまり、これらのルーティング ルールを使用して基盤となる Cloud Service Mesh Ingress ゲートウェイを構成するように、サービス メッシュ クラウド ゲートウェイを構成します。HTTPRoute は Istio VirtualService と同じ機能を実行するために Kubernetes Gateway API を使用します。Gateway API は、多くの基盤となる実装を備えた OSS 仕様であるため、異なるロードバランサ(Cloud Service Mesh プロキシやロードバランサなど)の組み合わせでルーティングを定義するのに最適な API です。アプリケーションにトラフィックを送信できるように、Gateway から IP アドレスを取得します。
VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
出力は IP アドレスです。
echo $VIP 34.111.61.135
Gateway IP アドレスにトラフィックを送信して、この設定が正しく機能していることを確認します。
version: v2
ヘッダーのあるリクエストとヘッダーなしのリクエストを 1 つづつ送信し、2 つのアプリケーション バージョンでルーティングが正しく行われていることを確認します。curl ${VIP} -H "host: where.example.com" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v1", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v1-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" } curl ${VIP} -H "host: where.example.com" -H "version: v2" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v2", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v2-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" }
本番環境ゲートウェイのデプロイ
前のセクションでは、サービス メッシュ クラウド ゲートウェイの非常にシンプルな例について説明しました。次の手順では、そのシンプルな例を基にして、上り(内向き)ルーティング機能の一部をロードバランサの従来のアプリケーション ロードバランサに委ねることの利点を示す、本番環境に対応した設定を紹介します。
Cloud Service Mesh を初めて利用される場合は、このドキュメントを使用しないでください。新しいユーザーは、Cloud Service Mesh マネージド コントロール プレーンで自動的に設定されます。Cloud Service Mesh マネージド コントロール プレーンでは、このドキュメントで説明する構成は使用できません。
Cloud Load Balancing では、グローバル エニーキャスト ロード バランシング、Google マネージド証明書、Identity and Access Management、Cloud Next Generation Firewall、Cloud Intrusion Detection System など、さまざまなクラウド マネージド エッジ機能を使用できます。Cloud Service Mesh は、次のメッシュ Ingress モデルでこれらのエッジ機能をシームレスに統合できます。サービス メッシュ クラウド ゲートウェイは、Kubernetes Gateway API を介して Cloud Load Balancing と同時に Cloud Service Mesh Ingress ゲートウェイを構成する、統合された方法を提供します。
以前のユーザーガイドであるエッジからメッシュへ: GKE Ingress によるサービス メッシュ アプリケーションの公開と比べると、サービス メッシュ クラウド ゲートウェイのこのモデルでは 1 つの Kubernetes Gateway リソースを介してデプロイできるようになり、クラウドとクラスタホスト型のロードバランシングを同時にデプロイするプロセスが簡素化されました。
プレビューの制限
この機能のプレビュー リリースには次の制限があります。
- マルチクラスタ Gateway はサポート対象外
- Autopilot クラスタはサポート対象外
- 従来のアプリケーション ロードバランサのみがサポートされています。グローバル外部アプリケーション ロードバランサ(高度なロードバランサとも呼ばれます)と内部アプリケーション ロードバランサはサポートされていません。
- 従来のアプリケーション ロードバランサと Cloud Service Mesh Ingress ゲートウェイ間のトラフィックは、TLS を使用して暗号化されます。ただし、従来のアプリケーション ロードバランサは、Cloud Service Mesh Ingress ゲートウェイから提供された証明書を検証しません。この制限は、Google Cloud HTTP(S) ロードバランサのユーザーすべてに適用されます。
- Cloud Service Mesh
GatewayClasses
がクラスタから削除された場合、再インストールは自動的に行われません。ただし、この機能のユーザビリティに影響はありません。 - ルート マッチング ロジックは Gateway API の仕様に準拠していないため、それに代わって
HTTPRoute
の順序で照合されます。これは、Gateway API の仕様に従って今後のバージョンで変更されます。
要件
- マネージド Cloud Service Mesh が、1.24 以降の Google Kubernetes Engine(GKE)クラスタにインストールされていること。他の GKE Enterprise クラスタはサポートされていません。
- Kubernetes Gateway API v1beta1 バージョンのみ。
前提条件
プロジェクトで次の API を有効にします。
- compute.googleapis.com
- container.googleapis.com
- certificatemanager.googleapis.com
- serviceusage.googleapis.com
gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ certificatemanager.googleapis.com \ serviceusage.googleapis.com
単一クラスタ メッシュ用のサービス メッシュ クラウド ゲートウェイをデプロイする
このセクションでは、従来のアプリケーション ロードバランサと Cloud Service Mesh Ingress ゲートウェイをデプロイする Kubernetes Gateway リソースのデプロイ方法について説明します。
マネージド Cloud Service Mesh を使用して Gateway API を有効にする
クラスタで Gateway API を有効にします。GKE クラスタはバージョン 1.24 以降である必要があります。
rapid
またはregular
をリリース チャンネルとするマネージド Cloud Service Mesh をインストールします。
Gateway リソースをデプロイする
サービス メッシュ クラウド ゲートウェイをデプロイする場合、Kubernetes Gateway リソースを使用して、Cloud Load Balancing と Cloud Service Mesh Ingress ゲートウェイの両方を 1 つのステップでデプロイします。Kubernetes Gateway リソースは Istio Gateway リソースとは異なることに注意してください。
この違いの詳細については、Kubernetes Gateway と Istio Gateway をご覧ください。すべての Kubernetes Gateway には、その種類と固有の機能を示す GatewayClass があります。サービス メッシュ クラウド ゲートウェイには、Cloud Load Balancing と Cloud Service Mesh Ingress ゲートウェイの両方をデプロイする機能を備えた GatewayClass があります。
次の GatewayClass マニフェストを
l7-gateway-class.yaml
という名前のファイルに保存します。apiVersion: gateway.networking.k8s.io/v1beta1 kind: GatewayClass metadata: name: asm-l7-gxlb spec: controllerName: mesh.cloud.google.com/gateway
クラスタに GatewayClass をデプロイします。
kubectl apply -f l7-gateway-class.yaml
インストール後に GatewayClass が存在することを確認します。
kubectl get gatewayclasses.gateway.networking.k8s.io
出力は次のようになります。
NAME CONTROLLER asm-l7-gxlb mesh.cloud.google.com/gateway gke-l7-rilb networking.gke.io/gateway gke-l7-gxlb networking.gke.io/gateway
リソースがすべてデプロイされるまでに数分かかることがあります。想定された出力が表示されない場合は、前提条件が正しく満たされていることを確認してください。
次の GatewayClass も表示されます。
gke-l7-gxlb networking.gke.io/gateway
これは、基盤となる Google Cloud の従来のアプリケーション ロードバランサをデプロイするために使用されます。
サービス メッシュ クラウド ゲートウェイ専用の Namespace を作成します。
kubectl create namespace istio-ingress
次の Gateway マニフェストを
gateway.yaml
という名前のファイルに保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All
istio-ingress Namespace のクラスタに Gateway をデプロイします。
kubectl apply -f gateway.yaml
Kubernetes Gateway API オブジェクトが作成されていることを確認します。
kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
出力は次のようになります。
NAME CLASS ADDRESS READY AGE asm-gw-gke-servicemesh-cloud-gw gke-l7-gxlb 34.111.114.64 True 9m40s asm-gw-istio-servicemesh-cloud-gw istio 9m44s servicemesh-cloud-gw asm-l7-gxlb 9m44s
この Kubernetes Gateway API オブジェクトがデプロイされると、次のようなことが起こります。
- 外部 HTTP(S) ロードバランサがデプロイされ、構成されます。起動までに数分かかることがありますが、その場合、Gateway は IP アドレスを表示し、作成された Compute Engine ロードバランサのリソースの名前がアノテーションとして表示されます。
- Cloud Service Mesh Ingress ゲートウェイの Deployment が istio-ingress Namespace に作成されます。これにより、ロードバランサからトラフィックを受信する Envoy プロキシ インスタンスが作成されます。
- ロードバランサがすべてのトラフィックを暗号化し、Cloud Service Mesh Ingress ゲートウェイに転送します。
これで、インターネット トラフィックをメッシュで受け入れるために必要なインフラストラクチャがすべて整いました。これは最も簡単な Gateway のデプロイです。以降のセクションでは、本番環境で使用するために必要なポリシーと機能を追加します。
アプリとルーティングのデプロイ
アプリケーションを Cloud Service Mesh にデプロイして、Gateway 経由でインターネット トラフィックを受信する場合を例にして、機能について詳しく説明します。
default
Namespace にラベルを付けてサイドカー インジェクションを有効にします。kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
次の Gateway マニフェストを
whereami.yaml
という名前のファイルに保存します。apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v1 spec: replicas: 2 selector: matchLabels: app: whereami-v1 template: metadata: labels: app: whereami-v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v1" --- apiVersion: v1 kind: Service metadata: name: whereami-v1 spec: selector: app: whereami-v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v2 spec: replicas: 2 selector: matchLabels: app: whereami-v2 template: metadata: labels: app: whereami-v2 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v2" --- apiVersion: v1 kind: Service metadata: name: whereami-v2 spec: selector: app: whereami-v2 ports: - port: 8080 targetPort: 8080
このマニフェストは、ID と位置を示す JSON を出力するシンプルなアプリケーションである whereami の
Service/whereami-v1
、Service/whereami-v2
、Deployment/whereami-v1
、Deployment/whereami-v2
を作成するものです。2 種類のバージョンをデプロイします。Service と Deployment を作成します。
kubectl apply -f whereami.yaml
準備が完了すると、クラスタ内で 4 つの whereami Pod が実行されます。
4 つの Pod すべてが稼働していることを確認します。
kubectl get pods
出力は次のようになります。
whereami-v1-7c76d89d55-qg6vs 2/2 Running 0 28s whereami-v1-7c76d89d55-vx9nm 2/2 Running 0 28s whereami-v2-67f6b9c987-p9kqm 2/2 Running 0 27s whereami-v2-67f6b9c987-qhj76 2/2 Running 0 27s
次の HTTPRoute マニフェストを
http-route.yaml
という名前のファイルに保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: where-route spec: parentRefs: - kind: Gateway name: servicemesh-cloud-gw namespace: istio-ingress hostnames: - "where.example.com" rules: - matches: - headers: - name: version value: v2 backendRefs: - name: whereami-v2 port: 8080 - backendRefs: - name: whereami-v1 port: 8080
クラスタに
http-route.yaml
をデプロイします。kubectl apply -f http-route.yaml
この HTTPRoute は
servicemesh-cloud-gw
を参照します。つまり、これらのルーティング ルールを使用して基盤となる Cloud Service Mesh Ingress ゲートウェイを構成するように、サービス メッシュ クラウド ゲートウェイを構成します。HTTPRoute は Istio VirtualService と同じ機能を実行するために Kubernetes Gateway API を使用します。Gateway API は、多くの基盤となる実装を備えた OSS 仕様であるため、異なるロードバランサ(Cloud Service Mesh プロキシやロードバランサなど)の組み合わせでルーティングを定義するのに最適な API です。アプリケーションにトラフィックを送信できるように、Gateway から IP アドレスを取得します。
VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
出力は IP アドレスです。
echo $VIP 34.111.61.135
Gateway IP アドレスにトラフィックを送信して、この設定が正しく機能していることを確認します。
version: v2
ヘッダーのあるリクエストとヘッダーなしのリクエストを 1 つづつ送信し、2 つのアプリケーション バージョンでルーティングが正しく行われていることを確認します。curl ${VIP} -H "host: where.example.com" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v1", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v1-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" } curl ${VIP} -H "host: where.example.com" -H "version: v2" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v2", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v2-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" }
本番環境ゲートウェイのデプロイ
前のセクションでは、サービス メッシュ クラウド ゲートウェイの非常にシンプルな例について説明しました。次の手順では、そのシンプルな例を基にして、上り(内向き)ルーティング機能の一部をロードバランサに委ねることの利点を示す、本番環境に対応した設定を紹介します。
次の例では、前のセクションの servicemesh-cloud-gw
を使用して、より安全で管理しやすい Gateway を作成するために以下の機能を追加します。
- 基盤となるインフラストラクチャが変更されても保持される静的 IP アドレスを持つ Gateway をデプロイします。
- 自己署名証明書を使用して HTTPS トラフィックを受信するように Gateway を変換します。
静的外部 IP アドレスを作成します。静的 IP は、基盤となるインフラストラクチャが将来変更されることがあっても、IP アドレスを保持できるため便利です。
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
where-example-com
ドメインの自己署名証明書を作成します。openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
TLS 証明書はさまざまな方法で生成できます。コマンドラインで手動で生成することも、Google マネージド証明書を使用して生成することもできます。また、社内の公開鍵基盤(PKI)システムによって内部的に生成することも可能です。この例では、自己署名証明書を手動で生成します。通常、自己署名証明書は公開サービスでは使用されませんが、この証明書を使用すると、こうしたコンセプトをわかりやすく説明できます。
Kubernetes Secret を使用して自己署名証明書を作成する方法の詳細については、ゲートウェイを保護するをご覧ください。
gateway.yaml
を次のマニフェストで更新します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
クラスタに Gateway を再度デプロイします。
kubectl apply -f gateway.yaml
静的 IP の IP アドレスを取得します。
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
curl
を使用して Gateway のドメインにアクセスします。このドメインに DNS は構成されていないため、--resolve オプションを使用して、ドメイン名を Gateway の IP アドレスに解決するように curl に指示します。curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
完了すると、出力は次のようになります。
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
詳細出力には、次の例のように、TLS handshake が成功した後のアプリケーションからのレスポンスが含まれます。これにより、Gateway で TLS が正しく終端し、アプリケーションが確実にクライアントに応答していることを確認できます。
これで、次のアーキテクチャが正常にデプロイされました。
servicemesh-cloud-gw
とその asm-l7-gxlb
GatewayClass では、ユーザー エクスペリエンスを簡素化するため、一部の内部インフラストラクチャ コンポーネントが抽象化されています。Cloud Load Balancing が内部証明書を使用して TLS トラフィックを終端します。また、Cloud Service Mesh Ingress ゲートウェイ プロキシ レイヤのヘルスチェックも行います。アプリとルーティングのデプロイでデプロイした whereami-route
は、トラフィックを正しいメッシュホストのサービスにルーティングするように Cloud Service Mesh Ingress ゲートウェイ プロキシを構成します。
次の例では、前のセクションの servicemesh-cloud-gw
を使用して、より安全で管理しやすい Gateway を作成するために以下の機能を追加します。
- 基盤となるインフラストラクチャが変更されても保持される静的 IP アドレスを持つ Gateway をデプロイします。
- 自己署名証明書を使用して HTTPS トラフィックを受信するように Gateway を変換します。
静的外部 IP アドレスを作成します。静的 IP は、基盤となるインフラストラクチャが将来変更されることがあっても、IP アドレスを保持できるため便利です。
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
where-example-com
ドメインの自己署名証明書を作成します。openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
TLS 証明書はさまざまな方法で生成できます。コマンドラインで手動で生成することも、Google マネージド証明書を使用して生成することもできます。また、社内の公開鍵基盤(PKI)システムによって内部的に生成することも可能です。この例では、自己署名証明書を手動で生成します。通常、自己署名証明書は公開サービスでは使用されませんが、この証明書を使用すると、こうしたコンセプトをわかりやすく説明できます。
Kubernetes Secret を使用して自己署名証明書を作成する方法の詳細については、ゲートウェイを保護するをご覧ください。
gateway.yaml
を次のマニフェストで更新します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
クラスタに Gateway を再度デプロイします。
kubectl apply -f gateway.yaml
静的 IP の IP アドレスを取得します。
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
curl
を使用して Gateway のドメインにアクセスします。このドメインに DNS は構成されていないため、--resolve オプションを使用して、ドメイン名を Gateway の IP アドレスに解決するように curl に指示します。curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
完了すると、出力は次のようになります。
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
詳細出力には、次の例のように、TLS handshake が成功した後のアプリケーションからのレスポンスが含まれます。これにより、Gateway で TLS が正しく終端し、アプリケーションが確実にクライアントに応答していることを確認できます。
これで、次のアーキテクチャが正常にデプロイされました。
servicemesh-cloud-gw
とその asm-l7-gxlb
GatewayClass では、ユーザー エクスペリエンスを簡素化するため、一部の内部インフラストラクチャ コンポーネントが抽象化されています。Cloud Load Balancing が内部証明書を使用して TLS トラフィックを終端します。また、Cloud Service Mesh Ingress ゲートウェイ プロキシ レイヤのヘルスチェックも行います。アプリとルーティングのデプロイでデプロイした whereami-route
は、トラフィックを正しいメッシュホストのサービスにルーティングするように Cloud Service Mesh Ingress ゲートウェイ プロキシを構成します。
次のステップ
- Kubernetes Gateway API の Google Kubernetes Engine(GKE)実装について確認する。
- オプションのマネージド Cloud Service Mesh 機能を有効にする方法を確認する。