✨
Kubernetes Gateway API 入門
ちょうど1年前にGAとなったKubernetesのGateway APIを触る機会がなかったので、個人的に理解を深めるようと思います。
Gateway API とは?
L4とL7ルーティングを担う次世代のKubernetes Ingress、Load Balancing、Service Mesh APIsです。汎用的で表現力があり役割が分離できるように設計されています。
- 役割指向
Kubernetesのサービスネットワークの利用と設定を行う組織の役割を表現したAPIリソースによって構成されています - 移植性
Ingressが多数の実装を持つ普遍的な仕様であるのと同様にGateway APIは多くの実装によってサポートされる移植可能な仕様となるように設計されています。 - 表現性
Gateway APIリソースはヘッダーベースのマッチングやトラフィックの重み付けなど以前はIngressのカスタムアノテーションを通じてのみ可能だったコア機能をサポートしています。 - 拡張性
Gateway APIはさまざまなAPIレイヤーにカスタムリソースをリンクすることを可能にします。これによりAPI構造内の適切な場所で詳細なカスタマイズが可能になります。
一旦、ローカルで動かす
-
MicroK8sをインストール
https://microk8s.io/docs/install-macos -
MetalLBを有効
$ microk8s enable metallb:192.168.64.241-192.168.64.250
- 今回はローカルなのでGateway controllerとしてNGINX Gateway Fabricをインストール
https://github.com/nginxinc/nginx-gateway-fabric
$ 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
提供されているリソース
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 上にビルドされたグローバル外部アプリケーション ロードバランサ
- gke-l7-global-external-managed グローバル外部アプリケーション ロードバランサ上にビルドされたグローバル外部アプリケーション ロードバランサ
- 最初に動かした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
- https://gateway-api.sigs.k8s.io/api-types/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/
- 異なるNamespaceのGatewayに接続できる
https://gateway-api.sigs.k8s.io/ - HTTPRoute
- https://gateway-api.sigs.k8s.io/api-types/httproute/
- リダイレクト、Pathの置換、URLの書き換え、HTTPヘッダーの追加、重み付け、リクエストのミラーリング
- GRPCRoute
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/
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での状況
- GKE、Azure、IstioはGA
- EKSはalpha
GKE
GKE Gateway Controllerを利用する
EKS
Amazon VPC LatticeリソースをプロビジョニングするAWS Gateway API Controllerを利用する
https://aws.amazon.com/
Istio
Kubernetes 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