🌐

GKE Gateway で Internal LB を構築する

2023/10/07に公開

概要

前回の記事で GKE において Gateway API を利用した API のデプロイまでを行いました。
https://zenn.dev/tetsuya28/articles/gke-gateway-intro

今回は Gateway を Internal LB として利用する方法について検証していきます。

Internal Gateway とは

GKE Gateway には Internal で利用出来る gke-l7-rilb が用意されています。

Gateway の他の class については以下の記事をご覧ください。

https://cloud.google.com/kubernetes-engine/docs/how-to/gatewayclass-capabilities?hl=ja

構築

事前準備

Internal Gateway を利用するにはプロキシ専用サブネットを構築する必要があります。

詳細は以下のドキュメントをご覧ください。

https://cloud.google.com/load-balancing/docs/proxy-only-subnets?hl=ja#proxy_only_subnet_create

プロキシ専用サブネットはリージョンごとに 1 つ、推奨されているサブネットサイズは /23 なので以下の設定でプロキシ専用サブネットを構築します。

プロキシ専用サブネットは RFC 1918 を満たす必要はないですが、今回は CIDR が空いていたので Class C を利用しています。

resource "google_compute_subnetwork" "proxy" {
  name          = "proxy"
  network       = google_compute_network.default.name
  purpose       = "REGIONAL_MANAGED_PROXY"
  role          = "ACTIVE"
  ip_cidr_range = "192.168.0.0/23"
}

Internal Gateway のデプロイ

続いて Internal Gateway を以下のマニフェストを用いてデプロイします。

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: internal
spec:
  gatewayClassName: gke-l7-rilb
  listeners:
    - name: http
      protocol: HTTP
      port: 80

暫くすると Internal LB が作成されます。

現時点では、まだバックエンドをデプロイしていないため 404 が返ってくることが確認出来ます。

$ curl -i http://10.0.0.10
HTTP/1.1 404 Not Found
content-length: 18
content-type: text/plain
date: Sun, 09 Apr 2023 01:29:21 GMT
via: 1.1 google

fault filter abor

Internal Gateway への HTTP Route のデプロイ

先ほどデプロイした Internal Gateway をバックエンドと紐付けるため以下の HTTP Route をデプロイします。

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store-external
spec:
  parentRefs:
  - kind: Gateway
    name: internal
  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

デプロイ後、ロードバランサに設定が反映されると Internal Gateway 経由でリクエストが出来ることが確認出来ました。

$ curl -i http://10.0.0.10
HTTP/1.1 200 OK
server: Werkzeug/2.2.2 Python/3.10.9
date: Sun, 09 Apr 2023 01:33:23 GMT
content-type: application/json
content-length: 354
access-control-allow-origin: *
via: 1.1 google

{
  "cluster_name": "tetsuya28",
  "gce_instance_id": "836092675233726340",
  "gce_service_account": "tetsuya28.svc.id.goog",
  "host_header": "10.0.0.10",
  "metadata": "store-v1",
  "pod_name": "store-v1-84c89967f8-bbpcq",
  "pod_name_emoji": "⛈️",
  "project_id": "tetsuya28",
  "timestamp": "2023-04-09T01:33:23",
  "zone": "asia-northeast1-b"
}

Discussion