あけましておめでとうございます。本年はアウトプットの数を増やすという目標のもと、さっそくブログの更新をする。 年末年始は友人・家族と会えたし、飲みすぎないようにしたおかげで溜まってた本の解消やBLEACH全巻読んだりと充実できた。

去年、学んだk8sのGateway APIについて記事を書く。

Gateway APIとは

Gateway APIは動的なインフラストラクチャの展開と高度なトラフィックルーティングを提供するAPIの種類のファミリーです。

とのこと。これだけだとわかりにくいが、要はk8sへの通信を担うLBをコード化して自動管理しようっていう認識であっていると思う。詳しくは、以下リンクでk8sやGCPの公式ドキュメントをみると理解が深まると思う。特に、GCPのドキュメントは具体的にどのリソースと紐づくのがわかりやすいので、GCPを知っている人はこっちを読むのをおすすめする。

https://kubernetes.io/ja/docs/concepts/services-networking/gateway/
https://docs.cloud.google.com/kubernetes-engine/docs/concepts/gateway-api?hl=ja

きっかけ

学んだきっかけは、会社でGKE StandardからAutopilot移行をしたときに、Autopilotクラスタが利用可能なすべてのゾーンにNEGが作成されていない状態で、手動でLBを作成すると障害になるケースがある。 という事象を発見したから。移行時の話は以下リンクから見れるので興味ある方は見てほしい。

所属している会社のアドベントカレンダーを書いた2025

さわってみた

Gateway APIはk8sのマニフェストファイルを増やすことで実装できる。 kustomizeを利用する前提でディレクトリ構成を以下に記載する。GCPの場合は、LB作成時に必要なフロント、バック、ヘルスチェック、バックに登録するNEGをそれぞれ表現しているイメージを持ってもらうのがわかりやすそう。 また、GKEのPodでNginxを立てている想定でサンプルは実装している。

k8s/
└── base/
    ├── configmap.yaml
    ├── deployment.yaml
    ├── gateway.yaml
    ├── healthcheck.yaml
    ├── httproute.yaml
    ├── kustomization.yaml
    └── service.yaml

Gateway APIに関係している実装は、gateway.yaml, healthcheck.yaml, httproute.yaml, service.yamlなので、それぞれサンプル実装を記載して解説をする。

gateway.yaml

kind: Gateway では利用するLBの種類やトラフィックをリッスンする場所と方法などの設定ができる。 addressesは予約したIPを指定して利用することもできる。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: nginx
  namespace: default
spec:
  gatewayClassName: gke-l7-rilb  # Regional Internal Load Balancer
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
  addresses:
    - type: NamedAddress
      value: nginx

healthcheck.yaml

これはLB作成時に必要なヘルスチェック。

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: nginx
  namespace: default
spec:
  default:
    config:
      type: HTTP
      httpHealthCheck:
        requestPath: /health/?from=lb
        port: 80
    checkIntervalSec: 10
    timeoutSec: 5
    healthyThreshold: 1
    unhealthyThreshold: 3
  targetRef:
    group: ""
    kind: Service
    name: nginx

httproute.yaml

HTTPRoute では、Gateway が受信した HTTP リクエストと HTTPS リクエストを Service に転送する方法を定義している。 L7レベルのルーティングをここで定義できる。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: nginx
  namespace: default
spec:
  parentRefs:
  - name: nginx
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: nginx
      port: 80

service.yaml

GKEの場合は、NEGを自動作成するアノテーションを付与して作成しておけば、いい感じにルーティングしてくれるようになる。

kind: Service
apiVersion: v1
metadata:
  name: nginx
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80

結果

これらを実行すると、GCP上にLBが作成される。注意点として、作成されるリソース名はすべてハッシュ値のようなランダムの値になっているため、コンソール画面などで一覧でみたときにぱっとみどのLBがどのアプリに紐付いているか分かりづらい。よりきれいな運用をするなら、ここらへんはもうちょっと調べる必要がある。(結果の画像があった方がわかりやすいが、めんどくさかったので省略した。)

感想

定義するだけで、かんたんにすぐLBが作れて非常に便利だった。GCPでLBを作成するときは4,5つのリソースをgcloudコマンドで作成する必要があったような気がするので以外とめんどくさい。それに、コード化をしておけば、再現しやすく横展開もしやすいので、IaCは基本的にやったほうがいい。