本記事は「Kong Advent Calendar 2024」の3日目のエントリとして、KonnectでKong Ingress Controllerを利用する方法について解説する。
Kong Ingress Controller(KIC)はKong Gatewayの各種エンティティ(ServiceやRouteなど)をKubernetesのIngressと融合して使うような事が出来るIngress Controllerであり、例えばIngressでサービスを公開すると、Ingress内のrules
の記載に基づいて自動的にKong Gateway内にRouteやServiceを作成してくれる。
このKIC、デプロイモードとしてDBありモードとDBなしモードが存在する。
ざっくりとした違いは以下になる。
DBありモード | DBなしモード | |
---|---|---|
構成の保存先 | DB | クラスタのetcd |
宣言的アプローチでの変更 | deckを使用 | Kubernetes Manifestを使用 |
構成 | 何でもあり | Hybridモード不可 |
DBなしモードの場合はDBのメンテナンスは不要になる一方でアーキテクチャの制約が強く、完全に新規で利用する場合に検討候補となる構成となる。
話が少しそれたが、言いたかったのはどちらの構成もデータをクラスタに持たせる構成になっている。
ではクラウド側にデータを持っているKonnectを使った場合はどうなるか、が本日の趣旨となる。
公式ドキュメントではKong Ingress Controller for Kubernetes Associationで説明しているあたりになる。
KonnectでのKICの利用
KonnectではGateway Manager(ControlPlane)の作成時にKICを選択することでKonnect+KICの構成が組めるようになっている。
特徴としては以下となる。
- Konnectは可視化用のダッシュボードとなり、ServiceやRouteなどの作成が出来ない
- ServiceやRouteはKubernetesのIngressリソースを介して作成する
- DataPlaneや通信の状態をダッシュボードから可視化可能
3番目の特徴はKICでなくても見れるので特筆する程のものでもないのだが、Kubernetes利用時に可視化を行おうとするとPrometheus/Grafanaのようなものの導入がデファクトとなるため、その点は少し楽が出来ると言える。
検証
構築から疎通確認
ここでは検証としてEKS上にKICを構築してKonnectと繋いでみる。
Konnectにログインし、Gateway Manager
からNew Gateway
を選択する。
すると選択肢にKubernetes Ingress Controllerがあるのでこれを選択してGatewayを作成する。
次にDataPlaneのデプロイ画面に遷移するのでDataPlanを作成する。
検証目的なのでここでは特に値などは変更せず、表示されたコマンドをそのまま実行する。
kubectl create namespace kong
helm repo add kong https://charts.konghq.com
helm repo update
kubectl create secret tls konnect-client-tls -n kong --cert=/tmp/tls.crt --key=/tmp/tls.key
helm install kong kong/ingress -n kong --values /tmp/values.yaml
自動で画面上の状態がアップデートされないようなので、デプロイが終わったらDataPlaneのページからConnectedになっていることを確認する。
なおOverviewでは以下のようにFully Operationalと表示されていればOK。
クラスタ側では2つのPodがデプロイされる。
$ kubectl get pod -n kong
NAME READY STATUS RESTARTS AGE
kong-controller-f745fd46f-s8hlp 1/1 Running 0 22m
kong-gateway-7bcccc668-t2q2r 1/1 Running 0 22m
KIC本体とProxyがデプロイされており、ProxyのServiceはtype: LoadBalancer
によって公開され、Ingress使用時はこのIPを利用することになる。
$ kubectl get svc -n kong
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kong-controller-validation-webhook ClusterIP 10.100.248.128 <none> 443/TCP 23m
kong-gateway-admin ClusterIP None <none> 8444/TCP 23m
kong-gateway-manager NodePort 10.100.170.74 <none> 8002:30662/TCP,8445:32409/TCP 23m
kong-gateway-proxy LoadBalancer 10.100.154.216 a3904a8cc45d7413f895dfe87162cd5f-xxxxx.us-east-1.elb.amazonaws.com 80:31015/TCP,443:31328/TCP 23m
KICは正常にデプロイで来たので、適当にIngressをデプロイしてみる。
ここではKuardを利用してデプロイする。
最初にNamespace、Service、Deploymentをデプロイする。
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: demo
---
apiVersion: v1
kind: Service
metadata:
name: kuard
namespace: demo
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
selector:
app: kuard
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kuard
namespace: demo
spec:
replicas: 1
selector:
matchLabels:
app: kuard
template:
metadata:
labels:
app: kuard
spec:
containers:
- name: kuard
image: gcr.io/kuar-demo/kuard-amd64:1
ports:
- containerPort: 8080
EOF
次にIngressをデプロイする。IngressClass
はKIC展開時にあわせてkong
という名前でデプロイ済みであるため、これを指定する。
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kuard
namespace: demo
spec:
ingressClassName: kong
rules:
- host: kuard.hogehoge.info
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kuard
port:
number: 80
EOF
デプロイするとKonnectの方でServiceとRouteが作成されたことが確認できる。
kuardにアクセス後、KonnectのRouteやServiceの画面からアクセス状況が可視化できていることも確認できる。
なお、Ingressの設定が適切でなくIngress経由で上手く通信できなくなると、以下のようにOverviewのKIC Detailsが警告っぽい画面になる。
この画面は例えば今作成したIngressのspec.rules.http.paths.backend.service.name
をkuard
からkuard-wrong
のように存在しないServiceを指定すると簡単に確認できる。
deckのYAMLを使ってIngressを作成
Kong Gatewayをある程度使っている人はdeck
というCLIで構築や設定をYAMLで書いていることも多いと思う。
KICの場合、Ingressリソースに置き換える必要があるが、既存のdeckのYAMLをKubernetesのManifestに変換する方法が用意されているのでこれも確かめておく。
以下にサンプルのdeck用YAMLを用意した。
_format_version: "3.0"
_konnect:
control_plane_name: simple-nginx
services:
- host: nginx.hogehoge.info
name: simple-nginx
path: /
port: 80
protocol: http
routes:
- name: route_route
methods:
- GET
paths:
- /simple-nginx
これをKICに持ち込んでみる。
deckにはdeck file kong2kic
という変換コマンドがあるのでこれを利用する。
deck file kong2kic -s /tmp/nginx-deck.yaml -o /tmp/nginx-ingress.yaml --ingress
引数に--ingress
をつけないとGateway APIのkind: HTTPRoute
に変換されるので注意。
変換後のIngressのManifestのspecは以下のようになった。
spec:
ingressClassName: kong
rules:
- http:
paths:
:(省略)
---
ホスト名が欠落していたため、元のdeck用YAMLのRouteにもホストを指定するよう修正して再実行した。
routes:
- name: route_route
hosts:
- nginx.hogehoge.info
methods:
- GET
paths:
- /simple-nginx
確認したところ、今度はホスト名が反映された。
spec:
ingressClassName: kong
rules:
- host: nginx.hogehoge.info
http:
paths:
:(省略)
変換したManifestをデプロイする。
kubectl apply -f /tmp/nginx-ingress.yaml -n default
所感
KIC+Konnectを使うとOut of Boxでメトリクス等を可視化出来るのは嬉しいし、Ingressが利用可能かの状態を見てくれるのも嬉しい。
特にIngressの状態はkubectl get ing
とかでは問題が起きているかどうか確認出来ないので、これはKIC+Konnectの強みだと思う。
一方で、UIから操作が出来ないことやdeckが使えないことはかなり辛い。
deckについては今回紹介したdeck file kong2kic
でカバー出来る部分はあるが、検証時にホスト名を書き換えたりしたなど、変換後のManifestを確認せずに使用するには少しリスクがありそうだ。
自身の組織でどのようにKong Gatewayを使うかによって合う合わないが大きそうなので、利用する際はユースケース等を整理してから使うのが良さそうである。