LoginSignup
0
0

Kong Gatewayの通信の遅延箇所をJaegerで確認する

Last updated at Posted at 2024-05-25

Kong GatewayにはOpenTelemetry Pluginが用意されていて、これを使うとアプリの改変やMeshへの追加なしで以下のようなトレースを取得することが出来る。
20240525132205.png

これを使うとレイテンシが大きい場合に以下のどこに問題があるかが確認できるようになる。

  • クライアント->Kong Gateway
  • Kong Gateway内
  • Kong Gateway->アプリケーション

この記事はOpenTelemetry Pluginの設定方法を確認した時のメモ。

検証環境

以下の環境で検証した。

  • KubernetesはEKS
  • Kong Ingress Controller(KIC)は導入済み
  • Kong Gatewayは構築済み
  • cert-managerは導入済み

KIC、Kong Gateway、cert-managerについてはこちらの記事の内容で構築したものを利用した。

Kong Gatewayの設定変更

Kong Gatewayに設定を加えないとトレースがエンドポイントに転送されないため、最初に設定変更を行う。
OpenTelemetry Pluginのこちらの説明に従い、tracing_instrumentationstracing_sampling_rateをKong Gatewayに設定する。
Helmのvalues.yamlに以下を追加してupgradeする。

env:
  tracing_instrumentations: all
  tracing_sampling_rate: 1.0

upgradeのコマンドは以下。

helm upgrade -i -f kong-values.yaml kong kong/kong -n kong

設定が反映されているかはKong ManagerにログインしてInfo(右上のi)をクリックし、Config DetailsView Full Configurationから確認できる。
20240525134034.png

Jaegerのインストール

Jaegerの構築方法はいくつかあるが、ここではJaeger Operatorで構築する。
まずJaeger Operatorをインストールする。

helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
helm upgrade -i jaeger-operator jaegertracing/jaeger-operator -n observability --create-namespace --set rbac.clusterRole=true

なお、私の環境ではOperatorが以下のエラーを吐いてJaegerリソースを作成しようとしても上手く行かなかった。

failed to list *v1.IngressClass: ingressclasses.networking.k8s.io is forbidden: User "system:serviceaccount:observability:jaeger-operator" cannot list resource "ingressclasses" in API group "networking.k8s.io" at the cluster scope

そのため以下のClusterRoleを作成し、Podを再起動した。

cat <<EOF > ./rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: jaeger-operator-ingress-class
rules:
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingressclasses"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jaeger-operator-ingress-class-binding
subjects:
  - kind: ServiceAccount
    name: jaeger-operator
    namespace: observability
roleRef:
  kind: ClusterRole
  name: jaeger-operator-ingress-class
  apiGroup: rbac.authorization.k8s.io
EOF
kubectl apply -f ./rbac.yaml
kubectl delete pod --all -n observability

Ingressを使ったJaegerを作成するために、Issuerで証明書を作成できるようにする。

MY_EMAIL=hogehoge@hogehoge.com
cat <<EOF > ./issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  labels:
    app: certmanager-issuer
    chart: certmanager-issuer-0.1.0
  name: jaeger-issuer
  namespace: observability
spec:
  acme:
    email: $MY_EMAIL
    privateKeySecretRef:
      name: jaeger-acme-key
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
    - http01:
        ingress:
          class: kong
EOF
kubectl apply -f ./issuer.yaml

Jaegerリソースを作成する。

MYHOST=xxx.hogehoge.com
cat <<EOF > ./jaeger.yaml
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: jaeger
  namespace: observability
spec:
  ingress:
    hosts:
    - jaeger.$MYHOST
    ingressClassName: kong
    enabled: true
    tls:
    - hosts:
      - jaeger.$MYHOST
      secretName: jaeger-cert
    annotations:
      kubernetes.io/tls-acme: "true"
      cert-manager.io/issuer: "jaeger-issuer"
EOF
kubectl apply -f ./jaeger.yaml

Ingressで設定したホスト名にアクセスするとJaegerのUIが確認できる。
20240524181058.png

サンプルアプリケーションのデプロイとService/Routeの作成

次にテストに使うサンプルアプリケーション(nginx)をデプロイし、サンプルアプリに到達するためのKong GatewayのService/Routeを作成する。
なお、KICを使ってIngressを作れば自動的にService/Routeは生成されるため、今回はIngressの作成=Service/Routeの作成となる。
以下のManifest(Deployment, Service, Issuer, Ingress)を作成する。

Manifest(クリックして表示)
nginx.yaml
cat <<EOF > ./nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: ClusterIP
  selector:
    app: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/issuer: nginx-issuer
    kubernetes.io/tls-acme: "true"
  name: nginx
spec:
  ingressClassName: kong
  rules:
    - host: nginx.eks.$MYHOST
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name:  nginx
                port:
                  number: 80
  tls:
  - secretName: nginx-general-tls
    hosts:
    - nginx.eks.$MYHOST
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: nginx-issuer
spec:
  acme:
    email: $MY_EMAIL
    privateKeySecretRef:
      name: nginx-acme-key
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
    - http01:
        ingress:
          class: kong
EOF

デプロイする。

kubectl create ns nginx-sample
kubectl apply -f ./nginx.yaml -n nginx-sample

Ingressのホスト名にブラウザでアクセスすれば、以下のようにnginxの初期画面が確認できる。
20240525141547.png
また、Kong ManagerからService/Routeが作成されていることも確認できる。
20240525141936.png

OpenTelemetry Pluginの導入

Kong GatewayにOpenTelemetry Pluginを導入してトレースを取得・転送する。
ここではKong Managerから設定し、Pluginの対象は先程作ったRouteに限定するものとする。
先程作成されたnginxのRouteを選択し、PluginsからNew Pluginを選択する。
Plugin選択の画面に遷移するので、OpenTelemetry Pluginを選択する。

picture 5

選択すると設定画面に遷移するので、以下の設定を入力してSaveする。

  • Endpoint: http://jaeger-collector.observability.svc:4318/v1/traces
  • Resource Attributes: { "service.name": "nginx" }

Endpointについては同一クラスタ内で展開しているので直接Serviceを参照した。Ingressのホスト名を使って参照したい場合、今回Jaeger OperatorでデプロイしたJaegerのIngressではOTEL用のPort(4318)向けのパスが存在していないので注意。
Resource AttributesについてはAdd Config.Resource Attributesをクリックして以下のように入力する。
20240525144018.png

以上で設定は完了となる。

動作確認

nginxに公開しているIngressのホスト名でアクセスする。

curl -X GET https://$(kubectl get ing nginx -n nginx-sample -o jsonpath={.spec.rules[].host})

Jaegerを見てみる。
ログインするとSearchServiceのところにOpenTelemetry Pluginのservice.nameで設定した名前のServiceが確認できる。

picture 7

選択してFind Tracesを選択し、表示された検索結果をクリックするとトレースが確認できる。
20240525145239.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0