KubernetesでJaegerを使用して分散トレースを実装する方法
著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Kubernetes とそれが可能にするマイクロサービスアーキテクチャは、非常に効率的でスケーラブルなシステムを作成できます。 ただし、これらのマイクロサービスの1つでパフォーマンスの問題が発生すると、問題が発生します。 通常、顧客対応サービスからの応答時間がますます長くなっていることに最初に気づきます。 問題は、バックエンドサービスの1つ、または最適な容量を超えているデータベースにある可能性があります。 問題の根本を発見するには、分散トレースを実装する必要があります。
Jaegerは、分散トレースソリューションであり、Cloud NativeComputingFoundationのインキュベーションプロジェクトを卒業しています。 トレースを視覚化するための快適なUI、トレースを収集するための Jaegerサイドカー、およびその他のいくつかのコンポーネントを備えています。 Jaegerのような分散トレースシステムでは、顧客が生成した各イベントのライフサイクルをトレースし、各サービスがそのイベントをどのように処理するかを確認できます。
このチュートリアルでは、非常に小さな分散アプリケーションをKubernetesクラスターにデプロイし、コードのスリープ関数を使用してパフォーマンスラグをシミュレートします。 この問題の根本原因を特定し、各イベントを追跡するには、Jaegerを使用します。 トレースを有効にすると、サービスの動作を観察し、問題を特定するのにどれほど効果的かがわかります。
前提条件
始める前に、次のツールとアカウントが必要になります。
- 接続構成が
kubectl
デフォルトとして設定されているKubernetes1.15+クラスター。 DigitalOceanでKubernetesクラスタを作成するには、Kubernetesクイックスタートをお読みください。 クラスタに接続するには、DigitalOceanKubernetesクラスタに接続する方法をお読みください。 - Dockerがインストールされています。 手順については、Dockerをインストールして使用する方法に関するチュートリアルに従ってください。 DockerのWebサイトには、macOSやWindowsなどの他のオペレーティングシステムのインストール手順が記載されています。
- Dockerイメージを保存するためのDockerHubのアカウント。
kubectl
コマンドラインツールがローカルマシンにインストールされ、クラスターに接続するように構成されています。kubectl
のインストールの詳細については、公式ドキュメントを参照するか、 Kubernetesの使用を開始するためのチュートリアル:kubectl CheatSheetに従ってください。- ローカルマシンにインストールされているcurlコマンドラインユーティリティ。 オペレーティングシステムに組み込まれているパッケージマネージャーを使用して、
curl
をインストールできます。
ステップ1—サンプルアプリケーションの構築
Jaegerのトレース機能をテストするために、フロントエンド用とバックエンド用の2つのサービスを使用するサンプルアプリケーションsammy-jaeger
をビルドしてデプロイします。 PythonとFlaskマイクロフレームワークの両方を使用してビルドします。
私たちのアプリケーションは、フロントエンドを呼び出すたびに値が増加するヒットカウンターになります。 パフォーマンスの問題をシミュレートするために、フロントエンドがGET
リクエストをバックエンドに送信するたびに実行されるランダム化されたスリープ関数をコーディングします。 このステップでは、そのアプリケーションをビルドしてデプロイします。 次の手順では、アプリをKubernetesにデプロイし、Jaegerをインストールしてから、それを使用してサービスの問題を追跡します。
まず、プロジェクトディレクトリ構造を作成し、内部をナビゲートしましょう。
mkdir -p ./sammy-jaeger/frontend ./sammy-jaeger/backend && cd ./sammy-jaeger
これで、ルートディレクトリsammy-jaeger
と2つのサブディレクトリができました。
output. ├── backend └── frontend
また、ルートディレクトリ/sammy-jaeger
に変更しました。 ここから残りのすべてのコマンドを実行します。
フロントエンドアプリケーションの構築を始めましょう。
フロントエンドアプリケーションの構築
お好みのテキストエディタを使用して、./frontend
にfrontend.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にデプロイする前に、バックエンドアプリケーションをコーディングしてビルドしましょう。
バックエンドアプリケーションの構築
バックエンドアプリケーションには、フロントエンドと同じ手順が必要です。
まず、./backend
にbackend.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()
random
やsleep
を含むいくつかのモジュールをインポートしています。 次に、カウンター値を1
に設定し、2つの関数を定義します。 最初のget_counter
は、counter_value
として格納されている現在のカウンター値を返します。 2番目の関数increase_counter
は、2つのアクションを実行します。 カウンター値を1
ずつインクリメントし、sleep
モジュールを使用して、関数の完了をランダムな時間だけ遅らせます。
バックエンドには、POST
とGET
の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がクラスターのパフォーマンスの問題を監視および解決するのにどのように役立つかについて詳しくは、公式ドキュメントをご覧ください。