G-gen の佐々木です。当記事では、Kubernetes で展開しているサービスの外部公開用 API リソースである Gateway API について、特に GKE で使用する場合における基本的な仕様を解説します。

Gateway API の概要
Gateway API は、Kubernetes でレイヤ7の高度なトラフィックルーティングを提供するための Kubernetes アドオンであり、Ingress API 同様、レイヤ7ロードバランサーをデプロイすることでバックエンドのサービスを公開することができます。
GKE における Gateway API では、GKE クラスタで使用できる Cloud Load Balancing の各種アプリケーションロードバランサーを定義、デプロイすることができます。
Ingress API との違い
Ingress からの改良点
一般的に、Kubernetes では外部公開するアプリケーションにトラフィックをルーティングしたい場合、 Ingress を使用することができます。
Gateway は Ingress よりも後発の API リソースであり、以下のような改良が加えられています。
| 改良点 | Ingress API の課題 | Gateway API の特徴 |
|---|---|---|
| ロール志向 | 1つのリソースにインフラの設定とアプリケーションのルーティング設定をまとめて定義する必要がある。そのため、インフラ担当者とアプリケーション開発者の責任範囲が曖昧になっている。 | リソース定義を Gateway(インフラ定義)、HTTPRoute(ルーティング定義) のように分割することで、インフラ担当者とアプリケーション開発者がそれぞれの担当領域(ロール)でリソースを管理できる。 |
| 移植性・表現性 | パスベース以外のルーティングなど、高度な機能はネイティブでサポートされておらず、GKE なら GKE 用の Ingress Controller が独自に定義したアノテーションを用いて実装する必要がある。 | 多くの高度な機能がネイティブでサポートされており、リソース定義がクラウドプロバイダーやオンプレミスなど環境に依存しない。 |
| Namespace 間アクセス | Ingress 単体の機能では、異なる Namespace にあるバックエンドサービスや Secret にアクセスすることができない。たとえばマイクロサービスごとに Namespace を割り当てている環境などで、1つの Ingress からそれぞれのサービスにルーティングするような構成ができない。 | Gateway は異なる Namespace のリソースにアクセスすることができる。 |
GKE における違い
GKE における Ingress では、外部アプリケーションロードバランサー向けの Ingress と、内部アプリケーションロードバランサー用の Ingress を使用することができます。前者は Cloud Load Balancing の従来の外部アプリケーションロードバランサーを、後者は内部アプリケーションロードバランサーをデプロイします。
後述するように、Gateway API では GatewayClass により、新しい世代の(「従来の」ではない)外部アプリケーションロードバランサーや、マルチクラスタで利用できるロードバランサーをデプロイすることができるようになっています。
Google Cloud の Cloud Load Balancing を利用する場合、ロードバランサーの各コンポーネントと Ingress API、Gateway API の関係は以下の図のようになっています。

Gateway API のリソース
リソースの構成
Gateway API は主に以下のリソースから構成されます。
- GatewayClass
- Gateway
- HTTPRoute

また、以下のような補助的なリソースがあります。
- Policy
- RefernceGrant
GatewayClass
Gateway から参照されるリソースで、クラスタに作成するロードバランサーのテンプレートとして機能します。GKE の場合、Google Cloud によってクラスタで利用できるロードバランサーが GatewayClass として事前定義されています。
以下は、GKE クラスタで利用可能な GatewayClass の例です。
| GatewayClass の名前 | 対応する Cloud Load Balancing のロードバランサー |
|---|---|
| gke-l7-global-external-managed | グローバル外部アプリケーションロードバランサ |
| gke-l7-regional-external-managed | リージョン外部アプリケーションロードバランサ |
| gke-l7-rilb | 内部アプリケーションロードバランサ |
| gke-l7-global-external-managed-mc | マルチクラスタ用のグローバル外部アプリケーションロードバランサ |
| gke-l7-regional-external-managed-mc | マルチクラスタ用のリージョン外部アプリケーションロードバランサ |
| gke-l7-rilb-mc | マルチクラスタ用の内部アプリケーションロードバランサ |
上記の GatewayClass の名前を Gateway のリソース定義で指定することで、対象のロードバランサーを作成することができます。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb # 内部アプリケーションロードバランサを作成する listeners: - name: http protocol: HTTP port: 80
詳細な仕様やその他の GatewayClass については、以下の公式ドキュメントもご一読ください。
Gateway
トラフィックを処理するロードバランサーの種類(GatewayClass)、プロトコル、ポート、TLS 設定などを定義します。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: external-http spec: gatewayClassName: gke-l7-global-external-managed # ロードバランサーの種類(GatewayClass) listeners: # プロトコル、ポート、TLS 設定など、リスナーの設定 - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: store-example-com
HTTPRoute
Gateway が受信したリクエストを、バックエンドの Service リソースにルーティングするためのルールを定義します。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http # ルーティング設定を紐付ける Gateway リソースの名前 hostnames: # ルーティング設定を適用するホスト名 - "store.example.com" rules: - backendRefs: # Gateway が受信したリクエストをルーティングするバックエンドサービス - name: store-v1 # Service リソースの名前 port: 8080
Policy
バックエンドサービスに対するヘルスチェックやトラフィック分散の方法、リクエストのタイムアウト、Identity-Aware Proxy や Cloud Armor バックエンドセキュリティポリシーの紐付けなどを定義します。
設定する Policy の種類によって、Policy リソースを Gateway リソースや Service リソースに対して紐付けます。
例えば以下のマニフェストファイルでは、Gateway リソースとして作成したロードバランサーに対する SSL ポリシーの紐付けが定義されています。
apiVersion: networking.gke.io/v1 kind: GCPGatewayPolicy metadata: name: my-gateway-policy namespace: team1 spec: default: sslPolicy: gke-gateway-ssl-policy # SSL ポリシーの名前 targetRef: group: gateway.networking.k8s.io kind: Gateway name: my-gateway # Policy を紐付ける Gateway リソースの名前
参考 : Configure Gateway resources using Policies
ReferenceGrant
Gateway や HTTPRoute が、異なる Namespace にあるバックエンドサービス、Secret などを参照できるようにするリソースです。
以下のマニフェストファイルは、frontend Namespace の HTTPRoute から backend Namespace の Service にトラフィックをルーティングできるような ReferenceGrant を定義しています。
apiVersion: networking.gke.io/v1 kind: ReferenceGrant metadata: name: allow-frontend-to-access-backend namespace: backend # Namespace間アクセスを許可するアクセス先のNamespace spec: from: # どこからのアクセスを許可するか - group: gateway.networking.k8s.io kind: HTTPRoute namespace: frontend to: # 何に対するアクセスを許可するか - group: "" kind: Service
Gateway API を使ってみる
サンプル構成
当記事ではサンプル構成として、nginx をバックエンドサービスとする Gateway、HTTPRoute リソースを作成していきます。Gateway には Certificate Manager で作成した Google マネージド SSL 証明書を紐づけ、Gateway で作成されたロードバランサーに HTTPS でアクセスできるようにします。

Gateway API の有効化
GKE クラスタで Gateway API が有効化されていない場合は有効化します。
# クラスタで Gateway API を有効化する $ gcloud container clusters update <GKEクラスタ名> \ --location=<クラスタのロケーション> \ --gateway-api=standard
SSL 証明書の作成
Gateway API で作成するロードバランサーで TLS を設定するために、Certificate Manager 管理の証明書を作成します。
当記事では Google マネージド SSL 証明書を使用します。
# Google マネージド SSL 証明書を作成する $ gcloud certificate-manager certificates create my-cert \ --domains="<使用するドメイン>" \ --scope=DEFAULT # 証明書マップを作成する $ gcloud certificate-manager maps create my-cert-map # 証明書マップのエントリーを作成する $ gcloud certificate-manager maps entries create [ENTRY_NAME] \ --map="my-cert-map" \ --certificates="my-cert" \ --hostname="<使用するドメイン>"
- 参考 : Manage certificates
サンプル Pod、Service のデプロイ
サンプルアプリケーションとして、以下のマニフェストを使用して nginx の Pod と Service をデプロイします。
# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx-server template: metadata: labels: app: nginx-server spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx-server ports: - protocol: TCP port: 80 targetPort: 80
Gateway のデプロイ
ロードバランサーのフロントエンドとして機能する Gateway リソースを作成します。
以下のサンプルマニフェストでは、先ほど作成した証明書を使用するグローバル外部アプリケーションロードバランサーを作成する Gateway リソースをデプロイします。
# gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: external-https-gateway annotations: networking.gke.io/certmap: "my-cert-map" # 作成した証明書マップの名前 spec: gatewayClassName: gke-l7-global-external-managed # グローバル外部アプリケーションロードバランサーを使用 listeners: - name: https-listener protocol: HTTPS port: 443
デプロイした Gateway リソースは以下のコマンドで確認できます。
# デプロイした Gateway の確認
$ kubectl get gateways
NAME CLASS ADDRESS PROGRAMMED AGE
external-https-gateway gke-l7-global-external-managed xxx.xxx.xxx.xxx True 74s
Google Cloud コンソールを確認すると、アプリケーションロードバランサーが作成されていることがわかります。

DNS レコードの設定
使用するドメインに対して、先ほど kubectl get gateways コマンドで確認したロードバランサーの外部 IP アドレスを解決できる A レコードを作成します。
以下のスクリーンショットは、Cloud DNS を使用する場合のレコードの設定例です。

HTTPRoute のデプロイ
Gateway が受信したトラフィックをバックエンドサービスにルーティングするために、HTTPRoute をデプロイします。
以下のサンプルマニフェストでは、バックエンドである nginx サービスの80番ポートにトラフィックをルーティングする HTTPRoute リソースを作成します。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nginx-http-route spec: parentRefs: - name: external-https-gateway # Gatewayリソースの名前 hostnames: - "<使用するドメイン>" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nginx-service # バックエンドの Service の名前 port: 80
デプロイした HTTPRoute リソースは以下のコマンドで確認できます。
$ kubectl get httproutes NAME HOSTNAMES AGE nginx-http-route ["<使用するドメイン>"] 13s
動作確認
作成した Gateway 関連リソースは、GKE のコンソールからも確認することができます。

それでは、使用しているドメインに対して、curl コマンドやブラウザから HTTPS でアクセスしてみます。
Gateway API で作成したアプリケーションロードバランサー経由で、HTTPS でバックエンドサービスにアクセスできています。

佐々木 駿太 (記事一覧)
G-gen 最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月に G-gen にジョイン。Google Cloud Partner Top Engineer に選出(2024 / 2025 Fellow / 2026)。好きな Google Cloud プロダクトは Cloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805