サービスメッシュを実現するIstioをEKS上で動かす - その4 データの可視化について

山崎 雅斗
6

Istioでは、CPUやメモリの使用量をはじめとして様々なデータがデフォルトで収集されています。
これらの情報は、各サービスのSidecar Proxyから、コントロールプレーンのMixerに集約され、最終的にPrometheusに格納されます。

今回は、それらの様々なデータを可視化するための方法についていくつか紹介していきたいと思います。
引き続き、前回までに使っていたEKSクラスタを使用していきますので、IstioはHelmでインストールされていることを前提としています。

シリーズ一覧

サービスメッシュの可視化

サービスメッシュ内のアプリケーション数が増えてくると、アプリケーション間の関係等がだんだん把握しづらくなっていくかと思います。
そういった時に使えるサービスメッシュ可視化サービスをいくつか紹介します。

ServiceGraph

ServiceGraph add-onを用いると、現在サービスメッシュ内で動作しているアプリケーションのつながりを下のようなグラフとして表示させることができます。

servicegraph
ServiceGraph

では、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

それでは、早速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-webvistio-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の画面が表示されます。

vistio-top
VistioのTop画面

サービスメッシュ名が書いてある方をクリックすると、メッシュ内に存在するアプリケーションの関係を可視化した画面が表示されます。

vistio
サービスメッシュが可視化されている様子

右上のFiltersという部分で、エラーが多い場所のみを表示する等のフィルタリング設定を行うことができます。

vistio-filtering
フィルタを使って特定のもののみ表示することも可能

mTLS有効時の注意

mTLSをSTRICTモードで有効にした状態でVistioをデプロイすると、Health Checkが失敗してPodがCrashLoopBackOffとなります。これは、kubeletから行われているHealth Checkのリクエストが、mTLSのHandshakeの段階でうまく動作しないためです。これを回避するにはいくつか方法があります。

  1. mTLSを無効にする
  2. mTLSをPERMISSIVEモードにする
    • STRICTモードとは異なり、PERMISSIVEモードではHTTPによる通信も許可されるため(mTLS対応していない部分は引き続きHTTPでの接続が可能)
  3. 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にアクセスできます。

grafana-top
Grafana

左上のHomeメニューから,作成されているダッシュボードの中から見たいものをを選ぶことができます.

grafana-select-dashboard
Dashboard一覧

例としてMesh Dashboardを選ぶと,次のようなダッシュボードが表示されるかと思います.

grafana-mesh-dashboard
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 にアクセスすると、つぎのような画面が表示されます。

jaeger-top
Jaeger

左側にあるServicesというプルダウンリストで検索したい対象のサービスを選択し、左下のFind Tracesボタンをクリックすると右側にトレーシングの結果が表示されます。
今回は、productpageサービスを例として見てみます。

あらかじめbookinfoサービスに何回かアクセスして、トレーシング結果が出るようにしておきます。
Jaegerの画面で、左側のServicesプルダウンリストから productpage を選択し、左下のFind Tracesをクリックします。
すると、右側にいくつかトレーシング結果が表示されるかと思います。

jaeger-tracing-result
トレーシング結果

それぞれのトレーシングの詳細をクリックすると、さらにその詳細を確認することができます。

jaeger-tracing-detail
トレーシングされたものをクリックすると詳細が確認できる

トレーシングを行う際の注意点

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のオプションを指定するだけで利用することができてとても便利です。