Kubernetes Gateway API 入門

2024/10/31に公開

ちょうど1年前にGAとなったKubernetesのGateway APIを触る機会がなかったので、個人的に理解を深めるようと思います。
https://kubernetes.io/blog/2023/10/31/gateway-api-ga/

Gateway API とは?

L4とL7ルーティングを担う次世代のKubernetes Ingress、Load Balancing、Service Mesh APIsです。汎用的で表現力があり役割が分離できるように設計されています。

  • 役割指向
    Kubernetesのサービスネットワークの利用と設定を行う組織の役割を表現したAPIリソースによって構成されています
  • 移植性
    Ingressが多数の実装を持つ普遍的な仕様であるのと同様にGateway APIは多くの実装によってサポートされる移植可能な仕様となるように設計されています。
  • 表現性
    Gateway APIリソースはヘッダーベースのマッチングやトラフィックの重み付けなど以前はIngressのカスタムアノテーションを通じてのみ可能だったコア機能をサポートしています。
  • 拡張性
    Gateway APIはさまざまなAPIレイヤーにカスタムリソースをリンクすることを可能にします。これによりAPI構造内の適切な場所で詳細なカスタマイズが可能になります。

一旦、ローカルで動かす

$ microk8s enable metallb:192.168.64.241-192.168.64.250
$ microk8s kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.4.0" | microk8s kubectl apply -f -
$ microk8s helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway
$ microk8s kubectl get all -n nginx-gateway
NAME                                            READY   STATUS    RESTARTS   AGE
pod/ngf-nginx-gateway-fabric-5b7b64f6f6-c7wvx   2/2     Running   0          19m

NAME                               TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)                      AGE
service/ngf-nginx-gateway-fabric   LoadBalancer   10.152.183.235   192.168.64.241   80:30142/TCP,443:30348/TCP   19m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ngf-nginx-gateway-fabric   1/1     1            1           19m

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ngf-nginx-gateway-fabric-5b7b64f6f6   1         1         1       19m

  • nginxのデモアプリを起動
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coffee
spec:
  replicas: 1
  selector:
    matchLabels:
      app: coffee
  template:
    metadata:
      labels:
        app: coffee
    spec:
      containers:
      - name: coffee
        image: nginxdemos/nginx-hello:plain-text
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: coffee
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tea
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tea
  template:
    metadata:
      labels:
        app: tea
    spec:
      containers:
      - name: tea
        image: nginxdemos/nginx-hello:plain-text
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: tea
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: tea

  • Gatewayを作成
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    hostname: "*.example.com"
  • HTTPRouteを作成
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: coffee
spec:
  parentRefs:
  - name: gateway
    sectionName: http
  hostnames:
  - "cafe.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /coffee
    backendRefs:
    - name: coffee
      port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tea
spec:
  parentRefs:
  - name: gateway
    sectionName: http
  hostnames:
  - "cafe.example.com"
  rules:
  - matches:
    - path:
        type: Exact
        value: /tea
    backendRefs:
    - name: tea
      port: 80
  • 接続
$ curl --resolve cafe.example.com:80:192.168.64.241 http://cafe.example.com:80/coffee
Server address: 10.1.254.71:8080
Server name: coffee-6b8b6d6486-kxhm5
Date: 30/Oct/2024:21:06:36 +0000
URI: /coffee
Request ID: a35746d2041a4e10098e4c598218ea32
$ curl --resolve cafe.example.com:80:192.168.64.201 http://cafe.example.com:80/tea
Server address: 10.1.254.72:8080
Server name: tea-9d8868bb4-8wz8b
Date: 30/Oct/2024:21:08:41 +0000
URI: /tea
Request ID: 2c2b7bc8b033b3cc5ee9185ccec9a949

提供されているリソース

https://gateway-api.sigs.k8s.io/concepts/api-overview/

GatewayClass

  • https://gateway-api.sigs.k8s.io/api-types/gatewayclass/
  • Gatewayの共通の設定や振る舞いを定義
  • 各GatewayClassは単一のコントローラーによって処理されるが、コントローラーは複数の GatewayClassを処理できる
  • GatewayClassはクラスタスコープのリソース
  • 基本的にGateway APIを実装するコントローラー側が提供
  • EKS
    • amazon-vpc-lattice
  • GKE
    • gke-l7-global-external-managed グローバル外部アプリケーション ロードバランサ上にビルドされたグローバル外部アプリケーション ロードバランサ
      gke-l7-regional-external-managed リージョン外部アプリケーション ロードバランサ上にビルドされたリージョン外部アプリケーション ロードバランサ
      gke-l7-rilb 内部アプリケーション ロードバランサ上にビルドされた内部アプリケーション ロードバランサ
      gke-l7-gxlb 従来のアプリケーション ロードバランサ上にビルドされたグローバル外部アプリケーション ロードバランサ
      gke-l7-global-external-managed-mc グローバル外部アプリケーション ロードバランサ上にビルドされたマルチクラスタ グローバル外部アプリケーション ロードバランサ
      gke-l7-regional-external-managed-mc グローバル外部アプリケーション ロードバランサ上にビルドされたマルチクラスタ リージョン外部アプリケーション ロードバランサ
      gke-l7-rilb-mc 内部アプリケーション ロードバランサ上にビルドされたマルチクラスタ内部アプリケーション ロードバランサ
      gke-l7-gxlb-mc 従来のアプリケーション ロードバランサ上にビルドされたマルチクラスタ グローバル外部アプリケーション ロードバランサ
      gke-td マルチクラスタの Traffic Director サービス メッシュ
      asm-l7-gxlb Anthos Service Mesh 上にビルドされたグローバル外部アプリケーション ロードバランサ
  • 最初に動かしたNGINX Gateway FabricのGatewayClass
$ microk8s kubectl get gatewayclasses.gateway.networking.k8s.io nginx -o yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  annotations:
    meta.helm.sh/release-name: ngf
    meta.helm.sh/release-namespace: nginx-gateway
  creationTimestamp: "2024-10-30T20:44:03Z"
  generation: 1
  labels:
    app.kubernetes.io/instance: ngf
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: nginx-gateway-fabric
    app.kubernetes.io/version: 1.4.0
    helm.sh/chart: nginx-gateway-fabric-1.4.0
  name: nginx
  resourceVersion: "1132"
  uid: 542abb55-b076-4015-81f7-babe1681156e
spec:
  controllerName: gateway.nginx.org/nginx-gateway-controller
status:
  conditions:
  - lastTransitionTime: "2024-10-30T20:44:12Z"
    message: GatewayClass is accepted
    observedGeneration: 1
    reason: Accepted
    status: "True"
    type: Accepted
  - lastTransitionTime: "2024-10-30T20:44:12Z"
    message: Gateway API CRD versions are supported
    observedGeneration: 1
    reason: SupportedVersion
    status: "True"
    type: SupportedVersion

Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    hostname: "*.example.com"

Routes(HTTPRoute、TLSRoute、GRPCRoute、TCPRoute、UDPRoute)

  • リクエストをマッピングするためのプロトコル固有のルールを定義


https://gateway-api.sigs.k8s.io/

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: coffee
spec:
  parentRefs:
  - name: gateway
    sectionName: http
  hostnames:
  - "cafe.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /coffee
    backendRefs:
    - name: coffee
      port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tea
spec:
  parentRefs:
  - name: gateway
    sectionName: http
  hostnames:
  - "cafe.example.com"
  rules:
  - matches:
    - path:
        type: Exact
        value: /tea
    backendRefs:
    - name: tea
      port: 80

組織の役割を表現したAPIリソース

各役割に対してきめ細かな権限付与ができるように設計されている

https://gateway-api.sigs.k8s.io/

https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/
https://gateway-api.sigs.k8s.io/concepts/security-model/

Gateway API for Service Mesh

  • RouteリソースをServiceに直接関連付けることもできる
kind: HTTPRoute
metadata:
  name: smiley-route
  namespace: faces
spec:
  parentRefs:
    - name: smiley
      kind: Service
      group: core
      port: 80
  rules:
    ...
    timeouts:
      request: 100ms

Ingressから移行すべきか

Gateway API は Ingress API を置き換えますか?
いいえ。Ingress API は Kubernetes 1.19 以降 GA です。この API を廃止する予定はなく、ほとんどの Ingress コントローラーがこの API を無期限にサポートすると予想されます。

Ingress APIがなくなるわけではないので、ルーティングの制御やリソースベースの権限管理などのモチベーションがあるなら移行する

2024/10/31での状況

https://gateway-api.sigs.k8s.io/implementations

  • GKE、Azure、IstioはGA
  • EKSはalpha

GKE

GKE Gateway Controllerを利用する
https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api?hl=ja

EKS

Amazon VPC LatticeリソースをプロビジョニングするAWS Gateway API Controllerを利用する

https://aws.amazon.com/
https://aws.amazon.com/jp/vpc/lattice/
https://www.gateway-api-controller.eks.aws.dev/latest/
https://www.eksworkshop.com/docs/networking/vpc-lattice/gateway-api-controller
https://aws.amazon.com/jp/blogs/news/introducing-aws-gateway-api-controller-for-amazon-vpc-lattice-an-implementation-of-kubernetes-gateway-api/

Istio

Kubernetes Gateway APIに準拠した実装が提供されている
https://istio.io/latest/docs/tasks/traffic-management/ingress/gateway-api/

---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
  namespace: istio-ingress
spec:
  gatewayClassName: istio
  listeners:
  - name: default
    hostname: "*.example.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http
  namespace: default
spec:
  parentRefs:
  - name: gateway
    namespace: istio-ingress
  hostnames: ["httpbin.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix

Discussion