Kong GatewayはAPIのGatewayとして流量制御や認証認可に使われるが、サービスのメトリクスを取得するのにも使うことが出来る。
これを利用すると、Prometheus向けのメトリクスを実装していないアプリケーションのメトリクスも取得することが出来るため、レガシーなアプリケーションの監視集約などにも利用することが出来る。
今回はこれを試してみる。
なお、ここでの検証構成は以下のような構成とする。
Prometheus/GrafanaをKong GWと同居させた方が楽だが、あまりリアリティがない感じがするのでクラスタを分けて確認する。
なお、KubernetesにはvSphere with Tanzu(Kubernetes:v1.25.7)を利用し、type: LoadBalancer
が利用できる環境で試している。
Kong Gateway、Prometheus/Grafanaの構築方法はそれぞれ過去に書いたこことここの方法で構築し、Kong Gateway構築時にあわせてKong Ingress Controller(以下KIC)も構築している。
構築に不安がある人はそれぞれのリンクを参照して確認するとよい。
Kong Promethues Plugin
Kong単体でもメトリクスを表示することは出来るが、メトリクスの表示項目を増やしたりProxyしたサービスのメトリクスを取得するにはPrometheus Pluginを利用する必要がある。
Prometheus PluginはKong Gatewayの中に内包されており、Kong Gatewayの中でメンテナンスされている。
これを利用するとざっくりと以下のメトリクスを確認する事が出来る。
- KongのDBに対するリーチャビリティ
- nginx
- DataPlaneノードの状態
- ライセンス情報
- DBのエンティティ数(※Enterprise版のみ)
- サービスごとの各種情報(デフォルトでは無効)
- HTTPステータスコード
- レイテンシ
- 帯域幅
- ヘルスチェック
今回はこの中で「サービスごとの各種情報」を確認していく。
準備
Prometheus Pluginの導入
Prometheus Pluginの導入方法はいくつかあるが、ここではKICのカスタムリソースを使って導入する。
KICを導入するとPluginをKubernetesのリソースとして定義できるようになり、Manifestを適用することでPluginを追加することが出来る。
ここではクラスタ単位で導入できるkind: KongClusterPlugin
を使ってPrometheus Pluginを導入してみる。
利用時の注意点は以下となる。
-
spec
がなく、plugin
で使用するプラグインを定義し、config
でプラグインの設定を定義する -
metadata.labels
にglobal: true
を書かないとKong GatewayのGlobal Pluginとして扱われない - AnnotationでKICの
IngressClass
を明示する(kubernetes.io/ingress.class: <IngressClass>名
を書く)必要がある
Annotationの制約については記載されている箇所が見つからなかったのだが、動作検証している際に省くとプラグインが認識されなかったので必須だと思われる。
以下を実行してPluginを適用する。
cat <<EOF | kubectl apply -f -
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: prometheus
annotations:
kubernetes.io/ingress.class: kong
labels:
global: "true"
config:
status_code_metrics: true
bandwidth_metrics: true
upstream_health_metrics: true
latency_metrics: true
per_consumer: false
plugin: prometheus
EOF
なお、Prometheus Pluginの設定の説明はここでは省いている。
必要に応じてPrometheus Configurationで確認するとよい。
カスタムリソースの仕様上、適用しても上手く適用されているかどうかはkubectl
では確認できないため、deck
やKong ManagerのUIから確認する。
ここではdeck
で確認する。
export DECK_KONG_ADDR=https://kong-admin.10-214-154-169.nip.io
export DECK_TLS_SKIP_VERIFY=true
deck gateway dump | yq eval '.plugins'
出力結果は以下となった。
- config:
bandwidth_metrics: true
latency_metrics: true
per_consumer: false
status_code_metrics: true
upstream_health_metrics: true
enabled: true
name: prometheus
protocols:
- grpc
- grpcs
- http
- https
tags:
- k8s-name:prometheus
- k8s-kind:KongClusterPlugin
- k8s-uid:bea56d0b-ab98-489d-87ab-649f9355c047
- k8s-group:configuration.konghq.com
- k8s-version:v1
- managed-by-ingress-controller
適切に入っているようだ。
Kong Gatewayのスクレイピング
PrometheusをPrometheus Operatorでデプロイした場合、外部のサービスのスクレイピング設定を追加で行う場合はAdditional Scrape Configuration
を使って既存リソースの構成を変更せずに外部からSecret
で設定するか、kind: ScrapeConfig
で新しいKubernetesリソースを定義して追加する方法がある。
(※同一クラスタ内のサービスのスクレイピングならkind: ServiceMonitor
を使うが、今回はクラスタを分けているため対象外)
ここでは後者のScrapeConfig
を使った方法で追加する。
Prometheus OperatorでデプロイされたPrometheusはkind: Prometheus
として定義されており、Prometheus
オブジェクト内のspec.scrapeConfigSelector
でどのScrapeConfig
をスクレイプするかのルールが設定されているので確認する。
$ kubectl get prometheus -n prometheus-stack prometheus-stack-kube-prom-prometheus -o yaml | yq eval .spec.scrapeConfigSelector
matchLabels:
release: prometheus-stack
上記の場合はrelease: prometheus-stack
をラベルに指定する必要がある。
以下が今回スクレイプのために適用するScrapeConfig
のManifestとなる。
KONG_METRICS=kong-admin.10-214-154-169.nip.io/metrics
cat <<EOF > ./scrape-kong.yaml
apiVersion: monitoring.coreos.com/v1alpha1
kind: ScrapeConfig
metadata:
name: scraping-kong
labels:
release: prometheus-stack
spec:
metricsPath: /metrics
scheme: HTTPS
tlsConfig:
insecureSkipVerify: true
staticConfigs:
- labels:
job: kong-gateway
targets:
- $KONG_METRICS
EOF
Kong GatewayをTLS化して立てているのでHTTPSとしてスクレイピングするよう設定しているが、HTTPで立てている場合はscheme
をHTTP
にしてtlsConfig
を削除する。
これを適用するとPrometheus側で自動で設定変更してくれる。
kubectl apply -f ./scrape-kong.yaml
設定適用後、最大で1分程度待てば以下のようにPrometheusのTargetsにエンドポイントが表示されるようになる。
Expression browserからも確認できる。
GrafanaでダッシュボードでKongのメトリクスを可視化
次にメトリクスの可視化を行う。
オフィシャルのダッシュボードがここで配布されているのでこれを使う。
Grafanaにログインし、左サイドバーのDashboards
からNew
->Import
を選択する。
ここでダッシュボード配布先のID7424
を入力し、Loadをクリックする。
LoadされたらdatasourceにPrometheusを選択してImport
をクリックする。
すると、それぞれのメトリクスのためのダッシュボードが利用できるようになる。
配布されているダッシュボードでは上記のように以下の6つの項目についてダッシュボードが用意される。
- リクエストレート
- レイテンシ
- 帯域幅
- キャッシュ
- Upstream
- Nginx
なお、Prometheusの仕組み上、メトリクスが発生しないとそのメトリクスは出てこないので、動作確認する場合は実際にサービスにアクセスするなどしてメトリクスが生成されるイベントを起こしてから確認する必要がある。
検証
KICを導入している時にkind: Ingress
リソースを作成するとKICのWebhookが動作して自動でGateway Serviceを作成してくれる。
これを使って適当なサービスを作成して公開し、そこにアクセスした時のメトリクスがGrafanaで見れるか確認する。
動作確認に利用したものは以下となる。
cat <<'EOF' > ./game-2048.yaml
apiVersion: v1
kind: Namespace
metadata:
name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: game-2048
name: deployment-2048
spec:
selector:
matchLabels:
app.kubernetes.io/name: app-2048
replicas: 3
template:
metadata:
labels:
app.kubernetes.io/name: app-2048
spec:
containers:
- image: alexwhen/docker-2048
name: app-2048
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: game-2048
name: service-2048
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
selector:
app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
konghq.com/protocols: "https"
namespace: game-2048
name: ingress-2048
spec:
ingressClassName: kong
rules:
- host: 2048-game.10.214.154.169.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-2048
port:
number: 80
tls:
- secretName: game-2048-tls
hosts:
- 2048-game.10.214.154.169.nip.io
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: game-2048-ca
namespace: game-2048
spec:
commonName: "*.10.214.154.169.nip.io"
secretName: game-2048-tls
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
EOF
Ingress
のAnnotationにkonghq.com/protocols: "https"
をつけなくてもGateway Serviceは作成されるが、これをつけないとHTTPとして作成されるので、HTTPSで作成されるように指定した。(Annotationの説明はこちら)
Manifestを適用するとKong ManagerからGateway Serviceが以下のように確認できる。
このサイトにwatch
コマンドで定期的にアクセスしてみる。
watch curl -s -k https://2048-game.10.214.154.169.nip.io/
1,2分経ってGrafanaで見ると、アクセスが確認できる。
以上により、サービスのメトリクスをスクレイピングしなくてもメトリクスを取得できることが確認できた。
また、サービスディスカバリについてもKICが担保することで、Prometheus側の設定変更なしで追従出来ることも確認できた。