このページでは、上り(内向き)トラフィックを単一の Google Kubernetes Engine(GKE)クラスタにロードバランスするために Kubernetes Gateway リソースをデプロイする方法について説明します。
Gateway をデプロイして複数のクラスタ(またはフリート)間で上り(内向き)トラフィックをロードバランスする方法については、マルチクラスタ Gateway のデプロイをご覧ください。始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API を有効にする
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
GKE Gateway Controller の要件
- Standard の場合は GKE バージョン 1.24 以降。
- Autopilot の場合は GKE バージョン 1.26 以降。
- Google Cloud CLI バージョン 407.0.0 以降。
- Gateway API は、VPC ネイティブ クラスタでのみサポートされます。
- 内部 GatewayClass を使用している場合は、プロキシ専用サブネットを有効にする必要があります。
- クラスタで
HttpLoadBalancing
アドオンが有効になっている必要があります。 - Istio を使用している場合は、Istio を次のいずれかのバージョンにアップグレードする必要があります。
- 1.15.2 以降
- 1.14.5 以降
- 1.13.9 以降
- 共有 VPC を使用している場合は、ホスト プロジェクトで、サービス プロジェクトの GKE サービス アカウントに
Compute Network User
ロールを割り当てる必要があります。
制限事項
GKE GatewayClasses がサポートする機能は、使用するロードバランサによって異なります。GatewayClass でサポートされている機能の詳細については、GatewayClass の機能をご覧ください。
FrontendConfig または BackendConfig を使用して Gateway を構成することはできません。ポリシーを使用する必要があります。
Ingress とは異なり、GKE Gateway はヘルスチェックのパラメータを推定しません。Service が
GET /
へのリクエストに対して 200 を返さない場合、または他の調整された Pod の readiness チェックがある場合は、サービスの HealthCheckPolicy を構成する必要があります。GKE が Gateway 用に作成したロードバランサ リソースは、Google Cloud コンソールで確認できますが、これらのリソースは接続先の Gateway や GKE クラスタを参照しません。
Gateway を使用して Google マネージド SSL 証明書を自動的に生成することはできませんが、Google マネージド SSL 証明書を手動で作成して参照することはできます。詳細については、Gateway を保護するをご覧ください。
Route タイプとしてサポートされているのは HTTPRoute だけです。TCPRoutes、UDPRoutes、TLSRoutes はサポートされていません。GKE Gateway Controller がサポートするフィールドの一覧については、GatewayClass の機能をご覧ください。
Gateway を含むカスタム リクエストとレスポンス ヘッダー、または Gateway を使用したパス リダイレクトと URL の書き換えは、GKE バージョン 1.27 以降でのみ使用できます。
- Gateway を含むカスタム リクエストとレスポンス ヘッダー、および Gateway を使用したパス リダイレクトと URL の書き換えの場合、GatewayClass
gke-l7-gxlb
はサポートされません。
HTTPRoute のカスタム リクエスト ヘッダーとレスポンス ヘッダーを構成する場合、次の Google Cloud 変数はサポートされません。
cdn_cache_id
(Cloud CDN は GKE Gateway でサポートされていません)cdn_cache_status
(Cloud CDN は GKE Gateway でサポートされていません)origin_request_header
(CORS ポリシーは GKE Gateway でサポートされていません)
GKE Gateway は Cloud CDN のロード バランシング機能をサポートしていません。
相互 TLS カスタム ヘッダーはサポートされていません(GKE Gateway で mTLS はサポートされていません)。
Google Cloud の従来のアプリケーション ロードバランサの制限は GKE Gateway に適用されます。さらに、次の制限も適用されます。
- バックエンド サービスでカスタムの Host レスポンス ヘッダーを構成することはできません。
パス リダイレクトと URL の書き換えは相互に排他的です。同じルールで両方のフィルタを同時に使用することはできません。
Cloud Load Balancing でトラフィックを別のポートにリダイレクトすることはできません。GKE Gateway Controller がサポートするフィールドの一覧については、GatewayClass の機能をご覧ください。
GKE Gateway は、ワイルドカード、正規表現、動的 URL をサポートしていません。
リージョン外部ゲートウェイ クラスを使用して Gateway を指定すると、コントローラは外部アドレスではなく内部 IP アドレスをプロビジョニングします。リージョン外部アプリケーション ロードバランサで名前付きアドレスを使用する方法については、リージョン外部 Gateway をデプロイするをご覧ください。
Gateway は、ネットワーク エンドポイント グループのプロビジョニングにスタンドアロン NEG を利用します。Gateway コントローラがロードバランサの構成を適切に調整できるようにするため、Gateway の一部である Service の
cloud.google.com/neg
アノテーションを変更することはできません。GKE Gateway は、GKE Ingress でも参照される Service の参照をサポートしていません。
IP アドレスをプロビジョニングするように
Gateway
が構成されている場合、Gateway.spec.gatewayClass
の変更はサポートされません。Gateway コントローラがロードバランサを適切に調整できるようにするため、既存の Gateway を削除し、更新されたgatewayClass
値を含むマニフェストを再度デプロイします。networking.gke.io/app-protocols
アノテーションはサポートされていません。同じ結果を得るには、代わりにappProtocol
フィールドを使用してください。
クラスタで Gateway API を有効にする
GKE で Gateway リソースを使用する前に、クラスタで Gateway API を有効にしておく必要があります。
Gateway API を有効にして新しいクラスタを作成する
GKE バージョン 1.26 以降では、GKE は Autopilot クラスタで Gateway API をサポートします。GKE 1.26 以降で新しい Autopilot クラスタを作成すると、Gateway API はデフォルトで有効になります。GKE バージョン 1.25 以前の既存のクラスタでは、Gateway API はデフォルトで無効になっています。
Autopilot
Gateway API を有効にする新しい GKE Autopilot クラスタを作成します。
gcloud container clusters create-auto CLUSTER_NAME \
--location=CLUSTER_LOCATION \
--release-channel=RELEASE_CHANNEL \
--cluster-version=VERSION
次のように置き換えます。
CLUSTER_NAME
: クラスタの名前。CLUSTER_LOCATION
: 新しいクラスタの Compute Engine のリージョンまたはゾーン。RELEASE_CHANNEL
: リリース チャンネルの名前。VERSION
: GKE のバージョン。1.26 以降にする必要があります。また、--release-channel
フラグを使用してリリース チャンネルを選択することもできます。リリース チャンネルには、デフォルトのバージョン 1.26 以降が必要です。
Standard
GKE Standard では、Gateway API は --gateway-api
フラグで制御されます。有効にする場合は値に standard を使用し、無効にする場合は値に disabled を使用します。
Gateway API が有効になっている新しい VPC ネイティブの GKE クラスタを作成します。
gcloud container clusters create CLUSTER_NAME \
--gateway-api=standard \
--cluster-version=VERSION \
--location=CLUSTER_LOCATION
次のように置き換えます。
RELEASE_CHANNEL
: リリース チャンネルの名前。CLUSTER_NAME
: クラスタの名前。VERSION
: GKE のバージョン。1.24 以降にする必要があります。また、--release-channel
フラグを使用してリリース チャンネルを選択することもできます。リリース チャンネルを使用するには、デフォルトのバージョン 1.24 以降が必要です。CLUSTER_LOCATION
: 新しいクラスタの Compute Engine のリージョンまたはゾーン。
--gateway-api=standard
フラグを指定すると、GKE は、クラスタと v1beta1
CRD をインストールします。
既存のクラスタで Gateway API を有効にする
Autopilot クラスタのバージョンが 1.26 以降で、Standard クラスタのバージョンが 1.24 以降であることを確認します。
既存の GKE クラスタ(Autopilot または Standard)で Gateway API を有効にするには、次のコマンドを使用します。
gcloud container clusters update CLUSTER_NAME \
--location=CLUSTER_LOCATION\
--gateway-api=standard
次のように置き換えます。
CLUSTER_NAME
: 既存のクラスタの名前。CLUSTER_LOCATION
: クラスタの Compute Engine のリージョンまたはゾーン。
--gateway-api=standard
フラグを指定すると、GKE は、クラスタと v1beta1
CRD をインストールします。
クラスタを確認する
クラスタを作成またはアップグレードすると、GKE Gateway Controller は GatewayClass を自動的にインストールします。コントローラが CRD を認識してから GatewayClass をインストールするまでに数分かかることがあります。
GKE コントロール プレーンで Gateway API が有効になっていることを確認します。
gcloud container clusters describe CLUSTER_NAME \ --location=CLUSTER_LOCATION \ --format json
出力は次のようになります。この出力が空の場合は、cluster update コマンドを再実行します。
"networkConfig": { ... "gatewayApiConfig": { "channel": "CHANNEL_STANDARD" }, ... },
GatewayClasses がクラスタにインストールされていることを確認します。
kubectl get gatewayclass
出力は次のようになります。
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-rilb networking.gke.io/gateway True 16h
各 GatewayClass の機能については、GatewayClass の機能をご覧ください。
内部 Gateway をデプロイする
内部 Gateway は、VPC または VPC に接続されているネットワーク内からのみ到達可能なアプリケーションを公開します。
リージョン内部 Gateway をデプロイする
次の例は、特定の地理的リージョン内のサービス間で効率的かつ安全な通信を可能にするリージョン内部 Gateway をデプロイする方法を示しています。
プロキシ専用サブネットを構成する
内部アプリケーション ロードバランサを使用する Gateway を作成する前に、プロキシ専用サブネットを構成する必要があります。内部アプリケーション ロードバランサを使用する VPC の各リージョンには、プロキシ専用サブネットが必要です。このサブネットは、ロードバランサ プロキシに内部 IP アドレスを提供します。
プロキシ専用サブネットを作成します。
gcloud compute networks subnets create SUBNET_NAME \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=COMPUTE_REGION \ --network=VPC_NETWORK_NAME \ --range=CIDR_RANGE
次のように置き換えます。
SUBNET_NAME
: プロキシ専用サブネットの名前。COMPUTE_REGION
: プロキシ専用サブネットのリージョン。VPC_NETWORK_NAME
: サブネットを含む VPC ネットワークの名前。CIDR_RANGE
: サブネットのプライマリ IP アドレス範囲。サブネット マスクの長さは/26
以下にして、リージョン内のプロキシで 64 個以上の IP アドレスを使用できるようにします。推奨のサブネット マスクは/23
です。
プロキシ専用サブネットを確認します。
gcloud compute networks subnets describe SUBNET_NAME \ --region=COMPUTE_REGION
出力は次のようになります。
... gatewayAddress: 10.1.1.1 ipCidrRange: 10.1.1.0/24 kind: compute#subnetwork name: proxy-subnet network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default privateIpGoogleAccess: false privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS purpose: REGIONAL_MANAGED_PROXY region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION role: ACTIVE selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet state: READY
Gateway を作成する
Gateway リソースは、Kubernetes のトラフィックをルーティングするデータプレーンを表します。Gateway は、派生元の GatewayClass に応じて、さまざまなロード バランシングとルーティングを表すことができます。Gateway リソースの詳細については、Gateway リソースの説明または API 仕様をご覧ください。
このケースでは、GKE クラスタの管理者は、さまざまなチームがアプリケーションを内部で公開するための Gateway を作成したいと考えています。管理者が Gateway をデプロイして、アプリケーション チームが Route を個別にデプロイし、Gateway に接続します。
次の Gateway マニフェストを
gateway.yaml
という名前のファイルに保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80
このマニフェストには次のフィールドがあります。
gatewayClassName: gke-l7-rilb
: この Gateway の派生元となる GatewayClass を指定します。gke-l7-rilb
は、内部アプリケーション ロードバランサに対応しています。port: 80
: HTTP トラフィックをリッスンするためにポート 80 のみを公開することを指定します。
クラスタに Gateway をデプロイします。
kubectl apply -f gateway.yaml
Gateway が正しくデプロイされたことを確認します。すべてのリソースがデプロイされるまで数分かかる場合があります。
kubectl describe gateways.gateway.networking.k8s.io internal-http
出力は次のようになります。
Name: internal-http Namespace: default Spec: Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 192.168.1.14 Conditions: Last Transition Time: 1970-01-01T00:00:00Z Message: Waiting for controller Reason: NotReconciled Status: False Type: Scheduled Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 92s networking.gke.io/gateway test/internal-http Normal UPDATE 45s (x3 over 91s) networking.gke.io/gateway test/internal-http Normal SYNC 45s networking.gke.io/gateway SYNC on test/internal-http was a success
この時点で、ロードバランサと IP アドレスをプロビジョニングしているクラスタに Gateway がデプロイされます。ただし、Gateway には Route がないため、バックエンドにトラフィックを送信する方法がわかりません。Route を使用しないと、すべてのトラフィックがデフォルトのバックエンドに移動し、HTTP 404 を返します。次に、アプリケーションと Route をデプロイします。これにより、Gateway にアプリケーション バックエンドの取得方法が指示されます。
デモ アプリケーションをデプロイする
アプリケーション チームは、Gateway のデプロイとは別にアプリケーションと Route をデプロイできます。アプリケーション チームで Gateway を所有し、アプリケーション専用のリソースとしてデプロイすることもできます。Gateway と Route のさまざまな所有権モデルについては、Route のバインディングをご覧ください。ただし、この例では、ストアチームがアプリケーションと付属の HTTPRoute をデプロイし、前のセクションで作成した internal-http
Gateway 経由でアプリを公開します。
HTTPRoute リソースには、トラフィック照合用の構成可能なフィールドが多数あります。HTTPRoute のフィールドの説明については、API の仕様をご覧ください。
ストア アプリケーション(store-v1、store-v2、store-german のデプロイ)をクラスタにデプロイします。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
これにより、3 つの Deployment と、store-v1、store-v2、store-german という名前の 3 つの Service が作成されます。
アプリケーションのデプロイが成功したことを確認します。
kubectl get pod
アプリケーションが稼働した後の出力は次のようになります。
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14m
Service がデプロイされていることを確認します。
kubectl get service
出力には、各ストア Deployment の Service が表示されます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
HTTPRoute をデプロイする
Route リソースは、Gateway から Kubernetes バックエンドにトラフィックをマッピングするためのプロトコル固有のルールを定義します。HTTPRoute リソースは、HTTP および HTTPS トラフィックの照合とフィルタリングを行います。これは、すべての gke-l7
GatewayClasss でサポートされています。
このセクションでは、HTTPRoute をデプロイし、トア アプリケーションに到達するために必要なルーティング ルールを使用して Gateway を制御します。
次の HTTPRoute マニフェストを
store-route.yaml
という名前のファイルに保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store spec: parentRefs: - kind: Gateway name: internal-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080 - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 - matches: - path: value: /de backendRefs: - name: store-german port: 8080
クラスタに HTTProute をデプロイします。
kubectl apply -f store-route.yaml
store
HTTPRoute はparentRefs
プロパティを使用してinternal-http
Gateway にバインドされます。次の図のように、これらのルーティング ルールは基盤となるロードバランサで構成されます。これらのルーティング ルールは HTTP トラフィックを次のように処理します。
store.example.com/de
へのトラフィックは、Servicestore-german
に送信されます。- HTTP ヘッダー
"env: canary"
を含むstore.example.com
へのトラフィックは、Servicestore-v2
に送信されます。 store.example.com
への残りのトラフィックは、Servicestore-v1
に送信されます。
HTTPRoute がデプロイされていることを確認します。
kubectl describe httproute store
出力は次のようになります。
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1beta1 Kind: HTTPRoute <...> Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: Conditions: Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 24m sc-gateway-controller default/store Normal SYNC 16m (x4 over 23m) sc-gateway-controller Bind of HTTPRoute "default/store" to ParentRef {Group: gateway.networking.k8s.io", <...>
HTTPRoute が Gateway にバインドされていることを確認します。
kubectl describe gateway
出力は次のようになります。
Name: internal-http Namespace: default Labels: <none> <...> Status: Addresses: Type: IPAddress Value: 10.128.15.203 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute <...>
アプリケーションにトラフィックを送信する
クラスタに Gateway、Route、アプリケーションがデプロイされたので、アプリケーションにトラフィックを送信してみましょう。
アプリケーションにトラフィックを送信できるように、Gateway から IP アドレスを取得します。
kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"
出力は IP アドレスです。
クラスタに接続している仮想マシン(VM)インスタンスのシェルから、この IP アドレスにトラフィックを送信します。この目的で使用する VM を作成することもできます。Gateway に内部 IP アドレスが割り振られ、VPC ネットワーク内からのみアクセスされるため、この操作が必要になります。
internal-http
はリージョン ロードバランサです。クライアント シェルは GKE クラスタと同じリージョン内に存在する必要があります。example.com ホスト名の所有者ではないため、ホストヘッダーを手動で設定してトラフィック ルーティングを監視できるようにします。最初に store.example.com にリクエストを送信してみましょう。
curl -H "host: store.example.com" VIP
VIP
は、前の手順で取得した IP アドレスに置き換えます。デモアプリの出力には、アプリが実行されている場所に関する情報が含まれます。
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:31:17", "zone": "ZONE_NAME" }
store.example.com/de
にあるドイツ語版のストアサービスにアクセスして、パスの照合をテストします。curl -H "host: store.example.com" VIP/de
出力で、リクエストが
store-german
Pod で処理されたことを確認できます。{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:35:37", "zone": "ZONE_NAME" }
最後に、
env: canary
HTTP ヘッダーを使用して、ストアの Service のカナリア バージョンにトラフィックを送信します。curl -H "host: store.example.com" -H "env: canary " VIP
出力で、リクエストが
store-v2
Pod で処理されたことを確認できます。{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "🦰", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:38:26", "zone": "ZONE_NAME" }
外部 Gateway をデプロイする
外部 Gateway は、インターネットまたは VPC 外のネットワークから到達可能なアプリケーションを公開します。これは内部 Gateway のデプロイと似ていますが、Gateway が公共のインターネットにアクセスできるため、アプリケーションを保護する必要があります。
外部 Gateway を作成する場合、グローバル外部 Gateway を作成する方法とリージョン外部 Gateway を作成する方法があります。
グローバル外部 Gateway は、すべての Google Cloud Compute リージョンでアドバタイズされる Gateway のフロントエンドとしてグローバル IP アドレス(またはエニーキャスト IP アドレス)を使用します。このエニーキャスト IP アドレスにトラフィックを送信するクライアントは、IP がアドバタイズされている最も近い Google ロケーションにルーティングされます。グローバル外部 Gateway は、プレミアム ネットワーク サービス ティアでのみ使用できます。
リージョン外部 Gateway は、リージョン外部 Gateway がデプロイされているローカル Google Cloud Compute リージョンでのみアドバタイズされる Gateway のフロントエンドとしてリージョン IP を使用します。このリージョン IP アドレスにトラフィックを送信するクライアントは、ローカル ISP とインターネット経由でルーティングされてから、IP がアドバタイズされている Google リージョンに到達します。リージョン外部 Gateway は、スタンダード ネットワーク サービス ティアでのみ使用できます。
グローバル外部 Gateway をデプロイする
次の例は、グローバル外部 Gateway に関連付けられ、Certificate Manager と HTTPRoute を使用して証明書マップにグループ化された複数の証明書を持つストア アプリケーションを公開する方法を示しています。
証明書マップを作成する
Gateway ごとに 15 個以上の証明書が必要な場合や、ワイルドカード証明書を使用する必要がある場合は、Certificate Manager を使用して証明書を管理することをおすすめします。
Kubernetes Secret または Google マネージド SSL 証明書を使用して外部 Gateway を保護することもできます。詳細については、Gateway のセキュリティをご覧ください。
このセクションでは、Certificate Manager を使用して証明書を作成し、クラスタ上で実行されるアプリケーションを保護します。
Certificate Manager API を有効にします。
gcloud services enable certificatemanager.googleapis.com
証明書マップを作成します。
gcloud beta certificate-manager maps create store-example-com-map
Google マネージド証明書と鍵を証明書に読み込みます。
gcloud beta certificate-manager certificates create store-example-com-cert \ --certificate-file="CERTIFICATE_FILE" \ --private-key-file="PRIVATE_KEY_FILE"
次のように置き換えます。
CERTIFICATE_FILE
: 選択した新しいファイルの名前。ファイルの拡張子は.pem
にする必要があります。例:cert.pem
PRIVATE_KEY_FILE
: 秘密鍵ファイルの名前。
詳細については、秘密鍵と証明書を作成するをご覧ください。
CertificateMapEntry
を作成します。これにより、証明書を証明書マップに割り当てます。gcloud beta certificate-manager maps entries create store-example-com-map-entry \ --map=store-example-com-map \ --hostname=store.example.com \ --certificates=store-example-com-cert
Kubernetes Secret や SSL 証明書など、証明書の他のソースを使用して Gateway を保護する方法については、Gateway を保護するをご覧ください。
Gateway を作成する
Gateway リソースは、Kubernetes のトラフィックをルーティングするデータプレーンを表します。Gateway は、使用する GatewayClass に応じて、さまざまなロード バランシングとルーティングを表すことができます。
Gateway リソースの詳細については、Gateway リソースの説明または API 仕様をご覧ください。
このセクションでは、Gateway を作成します。アプリケーション チームは、Route を個別にデプロイして Gateway に安全に接続することで、Gateway を使用してアプリケーションをインターネットに公開できます。
次のマニフェストを
gateway.yaml
という名前のファイルに保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http annotations: networking.gke.io/certmap: store-example-com-map spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443
このマニフェストでは、次のフィールドを使用して Gateway を記述しています。
gatewayClassName: gke-l7-global-external-managed
: この Gateway の GatewayClass を指定します。このゲートウェイ クラスは、グローバル外部アプリケーション ロードバランサを使用します。protocol: HTTPS
とport: 443
: Gateway が HTTPS トラフィック用にポート 443 を公開することを指定します。これらのフィールドにより TLS が有効になります。networking.gke.io/certmap: store-example-com-map
: Certificate Manager の証明書マップの名前を指定します。
TLS はアノテーション
networking.gke.io/certmap
を使用して Certificate Manager で構成されるため、TLS セクションはありません。マニフェストをクラスタに適用します。
kubectl apply -f gateway.yaml
GKE がリソースをデプロイするまでに数分かかることがあります。
Gateway のデプロイが成功したことを確認します。
kubectl describe gateway
出力は次のようになります。
Name: external-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-global-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
この出力は、クラスタにデプロイされた Gateway にロードバランサとパブリック IP アドレスがあることを示しています。Gateway には Route がありません。つまり、バックエンドにトラフィックを送信できません。Route を使用しないと、すべてのトラフィックがデフォルトのバックエンドに転送され、HTTP 404 レスポンスが返されます。次のセクションでは Route をデプロイして、バックエンドにトラフィックを送信するように Gateway に指示します。
デモ アプリケーションをデプロイする
アプリケーション チームは、Gateway のデプロイとは別にアプリケーションと Route をデプロイできます。アプリケーション チームで Gateway を所有し、アプリケーション専用のリソースとしてデプロイすることもできます。Gateway と Route のさまざまな所有権モデルについては、Route のバインディングをご覧ください。この例では、ストアチームがアプリケーションと付属の HTTPRoute をデプロイし、前のセクションで作成した external-http
Gateway 経由でアプリを公開します。
HTTPRoute フィールドの詳細については、API 仕様をご覧ください。
サンプル アプリケーションをクラスタにデプロイします。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
このサンプル アプリケーションは、
store-v1
、store-v2
、store-german
という名前の 3 つの Deployment と 3 つの Service を作成します。アプリケーションのデプロイが成功したことを確認します。
kubectl get pod
出力は次のようになります。
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14m
Service が正常にデプロイされたことを確認します。
kubectl get service
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
HTTPRoute を作成する
Route リソースは、Gateway から Kubernetes バックエンドにトラフィックをマッピングするためのプロトコル固有のルールを定義します。HTTPRoute リソースは、HTTP および HTTPS トラフィックの照合とフィルタリングを行います。これは、すべての gke-l7-*
GatewayClass でサポートされています。
このセクションでは、HTTPRoute をデプロイします。これにより、サンプル アプリケーションに到達するために必要なルーティング ルールで Gateway が構成されます。
次のマニフェストを
store-route-external.yaml
という名前のファイルに保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external spec: parentRefs: - kind: Gateway name: external-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080 - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 - matches: - path: value: /de backendRefs: - name: store-german port: 8080
このマニフェストでは、
external-http
Gateway を参照する HTTPRoute を記述しています。マニフェストをクラスタに適用します。
kubectl apply -f store-route-external.yaml
store
HTTPRoute はparentRefs
プロパティを使用してexternal-http
Gateway にバインドされます。次の図は、基盤となるロードバランサで構成されたルーティング ルールを示しています。ルーティング ルールは、HTTP トラフィックを次のように処理します。
store.example.com/de
へのトラフィックは Servicestore-german
に転送されます。- HTTP ヘッダー
"env: canary"
を含むstore.example.com
へのトラフィックは、Servicestore-v2
に転送されます。 store.example.com
への残りのトラフィックは、Servicestore-v1
に転送されます。
HTTPRoute がデプロイされていることを確認します。
kubectl describe httproute store-external
出力は次のようになります。
Name: store-external Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1beta1 Kind: HTTPRoute <...> Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: Conditions: Last Transition Time: 2022-11-01T05:42:31Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m48s sc-gateway-controller default/store-external Normal SYNC 61s (x3 over 2m27s) sc-gateway-controller Bind of HTTPRoute "default/store-external" to ParentRef Group: "gateway.networking.k8s.io", ...
HTTPRoute が Gateway にバインドされていることを確認します。
kubectl describe gateway external-http
出力は次のようになります。
Name: external-http Namespace: default Labels: <none> <...> Status: Addresses: Type: IPAddress Value: 34.149.207.45 Conditions: Last Transition Time: 2022-11-01T05:37:21Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Name: https Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute <...>
アプリケーションにトラフィックを送信する
クラスタに Gateway、Route、アプリケーションがデプロイされたので、アプリケーションにトラフィックを送信してみましょう。
Gateway の IP アドレスを取得します。
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
出力は IP アドレスです。
VM を作成します。
gcloud cloud-shell ssh
VM から Gateway IP アドレスにトラフィックを送信します。
example.com
ホスト名を所有していないため、host ヘッダーを手動で設定する必要があります。curl -H "host: store.example.com" https://GATEWAY_IP_ADDRESS --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
GATEWAY_IP_ADDRESS
は、前の手順の Gateway の IP アドレスに置き換えます。出力には、アプリの実場所に関するデモアプリからの情報が表示されます。
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:31:17", "zone": "us-central1-a" }
store.example.com/de
にあるドイツ語版のstore
サービスにアクセスして、パスの照合をテストします。curl -H "host: store.example.com" https://GATEWAY_IP_ADDRESS/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
出力で、リクエストが
store-german
Pod で処理されたことを確認できます。{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:35:37", "zone": "us-central1-a" }
env: canary
HTTP ヘッダーを使用して、store
Service のカナリア バージョンにトラフィックを送信します。curl -H "host: store.example.com" -H "env: canary " https://GATEWAY_IP_ADDRESS/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
出力で、リクエストが
store-v2
Pod で処理されたことを確認できます。{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "👩🏿", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:38:26", "zone": "us-central1-a" }
リージョン外部 Gateway をデプロイする
次の例は、セルフマネージド証明書と HTTPRoute を使用して、リージョン外部 Gateway に関連付けられた複数の証明書を持つストア アプリケーションを公開する方法を示しています。
リージョン Gateway のプロキシ サブネットを作成する
リージョン外部アプリケーション ロードバランサを使用する Gateway を作成する前に、プロキシ専用サブネットを構成する必要があります。リージョン外部アプリケーション ロードバランサを使用する VPC の各リージョンには、external_managed_proxy
サブネットが必要です。このサブネットは、ロードバランサ プロキシに内部 IP アドレスを提供します。
証明書を作成してクライアント トラフィックを保護する
認証局(CA)から発行された検証済みの証明書を使用するか、自己署名証明書を作成できます。証明書の作成方法の詳細については、Kubernetes Secret に証明書を保存するをご覧ください。
リージョン外部 HTTP(S) Gateway を作成する
外部ロードバランサのリージョン静的 IP アドレスを作成します。
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARD
次のように置き換えます。
IP_ADDRESS_NAME
: 新しい静的 IP アドレスの名前。COMPUTE_REGION
: クラスタが動作している Compute Engine リージョン。
次のようにセルフマネージド証明書を使用して、リージョン外部アプリケーション ロードバランサの Gateway を作成し、マニフェストを
regional-gateway.yaml
として保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-regional-http spec: gatewayClassName: gke-l7-regional-external-managed listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: store-example-com addresses: - type: NamedAddress value: IP_ADDRESS_NAME
regional-gateway
マニフェストを適用します。kubectl apply -f regional-gateway.yaml
構成を確認します。
kubectl get gateway
出力は次のようになります。
NAME CLASS ADDRESS READY AGE external-http gke-l7-regional-external-managed 35.118.32.224 True 49s
詳細を取得するには、describe コマンドを使用します。
kubectl describe gateway
出力は次のようになります。
Name: external-regional-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-regional-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
デモ アプリケーションをデプロイする
Gateway のデプロイとは別に、アプリケーションとルートをデプロイできます。
デモ アプリケーションのデプロイ方法については、デモ アプリケーションをデプロイするをご覧ください。HTTPRoute を作成する
HTTP および HTTPS トラフィックの照合とフィルタリングを行うには、HTTPRoute を作成する必要があります。
アプリケーションにトラフィックを送信する
アプリケーションをデプロイして HTTPRoute を作成したら、アプリケーションにトラフィックを渡すことができます。
アプリケーションにトラフィックを送信する方法については、アプリケーションにトラフィックを送信するをご覧ください。共有 Gateway を使用する
Gateway API は、個別のリソース、Gateway と Route のリソースを使用して、ロードバランサとルーティング ルールをデプロイします。Ingress とは異なり、1 つのリソースにすべてが結合されます。リソース間で責任を分担することにより、Gateway でロードバランサとルーティング ルールを別々にデプロイすることが可能になります。これらは、異なるユーザーまたはチームがデプロイすることもできます。これにより、Gateway を複数の異なる Route で接続される共有 Gateway にし、Namespace が異なる場合でも、個々のチームで完全に所有し、管理できるようになります。
共有 Gateway に対するルートをデプロイする
この例は、内部 Gateway のデプロイでデプロイした internal-http
Gateway を基盤としています。
この例では、サイトチームがアプリケーション、Service、HTTPRoute をデプロイして、Gateway からこれらの Service へのトラフィックを照合します。
サンプル アプリケーションをデプロイします。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml
次のマニフェストを
site-route-internal.yaml
という名前のファイルに保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: site-internal spec: parentRefs: - kind: Gateway name: internal-http hostnames: - "site.example.com" rules: - backendRefs: - name: site-v1 port: 8080
このマニフェストでは、
site.example.com
のすべてのトラフィックを照合し、一致したものをsite-v1
Service にルーティングする HTTPRoute を記述しています。マニフェストをクラスタに適用します。
kubectl apply -f site-route-internal.yaml
HTTPRoute が Gateway に接続されていることを確認します。
kubectl describe httproute.gateway.networking.k8s.io site-internal
出力は次のようになります。
Status: Parents: Conditions: Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http ...
Gateway の
Accepted
条件がTrue
の場合、HTTPRoute は Gateway に正常にバインドされています。[Status] フィールドの詳細については、ルートのステータスをご覧ください。Gateway へのトラフィックが正しくルーティングされていることを確認します。
curl -H "host: site.example.com" GATEWAY_IP_ADDRESS curl -H "host: store.example.com" GATEWAY_IP_ADDRESS
GATEWAY_IP_ADDRESS
は、Gateway の IP アドレスに置き換えます。Gateway と同じ VPC で仮想マシン(VM)を使用する必要があります。
出力は次のようになります。
{ "cluster_name": "CLUSTER_NAME", "host_header": "site.example.com", "metadata": "site-v1", "pod_name": "site-v1-5d64fc4d7d-fz6f6", "pod_name_emoji": "👩🏼🍳", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" } ... { "cluster_name": "CLUSTER_NAME", "host_header": "store.example.com", "metadata": "store-v1", "pod_name": "store-v1-6d8d58d78-vz8pn", "pod_name_emoji": "🧝🏻♂️", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" }
Gateway のデフォルト バックエンドを構成する
すべての gke-l7-*
GatewayClass は、一致しないトラフィックに対して HTTP 404 を返します。一致しないトラフィックをユーザー指定の Service に送信する明示的なデフォルト Route を使用して、デフォルト バックエンドを構成できます。
次の HTTPRoute は、デフォルトのバックエンドをカスタマイズする方法の一例です。次のような HTTPRoute を適用すると、暗黙的なデフォルト バックエンドよりも優先されます。
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: custom-default-backend
spec:
parentRefs:
- kind: Gateway
name: my-internal-gateway
rules:
- backendRefs:
- name: my-custom-default-backend-service
port: 8080
この HTTPRoute は特定の Gateway のすべてのトラフィックに一致します。このようなルールは Gateway ごとに 1 つだけ設定できます。そうでない場合は、ルールが競合して優先順位が適用されます。
デフォルトのバックエンドを使用して、すべての Gateway トラフィックをルーティングするデフォルト ルートのバックエンドが作成されないようにすることができます。明示的な HTTPRoute は、競合するルーティング ルールを持つ新しい HTTPRoute よりも常に優先されます。
Gateway に静的 IP アドレスを構成する
どの Gateway にもトラフィックのリッスンに使用する IP アドレスがあります。Gateway の IP アドレスを指定しない場合、Gateway コントローラは自動的に IP アドレスを提供します。Gateway のライフサイクルとは独立して IP アドレスが存在するように、静的 IP アドレスを作成することもできます。
Gateway がデプロイされると、ステータス フィールドにその IP アドレスが表示されます。
kind: Gateway
...
status:
addresses:
- value: 10.15.32.3
GatewayClass に応じて、IP アドレスは次のサブネットから割り振られます。
GatewayClass | デフォルトの IP アドレスプール |
---|---|
|
プライマリ ノードの IPv4 / IPv6 アドレス範囲のリージョン プライベート IP アドレス |
|
Google のリージョン外部 IPv4 / IPv6 範囲のリージョン パブリック IP アドレス |
|
Google のグローバル外部 IPv4 / IPv6 範囲のグローバル パブリック IP アドレス |
addresses.NamedAddress
フィールドを使用すると、Gateway とは無関係に IP アドレスを指定できます。Gateway のデプロイ前に静的 IP アドレス リソースを作成できます。これらのリソースは、NamedAddress
によって参照されます。Gateway が削除されても、静的 IP アドレスは再利用できます。
名前付き IP アドレスを使用する
IP アドレスを構成するには、NamedAddress
を指定します。Gateway を作成する前に、静的 IP アドレスをプロビジョニングする必要があります。
静的 IP アドレス リソースを作成します。
gcloud compute addresses create IP_ADDRESS_NAME \ --purpose=SHARED_LOADBALANCER_VIP \ --region=COMPUTE_REGION \ --subnet=SUBNET \ --project=PROJECT_ID
次のように置き換えます。
IP_ADDRESS_NAME
: 新しい静的 IP アドレスの名前COMPUTE_REGION
: リージョン Gateway の場合、クラスタが動作している Compute Engine リージョン。 このフラグは、グローバル外部 Gateway には必要ありません。SUBNET
: IP アドレスのサブネット。 このフラグは、グローバル外部 Gateway には必要ありません。PROJECT_ID
: GKE クラスタが実行されているプロジェクト。
次のマニフェストを
named-ip-gateway.yaml
という名前のファイルに保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 addresses: - type: NamedAddress value: IP_ADDRESS_NAME
このマニフェストでは、指定された IP アドレスを参照する Gateway を記述しています。
マニフェストをクラスタに適用します。
kubectl apply -f named-ip-gateway.yaml
Gateway の IP アドレスを確認します。
kubectl describe gateway internal-http
出力は次のようになります。
Name: internal-http Namespace: default Labels: <none> ... Spec: Addresses: Type: NamedAddress Value: IP_ADDRESS_NAME Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.15.32.103
HTTP から HTTPS へのリダイレクトを構成する
Cloud Load Balancing には、HTTP から HTTPS へのリダイレクト機能が用意されています。外部アプリケーション ロードバランサは、同じ IP アドレスを使用する HTTPS ロードバランサに、暗号化されていない HTTP リクエストをリダイレクトします。HTTP から HTTPS へのリダイレクトを有効にして Gateway を作成すると、この両方のロードバランサが自動的に作成されます。ポート 80 の Gateway の外部 IP アドレスへのリクエストは、ポート 443 の同じ外部 IP アドレスに自動的にリダイレクトされます。
デフォルトでは、HTTP から HTTPS へのリダイレクトは Gateway で定義されていません。
HTTP トラフィックを HTTPS にリダイレクトするには、HTTP と HTTPS の両方のトラフィックを処理するように Gateway を構成します。HTTP または HTTPS を無効にすると、Gateway はトラフィックをリダイレクトしません。
次の例では、クライアントからウェブ アプリケーションに向うトラフィックが常に安全なページにリダイレクトされるようにするために、HTTP から HTTPS へのリダイレクトを使用する方法を示します。
Gateway Namespace からの HTTP トラフィックをリダイレクトする
次の例では、HTTPS リスナーがすべての Namespace に対して開かれている間、HTTP リスナーで Same
(同じ Namespace からのアタッチメント)を許可するように Gateway が構成されています。この構成を使用する場合、リダイレクト HTTPRoute
のみを Gateway と同じ Namespace に置く必要があります。
この構成により、追加の HTTPRoute が Gateway の HTTP リスナーにバインドされないことが保証されます。そのためには、アプリケーション チームの HTTPRoute を gateway-infra
Namespace で許可しないようにする必要があります。
Gateway の Namespace
gateway-infra
を作成します。マニフェストをgateway-namespace.yaml
として保存します。apiVersion: v1 kind: Namespace metadata: name: gateway-infra
次のようにマニフェストを適用します。
kubectl apply -f gateway-namespace.yaml
次のマニフェストを使用して Gateway を作成し、マニフェストを
external-gateway.yaml
として保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http namespace: gateway-infra spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: Same - name: https protocol: HTTPS port: 443 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-com
allowedRoutes
セクションのnamespaces
フィールドは、HTTP リスナーを Gateway の Namespacegateway-infra
のみに制限します。https リスナーには、許可される Namespace に対する制限が含まれていないため、すべての Namespace で HTTPRoute とともに https リスナーを使用します。
次のようにマニフェストを適用します。
kubectl apply -f external-gateway.yaml
HTTPS リダイレクトを強制するには、次のマニフェストを使用してデフォルトの HTTPRoute を作成し、マニフェストを
redirect-httproute.yaml
として保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: redirect namespace: gateway-infra spec: parentRefs: - namespace: gateway-infra name: external-http sectionName: http rules: - filters: - type: RequestRedirect requestRedirect: scheme: https
sectionName
フィールドは、http リスナーのみで照合するように Gateway に指示します。RequestRedirect
フィルタは、https リスナーへのリダイレクトを強制します。
この構成では、Gateway のポート 80 で受信したトラフィックをポート 443 のリスナーにリダイレクトし、クライアントとロードバランサの間で安全な通信を実現します。
次のようにマニフェストを適用します。
kubectl apply -f redirect-httproute.yaml
次のマニフェストを使用して、アプリケーションの Service を作成します。マニフェストを
service-deployment.yaml
として保存します。apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store version: v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store version: v1 template: metadata: labels: app: store version: 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: "store-v1"
次のようにマニフェストを適用します。
kubectl apply -f service-deployment.yaml
HTTPS のみを許可するアプリケーションに HTTPRoute を作成します。マニフェストを
httproute.yaml
として保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http namespace: gateway-infra sectionName: https hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
次のようにマニフェストを適用します。
kubectl apply -f httproute.yaml
インフラストラクチャ Namespace からの HTTP トラフィックをリダイレクトする
場合によっては、インフラストラクチャやプラットフォームの管理チームとアプリケーション チームとの間に明確な違いがなく、Gateway の誤用防止が課題になることがあります。
次の例では、HTTP リスナーの使用をさらに制限して、アプリケーション チームが誤ってセキュアでないプロトコルを使用しないようにします。この例では、ルートが特定の Namespace(http-redirect)にある場合にのみ HTTPRoute が HTTP リスナーを使用できるようにし、すべての Namespace に対して HTTPS リスナーを開くように Gateway を構成します。Kubernetes RBAC を使用して http-redirect Namespace を制限することで、アプリケーション チームが誤ってこの Namespace に HTTPRoute を作成しないようにします。
Gateway の Namespace を作成し、マニフェストを
gateway-namespace.yaml
として保存します。apiVersion: v1 kind: Namespace metadata: name: gateway-infra
次のようにマニフェストを適用します。
kubectl apply -f gateway-namespace.yaml
Gateway の Namespace を作成し、マニフェストを
redirect-namespace.yaml
として保存します。apiVersion: v1 kind: Namespace metadata: name: http-redirect labels: otherInfra: httpToHttps
- この Namespace には特定のラベルが設定されています。
次のようにマニフェストを適用します。
kubectl apply -f redirect-namespace.yaml
HTTP リスナーの使用を制限するには、次のマニフェストを使用して Gateway を作成します。マニフェストを
external-gateway.yaml
として保存します。kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http namespace: gateway-infra spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: selector selector: matchLabels: otherInfra: httpToHttps - name: https protocol: HTTPS port: 443 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-com ```
namespace
フィールドには、Gateway がgateway-infra
Namespace に作成されることを指定します。allowedRoutes
セクションのnamespaces
フィールドは、HTTP リスナーをラベルotherInfra: httpToHttps
と一致する Namespace に制限します。
次のようにマニフェストを適用します。
kubectl apply -f external-gateway.yaml
HTTPS リダイレクトを強制するには、次のマニフェストを使用してデフォルトの HTTPRoute を作成します。マニフェストを
http-redirect.yaml
として保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: redirect namespace: http-redirect spec: parentRefs: - namespace: gateway-infra name: external-http sectionName: http rules: - filters: - type: RequestRedirect requestRedirect: scheme: https
sectionName
フィールドは、http リスナーのみで照合するように Gateway に指示します。RequestRedirect
フィルタは、HTTPS リスナーへのリダイレクトを強制します。
次のようにマニフェストを適用します。
kubectl apply -f http-redirect.yaml
次のマニフェストを使用して、アプリケーションの Service を作成します。マニフェストを
service-deployment.yaml
として保存します。apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store version: v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store version: v1 template: metadata: labels: app: store version: 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: "store-v1"
次のようにマニフェストを適用します。
kubectl apply -f service-deployment.yaml
次のマニフェストを使用して、HTTPS のみを許可するアプリケーションに HTTPRoute を作成します。マニフェストを
http-route.yaml
として保存します。kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http namespace: gateway-infra sectionName: https hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
次のようにマニフェストを適用します。
kubectl apply -f http-route.yaml
パス リダイレクトと URL の書き換えを構成する
パス リダイレクトを使用すると、受信リクエストを 1 つの URL パスから別の URL パスにリダイレクトできます。パス リダイレクトを使用すると、古い URL や非推奨の URL を処理する必要がある場合に URL の構造を変更できます。
URL の書き換えは、受信 URL を変更してからサーバーで処理する場合に役立ちます。これにより、基になるコンテンツやファイル構造を実際に変更することなく、URL の構造や形式を変更できます。URL の書き換えは、覚えやすく理解しやすい、ユーザー フレンドリーで SEO に適した URL を作成するのに便利です。デフォルトでは、パス リダイレクトと URL の書き換えは構成されていません。HTTPRoute のフィルタを使用して、これらのリダイレクトまたは書き換えを明示的に構成する必要があります。
GKE Gateway はパス リダイレクトと URL の書き換えをサポートしています。詳細については、HTTP パス リダイレクトと書き換えをご覧ください。
パス リダイレクトを構成する
パス リダイレクトを構成して、パス全体または URL 内の接頭辞のみを置き換えることができます。
パス全体を置き換える
パス全体を置き換えるには、URL パスに接頭辞
/any-path
を含む任意の URL を厳格な値/new-path
に置き換えるフィルタを HTTPRoute に構成します。次のように
HTTPRoute
マニフェストを作成し、store.yaml
という名前を付けます。apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: type: PathPrefix value: /any-path filters: - type: RequestRedirect requestRedirect: path: type: ReplaceFullPath replaceFullPath: /new-path statusCode: 302
たとえば、このマニフェストでは、URL https://store.example.com/any-path/... へのルートが新しいロケーション https://store.example.com/new-path/ にリダイレクトされるように、HTTPRoute のルーティング ルールを厳格に設定しています。
次のようにマニフェストを適用します。
kubectl apply -f store.yaml
このルーティング ルールは厳格なリダイレクト ルールに従っています。ブラウザは、リダイレクトをキャッシュに保存せず、最新バージョンにリダイレクトします。
接頭辞のみを置き換える
接頭辞のみを置き換えるには、URL パスに接頭辞
/any-prefix
が含まれる URL を厳格な値/new-prefix
に置き換えるフィルタを HTTPRoute に構成します。次のように
HTTPRoute
マニフェストを作成し、store.yaml
という名前を付けます。apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: type: PathPrefix value: /any-prefix filters: - type: RequestRedirect requestRedirect: path: type: ReplacePrefixMatch replacePrefixMatch: /new-prefix statusCode: 302
たとえば、このマニフェストでは、URL https://store.example.com/any-path/v1/... へのルートを新しい場所 https://store.example.com/new-path/v1/... のみにリダイレクトされるように HTTPRoute のルーティング ルールを設定しています。
次のようにマニフェストを適用します。
kubectl apply -f store.yaml
このルーティング ルールは、唯一のリダイレクト ルールに従っています。ブラウザは常に同じページにリダイレクトされます。
URL の書き換えを構成する
URL の書き換えを設定すると、ユーザーへの URL の表示方法を変更できます。URL の書き換えは、URL をよりユーザー フレンドリーにしたり、SEO を改善するために使用します。また、ユーザーを新しいページにリダイレクトする場合にも使用できます。
ホスト名全体を書き換える
ホスト名全体を書き換えるには:
www.example.com から store.example.com へのリクエスト ヘッダーで
Host
情報を置き換えるようにゲートウェイに指示するフィルタを HTTPRoute で構成してから、リクエストをバックエンド サービスに転送します。次のように
HTTPRoute
マニフェストを作成し、www.yaml
という名前を付けます。apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - filters: - type: URLRewrite urlRewrite: hostname: store.example.com backendRefs: - name: store-v1 port: 8080
たとえば、上記の構成では、https://www.example.com へのリクエストは、
Host: www.example.com
ではなく、Host: store.example.com
ヘッダーを有するバックエンド サービスに転送されます。次のようにマニフェストを適用します。
kubectl apply -f www.yaml
パス修飾子を使用して書き換える
パス修飾子と組み合わせて書き換えを使用すると、リクエストをバックエンド サービスにリレーする前に、URL とパスに対して高度な変更を行うことができます。
パス修飾子を使用して書き換えるには:
www.example.com から store.example.com へのリクエスト ヘッダーで「ホスト」情報を置き換えるようにゲートウェイが指示するフィルタを HTTPRoute で構成し、値
/store
を値/
に置き換えてから、リクエストをバックエンド サービスに転送します。次のように
HTTPRoute
マニフェストを作成し、www.yaml
という名前を付けます。apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - matches: - path: type: PathPrefix value: /store filters: - type: URLRewrite urlRewrite: hostname: store.example.com path: type: ReplacePrefixMatch replacePrefixMatch: /de backendRefs: - name: store-german port: 8080
たとえば、上記の構成では、https://www.example.com/store/... へのリクエストはリクエスト ヘッダーに
Host: www.example.com
ではなくHost: store.example.com
があるバックエンド サービスに転送され、/store
は/de
に書き換えられます。次のようにマニフェストを適用します。
kubectl apply -f www.yaml
構成を確認する
URL の書き換えフィルタまたはパス リダイレクト フィルタを使用して HTTPRoute の作成後にフィルタが適用されたことを確認するには、次の操作を行います。
kubectl get httproute www -o yaml
出力は次のようになります。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1beta1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
creationTimestamp: "2023-06-22T01:00:42Z"
generation: 3
name: www
namespace: default
resourceVersion: "51268631"
uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
spec:
hostnames:
- www.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: external-http
rules:
- backendRefs:
- group: ""
kind: Service
name: store-german
port: 8080
weight: 1
filters:
- type: URLRewrite
urlRewrite:
hostname: store.example.com
path:
replacePrefixMatch: /de
type: ReplacePrefixMatch
matches:
- path:
type: PathPrefix
value: /store
status:
parents:
- conditions:
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: ReconciliationSucceeded
status: "True"
type: Reconciled
controllerName: networking.gke.io/gateway
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: external-http
詳細を確認するには、describe コマンドを使用します。
kubectl describe httproute
カスタム リクエストとレスポンス ヘッダーを構成する
カスタム リクエスト ヘッダーとカスタム レスポンス ヘッダーを使用すると、HTTP(S) のリクエストとレスポンスに追加のヘッダーを指定できます。ロードバランサで検出された情報に応じて、これらのヘッダーには次の情報が含まれます。
- クライアントまでのレイテンシ
- クライアントの IP アドレスの地理的位置
- TLS 接続のパラメータ
デフォルトでは、バックエンド サービスとの間で送受信されるリクエストに追加されるカスタム ヘッダーはありません。HTTPRoute のフィルタを使用して、カスタム ヘッダーを明示的に構成する必要があります。
カスタム ヘッダーを構成するには、次のように HTTPRoute のルールにフィルタ セクションを追加します。
カスタム リクエスト ヘッダーを構成する
RequestHeaderModifier フィルタを含む HTTPRoute マニフェストを作成し、http-route-request.yaml:
として保存します。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
<...>
次のようにマニフェストを適用します。
kubectl apply -f http-route-request.yaml
カスタム レスポンス ヘッダーを構成する
ResponseHeaderModifier フィルタを含む HTTPRoute マニフェストを作成し、http-route-response.yaml:
として保存します。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
<...>
次のようにマニフェストを適用します。
kubectl apply -f http-route-response.yaml
Gateway API の実装に説明されているように、ヘッダーの追加、設定、削除を行うことができます。Google Cloud でサポートされている変数を使用して、カスタム ヘッダーで HTTPRoute を構成できます。
例 1:
バックエンド サービスに送信する前にクライアントの位置情報を HTTP リクエストに追加する HTTPRoute を構成するには、HTTPRoute マニフェストを作成して external-http-request.yaml
という名前を付けます。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /fr
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Client-Geo-Location
value: "{client_region},{client_city}"
backendRefs:
- name: store-french
port: 8080
たとえば、フランスのストラスブールにあるクライアントの場合、Gateway は X-Client-Geo-Location:FR,Strasbourg
としてヘッダーを追加します。
例 2:
HTTP Strict Transport Security をサポートするカスタム レスポンス ヘッダーを追加する HTTPRoute を構成するには、HTTPRoute マニフェストを作成して external-http-response.yaml
という名前を付けます。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /de
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: Strict-Transport-Security
value: max-age=63072000
backendRefs:
- name: store-german
port: 8080
構成を確認する
カスタム リクエスト ヘッダーとカスタム レスポンス ヘッダーを構成した後に構成を確認するには、次の操作を行います。
kubectl get httproute
出力は次のようになります。
NAME HOSTNAMES AGE store ["store.example.com"] 4d23h
詳細を確認するには、describe コマンドを使用します。
kubectl describe httproute
出力は次のようになります。
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1beta1 Kind: HTTPRoute Metadata: Creation Timestamp: 2023-05-27T00:51:01Z Generation: 5 Resource Version: 25418887 UID: 2e07a1b8-420b-41b4-acd1-cecbfcd39f42 Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Filters: Request Header Modifier: Add: Name: X-Client-Geo-Location Value: {client_region},{client_city} Type: RequestHeaderModifier Matches: Path: Type: PathPrefix Value: /de Status: <...>
ルートのステータス
HTTPRoute リソースは条件とイベントを出力します。これにより、HTTPRoute が 1 つ以上の Gateway と正常にバインドされたかどうか、または拒否されたかどうかを確認できます。
HTTPRoute 条件
HTTPRoute 条件は、Route とバインドされている Gateway のステータスを示します。1 つの Route は複数の Gateway にバインドできるため、これは、Gateway および Route と Gateway 間の個々の条件のリストとなります。
Accepted=True
は、HTTPRoute が Gateway に正常にバインドされたことを示します。Accepted=False
は、HTTPRoute がこの Gateway とのバインディングで拒否されたことを示します。
Gateway bindings
見出しに「Gateway」がない場合、HTTPRoute ラベルと Gateway ラベルセレクタが一致していない可能性場合があります。これは、どの Gateway も Route を選択していない場合に発生します。
HTTPRoute イベント
HTTPRoute イベントは、HTTPRoute のステータスの詳細を提供します。イベントは、次の理由でグループ化されます。
ADD
イベントは、リソースの追加によってトリガーされます。UPDATE
イベントは、リソースの更新によってトリガーされます。SYNC
イベントは、定期的な調整でトリガーされます。
ルートのマージ、優先度、検証
ルートの優先度
Gateway API は、厳密な優先ルールを定義し、ルーティング ルールが重複している Route がトラフィックを照合する方法を制御します。重複する 2 つの HTTPRoutes 間の優先度は次のとおりです。
- ホスト名のマージ: 最も長い、または最も具体的なホスト名と一致。
- パスのマージ: 最も長い、または最も具体的なパスと一致。
- ヘッダーのマージ: 一致する HTTP ヘッダーの最大数。
- 競合: 前述の 3 つのルールが優先されない場合、最も古いタイムスタンプの HTTPRoute リソースが使用されます。
ルートのマージ
gke-l7
GatewayClasses の場合、特定の Gateway のすべての HTTPRoute は同じ URL マップリソースにマージされます。HTTPRoute をマージする方法は、HTTPRoute 間の重複のタイプによって異なります。前述の例の HTTPRoute は、ルートのマージと優先順位を示す 3 つの HTTPRoute に分割できます。
- ルートのマージ: 3 つの HTTPRoute はすべて同じ
internal-http
Gateway に接続されるため、1 つにマージされます。 - ホスト名のマージ:
store.example.com
の 3 つの Route がすべて一致するため、ホスト名ルールがマージされます。 - パスのマージ: store-german-route はより具体的なパス
/de
を持つため、マージされません。store-v1-route と store-v2-route はどちらも同じ/*
パスと一致するため、これらのパスでマージされます。 - ヘッダーのマージ: store-v2-route には、store-v1-route よりも具体的な一連の HTTP ヘッダーの一致があるため、マージされません。
- 競合: Route をホスト名、パス、ヘッダーとマージできるため、競合は発生せず、すべてのルーティング ルールがトラフィックに適用されます。
前述の例で使用した 1 つの HTTPRoute は、これらの 3 つのルートと同等です。
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-v1-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- kind: Service
name: store-v1
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-v2-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- headers:
- type: Exact
name: env
value: canary
backendRefs:
- kind: Service
name: store-v2
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-german-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /de
backendRefs:
- kind: Service
name: store-german
port: 8080
Kubernetes Gateway と Istio Gateway
Kubernetes Gateway API と Istio API にはどちらも Gateway
という名前のリソースがあります。機能は似ていますが、同じリソースではありません。同じ Kubernetes クラスタで Istio と Gateway API を使用している場合、コマンドラインで kubectl を使用するときに名前の重複が発生します。kubectl get gateway
は Kubernetes Gateway リソースを返す場合がありますが、Istio Gateway リソースは返しません。その逆も同様です。
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
gateways gw networking.istio.io/v1beta1 true Gateway
gateways gtw networking.k8s.io/v1beta1 true Gateway
Istio を使用して GKE 1.20 以降にアップグレードする場合は、Gateway リソースの省略名を使用するか、API グループを指定することをおすすめします。Kubernetes Gateway の省略名は gtw
、Istio ゲートウェイの省略名は gw
です。次のコマンドは、Kubernetes Gateway リソースと Istio Gateway リソースをそれぞれ返します。
# Kubernetes Gateway
$ kubectl get gtw
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
$ kubectl get gateway.networking.x-k8s.io
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
# Istio Gateway
$ kubectl get gw
NAME AGE
bookinfo-gateway 64m
$ kubectl get gateway.networking.istio.io
NAME AGE
bookinfo-gateway 64m
トラブルシューティング
リージョンにプロキシ専用サブネットが存在しない
症状:
リージョン Gateway(内部または外部)を作成する際に、次の問題が発生する場合があります。
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
理由:
このエラー メッセージは、Gateway のリージョンにプロキシ専用サブネットが存在しないことを示します。
回避策:
この問題を解決するには、プロキシ専用サブネットを構成します。
プロキシ専用サブネットが誤った目的でリージョンにすでに存在する
症状:
リージョン Gateway(内部または外部)にプロキシ専用サブネットを作成する際に、次の問題が発生する場合があります。
ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
- The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
理由:
このエラー メッセージは、すでにプロキシ専用サブネットが存在するリージョンにリージョン プロキシ専用サブネットを作成しようとしたことを示します。
回避策:
この問題を解決する手順は次のとおりです。
リージョンにプロキシ専用サブネットがすでに存在することを確認し、目的が正しいことを確認します。
サブネットを一覧表示して、リージョン内のプロキシ専用サブネットを見つけます。
gcloud compute networks subnets list --regions=COMPUTE_REGION
COMPUTE_REGION
は、リージョン Gateway を作成する Compute Engine リージョンに置き換えます。リージョン内のプロキシ専用サブネットの説明を取得して、目的を確認します。
gcloud compute networks subnets describe PROXY_ONLY_SUBNET \ --region COMPUTE_REGION | grep -E 'name|purpose'
PROXY_ONLY_SUBNET
は、プロキシ専用サブネットに置き換えます。
GKE Gateway は、リージョン Gateway(内部またはリージョン)の
REGIONAL_MANAGED_PROXY
プロキシ専用サブネットのみをサポートします。リージョン内の既存のプロキシ専用サブネットが
INTERNAL_HTTPS_LOAD_BALANCER
の目的で作成された場合は、サブネットの目的をREGIONAL_MANAGED_PROXY
に移行します。
次のステップ
- Gateway コントローラの詳細を確認する。
- ポリシーを使用して Gateway リソースを構成する方法を学習する。