あけましておめでとうございます。本年はアウトプットの数を増やすという目標のもと、さっそくブログの更新をする。 年末年始は友人・家族と会えたし、飲みすぎないようにしたおかげで溜まってた本の解消や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を作成すると障害になるケースがある。 という事象を発見したから。移行時の話は以下リンクから見れるので興味ある方は見てほしい。
さわってみた
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は基本的にやったほうがいい。