サービスメッシュを実現するIstioをEKS上で動かす - その4 データの可視化について
山崎 雅斗
Istioでは、CPUやメモリの使用量をはじめとして様々なデータがデフォルトで収集されています。
これらの情報は、各サービスのSidecar Proxyから、コントロールプレーンのMixerに集約され、最終的にPrometheusに格納されます。
今回は、それらの様々なデータを可視化するための方法についていくつか紹介していきたいと思います。
引き続き、前回までに使っていたEKSクラスタを使用していきますので、IstioはHelmでインストールされていることを前提としています。
シリーズ一覧
- まずはMinikubeでサンプルアプリケーションを動かしてみる
- EKSでサンプルを動かしてみる
- EKSでRDSなど外部サービスと接続してみる
- データの可視化について 👈 この記事
- 実運用中のサービスをIstioにのせてみる
- Datadogと連携する
サービスメッシュの可視化
サービスメッシュ内のアプリケーション数が増えてくると、アプリケーション間の関係等がだんだん把握しづらくなっていくかと思います。
そういった時に使えるサービスメッシュ可視化サービスをいくつか紹介します。
ServiceGraph
ServiceGraph add-onを用いると、現在サービスメッシュ内で動作しているアプリケーションのつながりを下のようなグラフとして表示させることができます。
では、ServiceGraphをインストールしていきます。
まず、Helmを使ってServiceGraphをインストールします。istio-system namespaceにServiceGraphのリソースが作成されているのを確認しておきます。
$ helm upgrade istio install/kubernetes/helm/istio --set servicegraph.enabled=true
$ kubectl --namespace istio-system get deployments servicegraph
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
servicegraph 1 1 1 1 15m
$ kubectl --namespace istio-system get service servicegraph
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
servicegraph ClusterIP 172.20.110.108 <none> 8088/TCP 15m
インストール自体はこれで完了です。本来はServiceGraphにアクセスするためGatewayやVirtualService等を作成してロードバランサ経由でアクセスするような設定を入れるかと思いますが、ここでは簡単にPort Forwardingを使ってサービスにアクセスしてみます。次のコマンドを実行して、ServiceGraphとのPort Forwardingを有効にしておきます( kubectl port-forward
で指定するPod名は各自確認して適切なものを指定してください)。
$ kubectl get pods --namespace istio-system --selector app=servicegraph
NAME READY STATUS RESTARTS AGE
servicegraph-56dddff777-rn2zt 1/1 Running 0 15m
$ kubectl --namespace istio-system port-forward servicegraph-56dddff777-9ljwf 8088:8088
Port Forwardingを有効にした状態で http://localhost:8088/force/forcegraph.html
にアクセスすると、上に乗せてある画像のような画面になって、サービスのグラフが表示できます。このグラフは自動で定期的に更新されるため、アプリケーションの増減に応じて変化していきます。
Vistio
Vistioは、ServiceGraphと同じようにサービスメッシュを可視化してくれるツールです。Netflixが開発したVizceralというものがベースとなって作られているようです。
サービス間を流れるトラフィック量に応じてアニメーションが表示されるので、今どれくらいのトラフィック量が流れているのかが視覚的にわかりやすくなっています。
(下の画像は検証環境での画面となっているため、大したトラフィックがなくて分かりづらいですが…)
それでは、早速Vistioをインストールしていきます。
VistioはServiceGraphのようにIstioに元から含まれているものではないので、まずVistioのファイル群をダウンロードしてくる必要があります。今回はシンプルに git clone
で持ってきています。
$ git clone https://github.com/nmnellis/vistio.git
$ cd vistio
ダウンロードが終わったら、Helmを使ってVistioをインストールしていきます。
$ helm install helm/vistio -f helm/vistio/values-with-ingress.yaml --name vistio --namespace default
通常ならこれでインストールが完了ですが、EKSを使っている場合はPersistent Volumeの割当がうまくいかずにインストールが完了できていない可能性があります。
Vistioが要求しているPersistent Volume ClaimのStorageClassは standard
となっていますが、EKSのデフォルトではそれが存在しないようです。
HelmのオプションでStorageClassが変更できればよいのですが、軽く確認した限りでは難しそうだったので、 standard
という名前のStorageClassを作成することで対応しました。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
mountOptions:
- debug
StorageClassの問題を解決するとVistioのサービスがうまく起動するかと思います。 vistio-web
と vistio-api
の2つのPodがRunningとなっていればOKです。
サービスの起動が確認できたら、ブラウザからアクセスできるように次のコマンドでPort Forwardingをしておきます。 vistio-web
のPod名は各環境に応じて変更してください( vistio-api
はStatefulSetリソースとして作成されているため、Pod名は例と同じになっているはずです)。
$ kubectl get pods --selector app=vistio-web
NAME READY STATUS RESTARTS AGE
vistio-web-bd6887d77-mztcv 2/2 Running 0 5m
$ kubectl port-forward vistio-web-97976464c-zqrd2 8080:8080
$ kubectl port-forward vistio-api-0 9091:9091
Port Forwardingにした状態で http://localhost:9091
にアクセスすると、Vistioの画面が表示されます。
サービスメッシュ名が書いてある方をクリックすると、メッシュ内に存在するアプリケーションの関係を可視化した画面が表示されます。
右上のFiltersという部分で、エラーが多い場所のみを表示する等のフィルタリング設定を行うことができます。
mTLS有効時の注意
mTLSをSTRICTモードで有効にした状態でVistioをデプロイすると、Health Checkが失敗してPodがCrashLoopBackOffとなります。これは、kubeletから行われているHealth Checkのリクエストが、mTLSのHandshakeの段階でうまく動作しないためです。これを回避するにはいくつか方法があります。
- mTLSを無効にする
- mTLSをPERMISSIVEモードにする
- STRICTモードとは異なり、PERMISSIVEモードではHTTPによる通信も許可されるため(mTLS対応していない部分は引き続きHTTPでの接続が可能)
- Health Check方式をHTTPからCommandに変更する
テレメトリの可視化
Grafanaを使うと、サービスメッシュ内の様々なメトリクスのグラフがあらかじめ設定されたダッシュボードにアクセスできるようになります。もちろん自分で独自のダッシュボード作成も可能なので、用途に合わせてカスタマイズを行うことが可能です。
GrafanaはIstioに元から含まれているので、Helmのオプションで有効にするだけで使用可能になります。
Grafanaを有効にするため、次のコマンドを実行します。
$ helm upgrade istio install/kubernetes/helm/istio --set grafana.enabled=true
これだけでインストールは終了です。
では、Port Forwardingを使ってGrafanaの画面にアクセスしてみます。
$ kubectl --namespace istio-system port-forward grafana-7f6cd4bf56-x9h2c 3000:3000
この状態で http://localhost:3000/
にアクセスするとGrafanaにアクセスできます。
左上のHomeメニューから,作成されているダッシュボードの中から見たいものをを選ぶことができます.
例としてMesh Dashboardを選ぶと,次のようなダッシュボードが表示されるかと思います.
分散トレーシング
Istioでは、クラスタの運用者が特に何も気にしなくても、分散トレーシングで必要となるSpanをSidecar Proxyが勝手に送信してくれています。
ここでは、Jaegerというサービスを使って分散トレーシングを行い、それで得た情報を見ていこうと思います。
Jaegerも他のサービスと同様、Helmのオプションを指定するだけでインストールが可能となります。
一つ注意したい点として、トラフィックのサンプリングレートがあります。デフォルトでは1%、すなわち全トラフィックの1%のみを対象としたトレーシングが行われます。しかし、テスト環境等でそれほどトラフィック量が多くない場合、1%のサンプリングだと中々トレーシングの結果が見れない、という状況が考えられます。今回の検証環境はトラフィック量が少ないので、サンプリングレートを100%にしてJaegerをインストールしていきたいと思います。
次のコマンドでJaegerをインストールすることができます。 traceSampling=100
というのがサンプリングレートの設定となり、0〜100の範囲で設定することができます。
$ helm upgrade istio --set tracing.enabled=true,pilot.traceSampling=100
インストールができたら、Port Forwardingをしてブラウザからアクセスできるようにしておきます。
$ kubectl port-forward --namespace istio-system istio-tracing-7596597bd7-27plf 16686:16686
この状態で http://localhost:16686
にアクセスすると、つぎのような画面が表示されます。
左側にあるServicesというプルダウンリストで検索したい対象のサービスを選択し、左下のFind Tracesボタンをクリックすると右側にトレーシングの結果が表示されます。
今回は、productpageサービスを例として見てみます。
あらかじめbookinfoサービスに何回かアクセスして、トレーシング結果が出るようにしておきます。
Jaegerの画面で、左側のServicesプルダウンリストから productpage
を選択し、左下のFind Tracesをクリックします。
すると、右側にいくつかトレーシング結果が表示されるかと思います。
それぞれのトレーシングの詳細をクリックすると、さらにその詳細を確認することができます。
トレーシングを行う際の注意点
Jaegerによるトレーシングを正しく行うためには、それぞれの通信を正確に紐付けるために何らかのヒントを与えてあげる必要があります。
Istioでは、Sidecar Proxyが次の8つのヘッダを自動的にリクエストに付与しているので、リクエストについてきたこれらのヘッダをレスポンスに含めて返却する必要があります。これにより、Jaegerで正しくトレーシングを行うことができるようになります。
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context
まとめ
今回は、Istioのサービスメッシュや取得できるデータを可視化するためのサービスをいくつか紹介しました。基本的なサービスはIstioに元から含まれているため、Helmのオプションを指定するだけで利用することができてとても便利です。