はじめに
(1年ぶりに記事を書いています...)
この記事は、Oracle Cloud Infrastructure Advent Calender 2024 シリーズ 1 Day6の記事として書いています。
久々にしては平凡?な記事ですが、OKEでGateway APIを動かしてみたので、その内容について書いていこうと思います。
Gateway APIについて
まず、Gateway APIについて軽く説明します。
Gateway APIとはKubernetesでのクラスタ外からクラスタ内へのL4/L7ロードバランサー相当の機能です。
Kubernetesでのロードバランサー機能といえば、ServiceやIngressがありますが、昨年の10月にGateway APIという新たな実装がGAになりました。
現在までに様々なベンダーによるGateway APIの実装がリリースされています。
参考までに以下のような実装があります。
- AWS Gateway API (α)(Amazon VPC Latticeを利用)
- Azure Application Gateway(GA)
- GKE Gateway(GA)
- Cilium(β)
- Istio(GA)
- NGINX Gateway Fabric(GA)
なお、OKEの実装がないのは察してください...
Gateway APIの特徴は一般的に以下と言われています。
- Roleによって、扱うべきリソースが明確に分かれている
- L4からL7プロトコルまで幅広いプロトコルをサポート(実装による)
- ServiceはL4のみ、IngressはL7のみサポートしています
- 高い拡張性と可搬性
- Ingressはアノテーション(
.metadata.annotation
)を利用してベンダー独自の仕様を取り入れていましたが、Gateway APIは標準仕様(.spec
)として様々な機能を組み込んでいる
- Ingressはアノテーション(
- リソースはIngressよりかなり数が多い(管理対象が多い)
この中で、一番特筆すべきは「Roleによって、扱うべきリソースが明確に分かれている」という特徴です。
公式ドキュメントでは以下のような図で説明されています。
参考:https://gateway-api.sigs.k8s.io/
これによって、以下のような課題を解決できます。
- ServiceやIngressを設定するのは開発者…?それともクラスタ管理者(インフラエンジニア)…??
- 開発者だとしたら、Load Balancerをボコボコ作ってしまっていいのか…?課金管理とかどうなる…??
- クラスタ管理者(インフラエンジニア)だとしたら、わざわざ開発者が連絡しないといけないの…??
Gateway APIであれば、インフラエンジニア、クラスタ管理者、アプリケーション開発者がどのリソースを扱うべきかを標準化しています。
では、早速OKE上にGatewa APIを構築してみましょう。
NGINX Gateway Fabricを利用したGateway API
ここからはGateway APIがまだ未実装なのでNGINX Gateway Fabricを利用してGateway APIをOKE上に構築していきます。
環境構築(OKE)
OKEのプロビジョニングはこちらを参考に実施してください。
Worker NodeのスペックはVM.Standard.E5.Flexシェイプで2oCPU、16GB RAM × 3 Nodeで作成してください。
こちらを参考にkustomizeもインストールしてください。
NGINX Gateway Fabricのインストール
kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.0" | kubectl apply -f -
kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/crds.yaml
kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/default/deploy.yaml
以下のリソースが作成できていれば問題ありません。
kubectl get pods -n nginx-gateway
NAME READY STATUS RESTARTS AGE
nginx-gateway-7f7748c4d9-nr94g 2/2 Running 0 6d1h
これがGateway APIの役割を果たすリバースプロキシとなるNGINXサーバです。
Gateway APIリソースのインストール
以下のManifestを作成します。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
hostname: "*.example.com"
---
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
リソースを適用します。
kubectl apply -f gateway.yaml
リソースを確認します。
kubectl describe httproutes
Name: coffee
Namespace: default
Labels: <none>
Annotations: <none>
API Version: gateway.networking.k8s.io/v1
Kind: HTTPRoute
Metadata:
Creation Timestamp: 2024-12-01T13:46:51Z
Generation: 1
Resource Version: 821
UID: cc591089-d3aa-44d3-a851-e2bbfa285029
Spec:
Hostnames:
cafe.example.com
Parent Refs:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: gateway
Section Name: http
Rules:
Backend Refs:
Group:
Kind: Service
Name: coffee
Port: 80
Weight: 1
Matches:
Path:
Type: PathPrefix
Value: /coffee
Status:
Parents:
Conditions:
Last Transition Time: 2024-12-01T13:46:51Z
Message: The route is accepted
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2024-12-01T13:46:51Z
Message: All references are resolved
Observed Generation: 1
Reason: ResolvedRefs
Status: True
Type: ResolvedRefs
Controller Name: gateway.nginx.org/nginx-gateway-controller
Parent Ref:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: gateway
Namespace: default
Section Name: http
Events: <none>
Name: tea
Namespace: default
Labels: <none>
Annotations: <none>
API Version: gateway.networking.k8s.io/v1
Kind: HTTPRoute
Metadata:
Creation Timestamp: 2024-12-01T13:46:51Z
Generation: 1
Resource Version: 823
UID: d72d2a19-1c4d-48c4-9808-5678cff6c331
Spec:
Hostnames:
cafe.example.com
Parent Refs:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: gateway
Section Name: http
Rules:
Backend Refs:
Group:
Kind: Service
Name: tea
Port: 80
Weight: 1
Matches:
Path:
Type: Exact
Value: /tea
Status:
Parents:
Conditions:
Last Transition Time: 2024-12-01T13:46:51Z
Message: The route is accepted
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2024-12-01T13:46:51Z
Message: All references are resolved
Observed Generation: 1
Reason: ResolvedRefs
Status: True
Type: ResolvedRefs
Controller Name: gateway.nginx.org/nginx-gateway-controller
Parent Ref:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: gateway
Namespace: default
Section Name: http
Events: <none>
リソースを確認します。
kubectl describe gateway
Name: gateway
Namespace: default
Labels: <none>
Annotations: <none>
API Version: gateway.networking.k8s.io/v1
Kind: Gateway
Metadata:
Creation Timestamp: 2024-12-01T13:46:36Z
Generation: 1
Resource Version: 824
UID: 2ae8ec42-70eb-41a4-b249-3e47177aea48
Spec:
Gateway Class Name: nginx
Listeners:
Allowed Routes:
Namespaces:
From: Same
Hostname: *.example.com
Name: http
Port: 80
Protocol: HTTP
Status:
Addresses:
Type: IPAddress
Value: 10.244.0.5
Conditions:
Last Transition Time: 2024-12-01T13:46:51Z
Message: Gateway is accepted
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2024-12-01T13:46:51Z
Message: Gateway is programmed
Observed Generation: 1
Reason: Programmed
Status: True
Type: Programmed
Listeners:
Attached Routes: 2
Conditions:
Last Transition Time: 2024-12-0113:46:51Z
Message: Listener is accepted
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2024-12-01T13:46:51Z
Message: Listener is programmed
Observed Generation: 1
Reason: Programmed
Status: True
Type: Programmed
Last Transition Time: 2024-12-01T13:46:51Z
Message: All references are resolved
Observed Generation: 1
Reason: ResolvedRefs
Status: True
Type: ResolvedRefs
Last Transition Time: 2024-12-01T13:46:51Z
Message: No conflicts
Observed Generation: 1
Reason: NoConflicts
Status: False
Type: Conflicted
Name: http
Supported Kinds:
Group: gateway.networking.k8s.io
Kind: HTTPRoute
Group: gateway.networking.k8s.io
Kind: GRPCRoute
Events: <none>
サンプルアプリケーションのインストール
以下のDeploymentとServiceを作成します。
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
リソースを適用します。
kubectl apply -f app.yaml
以下のPodが作成されています。
kubectl -n default get pods
NAME READY STATUS RESTARTS AGE
coffee-6db9sdd495b-wk2mm 1/1 Running 0 12s
tea-7b7d6de47d-d4qcf 1/1 Running 0 11s
動作確認
作成した環境を動かしてみます。
curl --resolve cafe.example.com:8080:127.0.0.1 http://cafe.example.com:8080/coffee
Server address: 10.244.0.6:8080
Server name: coffee-6db9sdd495b-wk2mm
Date: 5/Dec/2024:13:52:13 +0000
URI: /coffee
Request ID: fb226a5s45g4f927b484dd31fb30e747
curl --resolve cafe.example.com:8080:127.0.0.1 http://cafe.example.com:8080/tea
Server address: 10.244.0.7:8080
Server name: tea-7b7d6de47d-d4qcf
Date: 5/Dec/2024:13:55:26 +0000
URI: /tea
Request ID: 43882f2f5794a1ee05dr5a017a035ce3
こんな感じでアクセスできます。
挙動はIngressとほぼ同じですが、Gateway APIでは重み付けルーティングやB/GデプロイなどのIngressやServiceではできなかった様々なルーティング方式を実現できます。
おわりに
今回は簡単にGateway APIをOKEで動かしてみました!
他にも様々なことができますが、それはまた別に機械に記事化できればと思います。
今回ご紹介したGateway APIを含めてKubernetesでのトライックルーティングの解説をこちらでお話しするので、お時間がある方はぜひご参加ください。