KubernetesでJaegerを使用して分散トレースを実装する方法

提供:Dev Guides
移動先:案内検索

著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

Kubernetes とそれが可能にするマイクロサービスアーキテクチャは、非常に効率的でスケーラブルなシステムを作成できます。 ただし、これらのマイクロサービスの1つでパフォーマンスの問題が発生すると、問題が発生します。 通常、顧客対応サービスからの応答時間がますます長くなっていることに最初に気づきます。 問題は、バックエンドサービスの1つ、または最適な容量を超えているデータベースにある可能性があります。 問題の根本を発見するには、分散トレースを実装する必要があります。

Jaegerは、分散トレースソリューションであり、Cloud NativeComputingFoundationのインキュベーションプロジェクトを卒業しています。 トレースを視覚化するための快適なUI、トレースを収集するための Jaegerサイドカー、およびその他のいくつかのコンポーネントを備えています。 Jaegerのような分散トレースシステムでは、顧客が生成した各イベントのライフサイクルをトレースし、各サービスがそのイベントをどのように処理するかを確認できます。

このチュートリアルでは、非常に小さな分散アプリケーションをKubernetesクラスターにデプロイし、コードのスリープ関数を使用してパフォーマンスラグをシミュレートします。 この問題の根本原因を特定し、各イベントを追跡するには、Jaegerを使用します。 トレースを有効にすると、サービスの動作を観察し、問題を特定するのにどれほど効果的かがわかります。

前提条件

始める前に、次のツールとアカウントが必要になります。

ステップ1—サンプルアプリケーションの構築

Jaegerのトレース機能をテストするために、フロントエンド用とバックエンド用の2つのサービスを使用するサンプルアプリケーションsammy-jaegerをビルドしてデプロイします。 PythonFlaskマイクロフレームワークの両方を使用してビルドします。

私たちのアプリケーションは、フロントエンドを呼び出すたびに値が増加するヒットカウンターになります。 パフォーマンスの問題をシミュレートするために、フロントエンドがGETリクエストをバックエンドに送信するたびに実行されるランダム化されたスリープ関数をコーディングします。 このステップでは、そのアプリケーションをビルドしてデプロイします。 次の手順では、アプリをKubernetesにデプロイし、Jaegerをインストールしてから、それを使用してサービスの問題を追跡します。

まず、プロジェクトディレクトリ構造を作成し、内部をナビゲートしましょう。

mkdir -p ./sammy-jaeger/frontend ./sammy-jaeger/backend && cd ./sammy-jaeger

これで、ルートディレクトリsammy-jaegerと2つのサブディレクトリができました。

output.
├── backend
└── frontend

また、ルートディレクトリ/sammy-jaegerに変更しました。 ここから残りのすべてのコマンドを実行します。

フロントエンドアプリケーションの構築を始めましょう。

フロントエンドアプリケーションの構築

お好みのテキストエディタを使用して、./frontendfrontend.pyという名前の新しいファイルを作成して開きます。

nano ./frontend/frontend.py

次のコードを追加します。 これにより、Flaskがインポートされ、カウンター関数が作成され、HTTPリクエストのルートが1つ定義されます。

./frontend/frontend.py

import os
import requests
from flask import Flask
app = Flask(__name__)

def get_counter(counter_endpoint):
    counter_response = requests.get(counter_endpoint)
    return counter_response.text

def increase_counter(counter_endpoint):
    counter_response = requests.post(counter_endpoint)
    return counter_response.text

@app.route('/')
def hello_world():
    counter_service = os.environ.get('COUNTER_ENDPOINT', default="https://localhost:5000")
    counter_endpoint = f'{counter_service}/api/counter'
    counter = get_counter(counter_endpoint)

    increase_counter(counter_endpoint)

    return f"""Hello, World!

You're visitor number {counter} in here!\n\n"""

3つのモジュールをインポートしています。 osモジュールはオペレーティングシステムと通信します。 requests モジュールは、HTTPリクエストを送信するためのライブラリです。 Flask は、アプリをホストするマイクロフレームワークです。

次に、get_counter()関数とincrease_counter()関数を定義します。これらの関数は、どちらもパラメーターcounter_endpointを受け入れます。 get_counter()は、GETメソッドを使用してバックエンドを呼び出し、現在のカウンター状態を見つけます。 increase_counter()は、POSTメソッドを使用してバックエンドを呼び出し、カウンターをインクリメントします。

次に、ルート/を定義します。これにより、hello_world()という別の関数が呼び出されます。 この関数は、バックエンドポッドのURLとポートを取得し、それを変数に割り当ててから、その変数を最初の2つの関数get_counter()increase_counter()に渡します。バックエンドへのX192X]およびPOSTリクエスト。 その後、バックエンドはランダムな期間(シミュレートされたラグ)一時停止してから、現在のカウンター番号をインクリメントし、その番号を返します。 最後に、hello_world()はこの値を取り、「HelloWorld!」を出力します。 新しい訪問者数を含むコンソールへの文字列。

Python環境を作成しておらず、ローカルマシンにpipをインストールしていないことに気付いたかもしれません。 Dockerを使用してアプリケーションをコンテナー化するときに、これらの手順を完了します。

frontend.pyを保存して閉じます。

次に、フロントエンドアプリケーション用のDockerfileを作成します。 このDockerfileには、コンテナ化された環境を構築するために必要なすべてのコマンドが含まれています。

./frontendで新しいDockerfileを作成して開きます。

nano ./frontend/Dockerfile

次のコンテンツを追加します。

./frontend/Dockerfile

FROM alpine:3.8

RUN apk add --no-cache py3-pip python3 && \
    pip3 install flask requests

COPY . /usr/src/frontend

ENV FLASK_APP frontend.py

WORKDIR /usr/src/frontend

CMD flask run --host=0.0.0.0 --port=8000

このDockerfileでは、ベースの AlpineLinuxイメージからビルドするようにイメージに指示します。 次に、Python3、pip、およびいくつかの追加の依存関係をインストールします。 次に、アプリケーションのソースコードをコピーし、メインのアプリケーションコードを指す環境変数を設定し、作業ディレクトリを設定し、イメージからコンテナーを作成するたびにFlaskを実行するコマンドを記述します。

ファイルを保存して閉じます。

次に、フロントエンドアプリケーション用のDockerイメージをビルドし、DockerHubのリポジトリにプッシュします。

まず、DockerHubにサインインしていることを確認します。

docker login --username=your_username --password=your_password

イメージを作成します。

docker build -t your_username/do-visit-counter-frontend:v1 ./frontend

次に、イメージをDockerHubにプッシュします。

docker push your_username/do-visit-counter-frontend:v1

これで、フロントエンドアプリケーションがビルドされ、DockerHubで利用できるようになりました。 ただし、Kubernetesにデプロイする前に、バックエンドアプリケーションをコーディングしてビルドしましょう。

バックエンドアプリケーションの構築

バックエンドアプリケーションには、フロントエンドと同じ手順が必要です。

まず、./backendbackend.pyというファイルを作成して開きます。

nano ./backend/backend.py

次のコンテンツを追加します。これにより、2つの関数と別のルートが定義されます。

./backend/backend.py

from random import randint
from time import sleep

from flask import request
from flask import Flask
app = Flask(__name__)

counter_value = 1

def get_counter():
    return str(counter_value)

def increase_counter():
    global counter_value
    int(counter_value)
    sleep(randint(1,10))
    counter_value += 1
    return str(counter_value)

@app.route('/api/counter', methods=['GET', 'POST'])
def counter():
    if request.method == 'GET':
        return get_counter()
    elif request.method == 'POST':
        return increase_counter()

randomsleepを含むいくつかのモジュールをインポートしています。 次に、カウンター値を1に設定し、2つの関数を定義します。 最初のget_counterは、counter_valueとして格納されている現在のカウンター値を返します。 2番目の関数increase_counterは、2つのアクションを実行します。 カウンター値を1ずつインクリメントし、sleepモジュールを使用して、関数の完了をランダムな時間だけ遅らせます。

バックエンドには、POSTGETの2つのメソッドを受け入れる1つのルート(/api/counter)もあります。 GETメソッドを使用してこのルートを呼び出すと、get_counter()が呼び出され、カウンター値が返されます。 POSTメソッドを使用してこのルートを呼び出すと、increase_counter()が呼び出され、ランダムな時間待機しながらカウンターの値が増加します。

ファイルを保存して閉じます。

バックエンドアプリケーションにも独自のDockerfileが必要です。これは、フロントエンドのバージョンとほぼ同じです。

./backendに2番目のDockerfileを作成して開きます。

nano ./backend/Dockerfile

次のコンテンツを追加します。 ここでの主な違いの1つは、ファイルパス以外に、ポートです。

./backend/Dockerfile

FROM alpine:3.8

RUN apk add --no-cache py3-pip python3 && \
    pip3 install flask

COPY . /usr/src/backend

ENV FLASK_APP backend.py

WORKDIR /usr/src/backend

CMD flask run --host=0.0.0.0 --port=5000

ファイルを保存して閉じます。

次に、イメージを作成します。

docker build -t your_username/do-visit-counter-backend:v1 ./backend

DockerHubにプッシュします。

docker push your_username/do-visit-counter-backend:v1

Docker Hubでアプリケーションを利用できるようになったので、アプリケーションをクラスターにデプロイして、次のステップでテストする準備が整いました。

ステップ2—アプリケーションのデプロイとテスト

コードの記述とコンテナーの公開は、最初の主要なステップでした。 次に、Kubernetesにデプロイして、基本的なアプリケーションをテストする必要があります。 その後、Jaegerを追加して、分散トレースの可能性を探ることができます。

展開とテストを始めましょう。

この時点で、ディレクトリツリーは次のようになります。

.
├── backend
│   ├── Dockerfile
│   └── backend.py
└── frontend
    ├── Dockerfile
    └── frontend.py

このアプリケーションをクラスターにデプロイするには、2つのKubernetesマニフェストも必要です。 アプリケーションの半分ごとに1つ。

./frontendで新しいマニフェストファイルを作成して開きます。

nano ./frontend/deploy_frontend.yaml

次のコンテンツを追加します。 このマニフェストは、Kubernetesが Deployment を構築する方法を指定します(強調表示されたセクションをDocker Hubのユーザー名に置き換えることを忘れないでください)。

./frontend/deploy_frontend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: do-visit-counter-frontend
  labels:
    name: do-visit-counter-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: do-visit-counter-frontend
  template:
    metadata:
      labels:
        app: do-visit-counter-frontend
    spec:
      containers:
        - name: do-visit-counter-frontend
          image: your_dockerhub_username/do-visit-counter-frontend:v1
          imagePullPolicy: Always
          env:
            - name: COUNTER_ENDPOINT
              value: "http://do-visit-counter-backend.default.svc.cluster.local:5000"
          ports:
            - name: frontend-port
              containerPort: 8000
              protocol: TCP

Kubernetesを指定して、デプロイをビルドし、do-visit-counter-frontendという名前を付け、DockerHubのフロントエンドイメージを使用して1つのレプリカをデプロイします。 また、アプリケーションの2つの半分をリンクするために、COUNTER_ENDPOINTという名前の環境変数を構成しました。

ファイルを保存して閉じます。

次に、./backendでバックエンドアプリケーションのマニフェストを作成します。

nano ./backend/deploy_backend.yaml

次のコンテンツを追加し、強調表示されたセクションをDockerHubのユーザー名に置き換えます。

./backend/deploy_backend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: do-visit-counter-backend
  labels:
    name: do-visit-counter-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: do-visit-counter-backend
  template:
    metadata:
      labels:
        app: do-visit-counter-backend
    spec:
      containers:
        - name: do-visit-counter-backend
          image: your_dockerhub_username/do-visit-counter-backend:v1
          imagePullPolicy: Always
          ports:
            - name: backend-port
              containerPort: 5000
              protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
    name: do-visit-counter-backend
spec:
    selector:
        app: do-visit-counter-backend
    ports:
        - protocol: TCP
          port: 5000
          targetPort: 5000

このマニフェストでは、バックエンドのデプロイメントとサービスを定義しています。 デプロイメントでは、コンテナーの実行方法と実行内容について説明します。 ポートがフロントエンドの8000からバックエンドの5000に変更されていることに注意してください。 このサービスでは、フロントエンドからバックエンドへのクラスター間接続が可能です。

ファイルを保存して閉じます。

次に、kubectlを使用してカウンターをクラスターにデプロイしましょう。 フロントエンドから始めます。

kubectl apply -f ./frontend/deploy_frontend.yaml

次に、バックエンドをデプロイします。

kubectl apply -f ./backend/deploy_backend.yaml

すべてが機能していることを確認するには、kubectl get podsを呼び出します。

kubectl get pods

次のような出力が表示されます。

OutputNAME                                         READY   STATUS    RESTARTS   AGE
do-visit-counter-backend-79f6964-prqpb       1/1     Running   0          3m
do-visit-counter-frontend-6985bdc8fd-92clz   1/1     Running   0          3m

すべてのポッドをREADY状態にする必要があります。 まだ準備ができていない場合は、数分待ってから前のコマンドを再実行してください。

最後に、アプリケーションを使用します。 これを行うには、クラスターからポートを転送してから、curlコマンドを使用してフロントエンドと通信します。 転送ポートは1つのウィンドウをブロックするため、必ず2番目のターミナルウィンドウを開いてください。

kubectlを使用して、ポートを転送します。

kubectl port-forward $(kubectl get pods -l=app="do-visit-counter-frontend" -o name) 8000:8000

次に、2番目のターミナルウィンドウで、フロントエンドアプリケーションに3つのリクエストを送信します。

for i in 1 2 3; do curl localhost:8000; done

curlを呼び出すたびに、訪問数が増加します。 次のような出力が表示されます。

OutputHello, World!

You're visitor number 1 in here!

Hello, World!

You're visitor number 2 in here!

Hello, World!

You're visitor number 3 in here!

ビジターカウンターは正常に機能していますが、各応答の間に遅延があることに気付いたと思います。 これは、パフォーマンスラグをシミュレートしているスリープ機能の結果です。

分散アプリケーションの準備ができたら、Jaegerをインストールしてこれらのイベントを追跡します。

ステップ3—Jaegerをデプロイする

トレースを収集して視覚化することは、イエーガーの得意分野です。 このステップでは、Jaegerをクラスターにデプロイして、パフォーマンスの遅れを検出できるようにします。

Jaegerの公式ドキュメントには、JaegerOperatorをインストールするためのコマンドが含まれています。 また、ツールを機能させるためにデプロイする必要のある4つの追加のマニフェストも含まれています。 今それをやってみましょう:

まず、イエーガーオペレーターが必要とするカスタムリソース定義を作成します。 Jaegerの公式ドキュメントで入手可能な推奨テンプレートを使用します。

kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml

次に、ロールベースのアクセス制御サービスアカウントロール、およびロールバインディングを作成します。

kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml

最後に、JaegerOperatorをデプロイします。

kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml

オペレーター自体は、イエーガーが働いているという意味ではありません。 ここで、カスタムリソース定義が役立ちます。 オペレーターに管理させたいJaegerインスタンスを説明するリソースを作成する必要があります。 繰り返しになりますが、Jaegerの公式ドキュメントに記載されている手順に従います。

ヒアドキュメントを使用して、コマンドラインからこのリソースを作成します。

kubectl apply -f - <<EOF
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simplest
EOF

ENTERを押してリソースを作成します。

次に、デプロイメントを再度確認します。

kubectl get pods

Jaegerオペレーターとsimplestデプロイメントの出力が表示されます。

OutputNAME                                                   READY   STATUS    RESTARTS   AGE
do-visit-counter-backend-79f6964-prqpb                 1/1     Running   0          3m
do-visit-counter-frontend-6985bdc8fd-92clz             1/1     Running   0          3m
jaeger-operator-547567dddb-rxsd2                       1/1     Running   0          73s
simplest-759cb7d586-q6x28                              1/1     Running   0          42s

Jaegerが正しく機能していることを検証するために、そのポートを転送して、UIにアクセスできるかどうかを確認しましょう。

kubectl port-forward $(kubectl get pods -l=app="jaeger" -o name) 16686:16686

ブラウザを開き、http://localhost:16686に移動します。 JaegerUIが読み込まれます。

アプリケーションとJaegerの両方が機能しています。 次のステップでは、Jaegerがデータを収集し、パフォーマンスの遅れを見つけるためのインストルメンテーションを追加します。

ステップ4—インストルメンテーションの追加

JaegerをKubernetesで使用すると多くのタスクが自動化されますが、アプリケーションにインストルメンテーションを手動で追加する必要があります。 幸い、そのタスクを処理するためのFlask-OpenTracingモジュールがあります。

OpenTracingは、分散トレースの標準の1つです。 これは、他のトレースツールもサポートすることを目的として、Jaegerの作成者によって提案されました。 ベンダーに依存せず、さまざまなプログラミング言語と一般的なフレームワークをサポートします。

すべてのOpenTracing実装の場合と同様に、Jaeger構成を追加し、トレースするエンドポイントにトレースデコレータを追加して、元のアプリケーションを変更する必要があります。

フロントエンドコードにFlask-OpenTracingを追加しましょう。

.frontend.pyを再度開きます:

nano ./frontend/frontend.py

次に、OpenTracingを埋め込む次の強調表示されたコードを追加します。

./frontend/frontend.py

import os
import requests
from flask import Flask
from jaeger_client import Config
from flask_opentracing import FlaskTracing

app = Flask(__name__)
config = Config(
    config={
        'sampler':
        {'type': 'const',
         'param': 1},
                        'logging': True,
                        'reporter_batch_size': 1,}, 
                        service_name="service")
jaeger_tracer = config.initialize_tracer()
tracing = FlaskTracing(jaeger_tracer, True, app)

def get_counter(counter_endpoint):
    counter_response = requests.get(counter_endpoint)
    return counter_response.text

def increase_counter(counter_endpoint):
    counter_response = requests.post(counter_endpoint)
    return counter_response.text

@app.route('/')
def hello_world():
    counter_service = os.environ.get('COUNTER_ENDPOINT', default="https://localhost:5000")
    counter_endpoint = f'{counter_service}/api/counter'
    counter = get_counter(counter_endpoint)

    increase_counter(counter_endpoint)

    return f"""Hello, World!

You're visitor number {counter} in here!\n\n"""

ファイルを保存して閉じます。 Flask OpenTracing構成の詳細については、GitHubページをご覧ください。

次に、バックエンドアプリケーションコードを開きます。

nano ./backend/backend.py

強調表示されたコードを追加します。 これは、frontend.pyに配置したものと同じコードです。

./backend/backend.py

from random import randint
from time import sleep

from flask import Flask
from flask import request
from jaeger_client import Config
from flask_opentracing import FlaskTracing


app = Flask(__name__)
config = Config(
    config={
        'sampler':
        {'type': 'const',
         'param': 1},
                        'logging': True,
                        'reporter_batch_size': 1,}, 
                        service_name="service")
jaeger_tracer = config.initialize_tracer()
tracing = FlaskTracing(jaeger_tracer, True, app)

counter_value = 1

def get_counter():
    return str(counter_value)

def increase_counter():
    global counter_value
    int(counter_value)
    sleep(randint(1,10))
    counter_value += 1
    return str(counter_value)

@app.route('/api/counter', methods=['GET', 'POST'])
def counter():
    if request.method == 'GET':
        return get_counter()
    elif request.method == 'POST':
        return increase_counter()

ファイルを保存して閉じます。

ライブラリを追加するため、両方のサービスのDockerfilesも変更する必要があります。

フロントエンドのDockerfileを開きます。

nano ./frontend/Dockerfile

強調表示されたコードを追加します。

./frontend/Dockerfile

FROM alpine:3.8

RUN apk add --no-cache py3-pip python3 && \
    pip3 install flask requests Flask-Opentracing jaeger-client

COPY . /usr/src/frontend

ENV FLASK_APP frontend.py

WORKDIR /usr/src/frontend

CMD flask run --host=0.0.0.0 --port=8000

ファイルを保存して閉じます。

次に、バックエンドのDockerfileを開きます。

nano ./backend/Dockerfile

強調表示されたコードを追加します。

./backend/Dockerfile

FROM alpine:3.8

RUN apk add --no-cache py3-pip python3 && \
    pip3 install flask Flask-Opentracing jaeger-client

COPY . /usr/src/backend

ENV FLASK_APP backend.py

WORKDIR /usr/src/backend

CMD flask run --host=0.0.0.0 --port=5000

これらの変更により、コンテナの新しいバージョンを再構築してプッシュしたいと考えています。

フロントエンドアプリケーションをビルドしてプッシュします。 最後にあるv2タグに注意してください。

docker build -t your_username/do-visit-counter-frontend:v2 ./frontend
docker push your_username/do-visit-counter-frontend:v2

次に、バックエンドアプリケーションをビルドしてプッシュします。

docker build -t your_username/do-visit-counter-backend:v2 ./backend
docker push your_username/do-visit-counter-backend:v2

分散トレースシステムには、最後の1つが必要です。Jaegerサイドカーをアプリケーションポッドに挿入して、ポッドからのトレースをリッスンし、Jaegerサーバーに転送します。 そのためには、マニフェストにアノテーションを追加する必要があります。

フロントエンドのマニフェストを開きます。

nano ./frontend/deploy_frontend.yaml

強調表示されたコードを追加します。 また、画像をv2バージョンに置き換えていることに注意してください。 その行を修正して、DockerHubのユーザー名を追加してください。

./frontend/deploy_frontend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: do-visit-counter-frontend
  labels:
    name: do-visit-counter-frontend
  annotations:
    "sidecar.jaegertracing.io/inject": "true"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: do-visit-counter-frontend
  template:
    metadata:
      labels:
        app: do-visit-counter-frontend
    spec:
      containers:
        - name: do-visit-counter-frontend
             image: your_dockerhub_username/do-visit-counter-frontend:v2
          imagePullPolicy: Always
          env:
            - name: COUNTER_ENDPOINT
              value: "http://do-visit-counter-backend.default.svc.cluster.local:5000"
          ports:
            - name: frontend-port
              containerPort: 8000
              protocol: TCP

このアノテーションは、Jaegerサイドカーをポッドに挿入します

ファイルを保存して閉じます。

次に、バックエンドのマニフェストを開きます。

nano ./backend/deploy_backend.yaml

このプロセスを繰り返し、強調表示された行を追加してJaegerサイドカーを挿入し、画像タグを更新します。

./backend/deploy_backend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: do-visit-counter-backend
  labels:
    name: do-visit-counter-backend
  annotations:
    "sidecar.jaegertracing.io/inject": "true"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: do-visit-counter-backend
  template:
    metadata:
      labels:
        app: do-visit-counter-backend
    spec:
      containers:
        - name: do-visit-counter-backend
             image: your_dockerhub_username/do-visit-counter-backend:v2
          imagePullPolicy: Always
          ports:
            - name: backend-port
              containerPort: 5000
              protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
    name: do-visit-counter-backend
spec:
    selector:
        app: do-visit-counter-backend
    ports:
        - protocol: TCP
          port: 5000
          targetPort: 5000

新しいマニフェストを配置したら、それらをクラスターに適用して、ポッドが作成されるのを待つ必要があります。

古いリソースを削除しましょう:

kubectl delete -f ./frontend/deploy_frontend.yaml
kubectl delete -f ./backend/deploy_backend.yaml

そしてそれらを交換します:

kubectl apply -f ./frontend/deploy_frontend.yaml
kubectl apply -f ./backend/deploy_backend.yaml

今回のアプリケーションのポッドは、アプリケーション用とJaegerサイドカー用の2つのコンテナで構成されます。

kubectlを使用して、これを確認します。

kubectl get pods

アプリケーションポッドは、READY列に2/2と表示されるようになりました。

OutputNAME                                                   READY   STATUS    RESTARTS   AGE
jaeger-operator-547567dddb-rxsd2                       1/1     Running   0          23m
simplest-759cb7d586-q6x28                              1/1     Running   0          22m
do-visit-counter-backend-694c7db576-jcsmv              2/2     Running   0          73s
do-visit-counter-frontend-6d7d47f955-lwdnf             2/2     Running   0          42s

サイドカーとインストルメンテーションを配置したら、プログラムを再実行して、JaegerUIでトレースを調査できます。

ステップ5—イエーガーの痕跡を調査する

これで、トレースのメリットを享受できます。 ここでの目標は、Jaeger UIを調べて、パフォーマンスの問題となる可能性のある呼び出しを確認することです。 もちろん、UIにいくつかのトレースを表示したい場合は、最初にアプリケーションを使用してデータを生成する必要があります。

2番目と3番目のターミナルウィンドウを開いてこれを設定しましょう。 2つのウィンドウを使用してJaegerとアプリケーションをポート転送し、3つ目のウィンドウを使用してcurlを介してマシンからフロントエンドにHTTPリクエストを送信します。

最初のウィンドウで、フロントエンドサービスのポートを転送します。

kubectl port-forward $(kubectl get pods -l=app="do-visit-counter-frontend" -o name) 8000:8000

2番目のウィンドウで、Jaegerのポートを転送します。

kubectl port-forward $(kubectl get pods -l=app="jaeger" -o name) 16686:16686

3番目のウィンドウで、ループでcurlを使用して、10個のHTTP要求を生成します。

for i in 0 1 2 3 4 5 6 7 8 9; do curl localhost:8000; done

以前のような出力が表示されます。

OutputHello, World!

You're visitor number 1 in here!

Hello, World!

You're visitor number 2 in here!

. . .

Hello, World!

You're visitor number 10 in here!

これにより、視覚化でそれらを比較するのに十分な異なるデータポイントが得られます。

ブラウザを開き、http://localhost:16686に移動します。 サービスドロップダウンメニューをサービスに設定し、制限結果30に変更します。 トレースの検索を押します。

アプリケーションからのトレースがグラフに表示されます。

ここでは、サービスへの呼び出しが異なれば実行時間が異なることがわかります。 Jaegerは、アプリケーションが情報を処理するのにかかる時間と、どの関数が最も貢献しているかを追跡しました。 スリープ関数の結果として、hello_world()関数が完了するまでにかかる時間が非常に変動することに注意してください。 これは非常に疑わしいことであり、調査に集中する場所を提供してくれます。 Jaegerは、分散アプリケーション内のパフォーマンスリークを効果的に視覚化しました。

トレースを実装し、Jaeger UIを使用することで、不規則な応答時間の原因を見つけることができました。

結論

この記事では、Jaegerを使用して分散トレースシステムをセットアップし、小さなアプリケーションにインストルメンテーションを追加しました。 これで、他のワークロードをクラスターにデプロイし、Jaegerサイドカーを注入して、さまざまなサービスがどのように相互作用し、どの操作に最も時間がかかっているかを確認できます。

複数のサービスを使用するアプリケーションのパフォーマンスのボトルネックを見つけることは、分散トレースを使用するとはるかに高速になります。 ただし、この例は、イエーガーの可能性のほんの一部を示しています。 より複雑な実稼働環境では、Jaegerを使用してさまざまなトレースを比較し、パフォーマンスリークを実際にドリルダウンできます。 Jaegerが生成できる複雑な視覚化は非常に印象的で、非常に便利です。 Jaegerがクラスターのパフォーマンスの問題を監視および解決するのにどのように役立つかについて詳しくは、公式ドキュメントをご覧ください。