kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Envoy x Prometheus x Grafana x Jaeger に入門する「Implementing Metrics and Tracing Capabilities」を試した

今回は「Try Envoy」「Implementing Metrics and Tracing Capabilities」を紹介する.Envoy を実戦投入するときには「モニタリング」「トレーシング」など,関連する技術トピックも把握しておく必要があると思う.今回の「Implementing Metrics and Tracing Capabilities」では「Envoy x Prometheus x Grafana x Jaeger」をまとめて試せる「お得すぎる!」コンテンツになっている.

Implementing Metrics and Tracing Capabilities

手順は以下の「計7種類」ある.

  • Step.1 「Start Envoy」
  • Step.2 「Adding Metrics」
  • Step.3 「Adding Tracing」
  • Step.4 「Generating Traffic」
  • Step.5 「Viewing Metrics」
  • Step.6 「Dashboarding Metrics with Grafana」
  • Step.7 「Viewing Tracing」

www.envoyproxy.io

www.katacoda.com

Step.1 「Start Envoy」

まず,Envoy と katacoda/docker-http-server:healthy を起動し,動作確認をしておく.

$ docker run --name=proxy -d \
  -p 80:10000 \
  -p 9901:9901 \
  -v $(pwd)/envoy/:/etc/envoy \
  envoyproxy/envoy:latest

$ docker run -d katacoda/docker-http-server:healthy
$ docker run -d katacoda/docker-http-server:healthy

$ curl 172.18.0.3
<h1>A healthy request was processed by host: 23fe941d8f04</h1>
$ curl 172.18.0.4
<h1>A healthy request was processed by host: bc3b328e6fbf</h1>

$ curl localhost
<h1>A healthy request was processed by host: bc3b328e6fbf</h1>
$ curl localhost
<h1>A healthy request was processed by host: 23fe941d8f04</h1>

ただし,今まで紹介した Try Envoy のコンテンツには出てなかった設定が envoy.yaml にある.例えば tracing で,今回試していく.

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9901 }

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 10000 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          generate_request_id: true
          tracing:
            operation_name: egress
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "*"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router
  clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]
    health_checks:
      - timeout: 1s
        interval: 10s
        interval_jitter: 1s
        unhealthy_threshold: 6
        healthy_threshold: 1
        http_health_check:
          path: "/health"
  - name: jaeger
    connect_timeout: 1s
    type: strict_dns
    lb_policy: round_robin
    load_assignment:
      cluster_name: jaeger
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 172.18.0.6
                port_value: 9411
tracing:
    http:
      name: envoy.zipkin
      config:
        collector_cluster: jaeger
        collector_endpoint: "/api/v1/spans"
        shared_span_context: false

Step.2 「Adding Metrics」

Envoy をモニタリングするため,Prometheus コンテナを起動する.

$ docker run -d -p 9090:9090 \
    -v /root/envoy/prometheus.yml:/etc/prometheus/prometheus.yml \
    --name prometheus-server \
    prom/prometheus

Prometheus の設定ファイル prometheus.yml は以下となる.簡単に言うと,Envoy の管理画面に 9901 ポートで接続できるため,そこから /stats/prometheus エンドポイントにアクセスし,メトリクスを収集している.

global:
  scrape_interval:     15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'envoy'
    metrics_path: /stats/prometheus
    static_configs:
      - targets: ['172.18.0.2:9901']
        labels:
          group: 'envoy'

Prometheus の詳細は「入門 Prometheus」を読むと良いかと!

kakakakakku.hatenablog.com

すると,Katacoda の公開ドメインから Prometheus の管理画面にも接続できるようになる.

f:id:kakku22:20200127112108p:plain

Step.3 「Adding Tracing」

次は Envoy で「分散トレーシング」を試す.今回は Uber の OSS であり,CNCF に参加するなど,よく知られた「Jaeger」を使う.Jaeger は Twitter の OSS である「Zipkin」の API と互換性があるため,envoy.yamltracing セクションでは,トレースドライバとして envoy.zipkin を指定する.

www.jaegertracing.io

tracing:
  http:
    name: envoy.zipkin
    config:
      collector_cluster: 172.18.0.6
      collector_endpoint: "/api/v1/spans"
      shared_span_context: false

ドキュメントに書いてある通り,Envoy は以下のようなトレースドライバをサポートしている.

  • envoy.lightstep
  • envoy.zipkin
  • envoy.dynamic.ot
  • envoy.tracers.datadog
  • envoy.tracers.opencensus
  • envoy.tracers.xray

www.envoyproxy.io

さらに重要なポイントがあり,envoy.yaml の中に generate_request_idtracing を追加している.generate_request_idtrue にすると,x-request-id ヘッダに UUID を追加することを明示的に設定できる.tracing を設定すると,既に説明した tracing セクションにトレース情報を送信する.

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 10000 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          generate_request_id: true
          tracing:
            operation_name: egress

最後にトレーシング用に Jaeger コンテナを起動しておく.

$ docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 9411:9411 -p 5775:5775/udp -p 16686:16686 jaegertracing/all-in-one:latest

Step.4 「Generating Traffic」

Envoy にリクエストを送り続ける.

$ while true; do curl localhost; sleep .5; done

Step.5 「Viewing Metrics」

ある程度 Envoy にリクエストを送ったら,今度は Prometheus の管理画面で Envoy のメトリクス envoy_cluster_external_upstream_rq をグラフ化する.これは Envoy のリクエスト数となる.

envoy_cluster_external_upstream_rq{envoy_cluster_name="targetCluster"}

すると,以下のようにメトリクスの増加を確認できる.

f:id:kakku22:20200126144500p:plain

Step.6 「Dashboarding Metrics with Grafana」

今度は Prometheus の可視化としてもよく使う「Grafana」を試す.Grafana コンテナを起動する.

$ docker run --name=grafana -d -p 3000:3000 grafana/grafana

次に Prometheus データソースを登録する.HTTP URL に http://172.18.0.5:9090 を設定し「Save & Test」を押す.

f:id:kakku22:20200126144534p:plain

また Envoy 用の Grafana ダッシュボードが用意されているため,ダッシュボード ID 6693 を指定して「Import」を押すと,すぐに Envoy 用のダッシュボードが使えるようになる.

grafana.com

f:id:kakku22:20200126144612p:plain

f:id:kakku22:20200127112740p:plain

もう1度 Envoy にリクエストを送り続ける.途中で /unhealthy エンドポイントを使ってヘルスチェックを落としたり,/healthy エンドポイントを使って復活させたり,HTTP 200 以外のエラーが出るように操作した.

$ while true; do curl localhost; sleep .1; done

$ curl 172.18.0.3/unhealthy
$ curl 172.18.0.4/unhealthy

$ curl 172.18.0.3/healthy
$ curl 172.18.0.4/healthy

すると,Prometheus のグラフに HTTP 500 の件数も表示される.今回はダッシュボードを拡張し,Grafana で確認できるようにした.

f:id:kakku22:20200127114026p:plain

Step.7 「Viewing Tracing」

最後は Jaeger UI を確認する.以下は Jaeger の「トレース分布(横軸 : 時系列 / 縦軸 : レスポンス)」「トレース詳細」を確認した.とは言え,本格的なトレースにはなってなく,得られる情報も少なかった.今回はあくまで動作確認を目的にしていると言えそう.

f:id:kakku22:20200127114552p:plain

f:id:kakku22:20200127114607p:plain

まとめ

  • 「Try Envoy」「Implementing Metrics and Tracing Capabilities」を試した
  • 内容としては「浅く広く」ではあるものの「Envoy x Prometheus x Grafana x Jaeger」をまとめて試せるお得感はある
  • やっと「Try Envoy」を(ほぼ)完走した 🎉

プルリクエスト

試しながら気付いた誤りを修正してプルリクエストを送っておいた!

github.com

Try Envoy 関連