kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Karabiner で「command + クリック」が動かなくなったら karabiner.json を確認しよう

数日前から,突然 Karabiner で「command + クリック」の組み合わせが動かなくなってしまった.事象としては,Karabiner 単体ではなく,以下の「日本語環境設定 (Complex Modifications)」を使っている場合に起きていた.ただし,Mac で US 配列を使っているため,左右の「command」を使って入力切替をする操作は必須となり,今まで通り使えるように戻すことを考えていた.

コマンドキーを単体で押したときに、英数・かなキーを送信する。(左コマンドキーは英数、右コマンドキーはかな) (rev 3)

前提

  • macOS Mojave
  • Karabiner-Elements 12.9.0

karabiner.json を修正したら解決した

結論を先に書くと,Karabiner の設定ファイル ~/.config/karabiner/karabiner.json を開き,to -> left_command -> lazyfalse に修正したら解決した.以下の karabiner.json は一部を抜粋している.もし「右 command + クリック」を使う場合は,同様に to -> right_command -> lazyfalse にする.

{
  "rules": [
    {
      "description": "コマンドキーを単体で押したときに、英数・かなキーを送信する。(左コマンドキーは英数、右コマンドキーはかな) (rev 3)",
      "manipulators": [
        {
          "from": {
            "key_code": "left_command",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "left_command",
              "lazy": false
            }
          ],
          "to_if_alone": [
            {
              "key_code": "japanese_eisuu"
            }
          ]
        }
      ]
    }
  ]
}

なお,ターミナルから ~/.config/karabiner/karabiner.json を直接開いても良いし,Karabiner 設定画面の Misc から,右下にある「Open config folder」をクリックして,慣れたテキストエディタを使うこともできる.

f:id:kakku22:20200203210021p:plain

EventViewer

Karabiner の動作に違和感を感じたら,EventViewer を使うと問題判別を素早くできる.例えば「command」を押しながら,EventViewer の右下にある Mouse Area をクリックすれば,イベントを確認できる.

f:id:kakku22:20200203210032p:plain

正常時は以下のように click_count:1 flags:cmd となる.

type:button_down     code:0          name:button1         misc:{x:729,y:111} click_count:1 flags:cmd
type:button_up       code:0          name:button1         misc:{x:729,y:111} click_count:1 flags:cmd

動かなくなったときは click_count:1 になっていた.ようするに「command + クリック」と操作しても,実際には「command」のイベントが送信されず,認識されていなかった.

type:button_down     code:0          name:button1         misc:{x:729,y:111} click_count:1 
type:button_up       code:0          name:button1         misc:{x:729,y:111} click_count:1 

lazy とは?

最後に Karabiner のドキュメントを読んで,lazy の意味を調べておく.個人的な意訳も含めて整理すると,lazy とは「別のキーと一緒に押すまで,該当のキーのイベントを送信しない設定」と言える.より具体的に left_command + c を例にすると,lazy: true の場合は left_command を押している間はイベントを送信せず,続いて c を押したタイミングで合わせてイベントを送信する.よって,lazy「command + クリック」の相性が悪かったんだと思う.

karabiner-elements.pqrs.org

まとめ

  • Karabiner で違和感を感じたら EventViewer を使うと問題判別を素早くできる
  • もし「command + クリック」の組み合わせが動かなくなってしまった場合は karabiner.jsonlazy の設定を確認する

Mackerel : check-http コマンドの --status オプションとは?

Mackerel の go-check-pluginscheck-http を使うと,エンドポイントの「チェック監視」を設定できる.なお,単純に外形監視をする場合は,Mackerel の機能で「URL 外形監視」を使える.ただし,ローカルエンドポイントを対象にするなど,check-http を使う場面もあるので,目的次第なところではある.

github.com

mackerel.io

check-http を使う

以下のように check-http コマンドを使うと,監視結果を取得できる.リターンコード 200 の場合は OK となり,リターンコード 404 の場合は WARNING となる.

# 200 の場合(サンプル)
$ check-http --url https://kakakakakku.hatenablog.com
HTTP OK: HTTP/1.1 200 OK - 214805 bytes in 0.295717 second response time

# 404 の場合(サンプル)
$ check-http --url https://kakakakakku.hatenablog.com/xxxxx
HTTP WARNING: HTTP/1.1 404 Not Found - 73031 bytes in 0.417951 second response time

なお,実際に「チェック監視」を行う場合は /etc/mackerel-agent/mackerel-agent.conf に以下(サンプル)を設定すると,Mackerel 管理画面に警告が出る.

[plugin.checks.check-http-kakakakakku-blog-200]
command = ["check-http", "--url", "https://kakakakakku.hatenablog.com/"]

[plugin.checks.check-http-kakakakakku-blog-404]
command = ["check-http", "--url", "https://kakakakakku.hatenablog.com/xxxxx"]

f:id:kakku22:20200203105724p:plain

check-http で使えるオプション

check-http には多くのオプションが実装されている.ヘルプを表示すると以下のようになる.

$ check-http --help
Usage:
  check-http [OPTIONS]

Application Options:
  -u, --url=                                          A URL to connect to
  -s, --status=                                       mapping of HTTP status
      --no-check-certificate                          Do not check certificate
  -i, --source-ip=                                    source IP address
  -H=                                                 HTTP request headers
  -p, --pattern=                                      Expected pattern in the content
      --max-redirects=                                Maximum number of redirects followed (default: 10)
      --connect-to=HOST1:PORT1:HOST2:PORT2            Request to HOST2:PORT2 instead of HOST1:PORT1
  -x, --proxy=[PROTOCOL://][USER:PASS@]HOST[:PORT]    Use the specified proxy. PROTOCOL's default is http, and PORT's
                                                      default is 1080.
      --user=USER[:PASSWORD]                          Basic Authentication user ID and an optional password.

Help Options:
  -h, --help                                          Show this help message

check-http --status とは?

ヘルプを見ただけだと,--status オプションをどう使えば良いのかわからなかった.コメントには「mapping of HTTP status」としか書かれていない.なお,GitHub の README.md を見ると,以下のようなサンプルは載っていた.何やら「特殊な構文」がありそうだとわかる.

check-http -s 404=ok -u http://example.com
check-http -s 200-404=ok -u http://example.com

整理をすると,check-http--status オプションは,Mackerel の「チェック監視」として「特定のリターンコードの監視結果を個別に設定するとき」に使う.例えば「404 を正常 (OK) とする」など.

今回は Go の実装を読みながら --status オプションの動作を整理した.

--status オプションに設定できるフォーマット

--status オプションには,以下の通り,2種類のフォーマットを設定できる.「特定のリターンコード」を設定することもできるし,ハイフンを使って「リターンコードの範囲(以上/以下)」を設定することもできる.

${コード}=${ステータス名}
${コード}-${コード}=${ステータス名}

${コード} には 200404500 など,リターンコードを数値で設定し,${ステータス名} には以下の4種類から固定値を設定する.

  • OK
  • WARNING
  • CRITICAL
  • UNKNOWN

よって,以下のように設定できる.

--status 200=OK
--status 500=WARINNG
--status 200-499=OK
--status 400-599=CRITICAL

さらに --status オプションを複数設定することもできる.

--status 200=OK --status 500=WARINNG
--status 200=OK --status 400-599=CRITICAL

--status オプションのデフォルト値

なお,重要な「デフォルト値」は以下となる.ただし,ドキュメントには書いてなく,Go の実装を読んで確認したため,ドキュメントに書いてもらえると良さそう.正直言って,わかりにくかった.プルリクエストを送ることもできるけど,どに書くべきだろう?

  • < 400 なら OK
  • < 500 なら WARNING
  • それ以外 なら CRITICAL

検証環境

--status オプションの動作確認をするために,Sinatra で雑に API を書いた.指定したリターンコードを返すだけだけど,以下に app.rb の実装を載せておく.200 / 202 / 401 / 404 / 500 / 503 を返す.

require 'sinatra'

get '/200' do
  status 200
end

get '/202' do
  status 202
end

get '/401' do
  status 401
end

get '/404' do
  status 404
end

get '/500' do
  status 500
end

get '/503' do
  status 503
end

実際に curl で実行すると,適切にリターンコードを返せている.

$ curl -s -I http://localhost:4567/200 | grep HTTP
HTTP/1.1 200 OK

$ curl -s -I http://localhost:4567/202 | grep HTTP
HTTP/1.1 202 Accepted

$ curl -s -I http://localhost:4567/401 | grep HTTP
HTTP/1.1 401 Unauthorized

$ curl -s -I http://localhost:4567/404 | grep HTTP
HTTP/1.1 404 Not Found

$ curl -s -I http://localhost:4567/500 | grep HTTP
HTTP/1.1 500 Internal Server Error

$ curl -s -I http://localhost:4567/503 | grep HTTP
HTTP/1.1 503 Service Unavailable

検証

404 はデフォルトでは WARNING だけど,--status 404=OK を設定すると OK になる.

$ check-http --url http://localhost:4567/404
HTTP WARNING: HTTP/1.1 404 Not Found  - 0 bytes in 0.021076 second response time

$ check-http --url http://localhost:4567/404 --status 404=OK
HTTP OK: HTTP/1.1 404 Not Found  - 0 bytes in 0.010714 second response time

401404 もデフォルトでは WARNING だけど,--status 400-499=OK を設定すると OK になる.

$ check-http --url http://localhost:4567/401
HTTP WARNING: HTTP/1.1 401 Unauthorized  - 0 bytes in 0.004647 second response time

$ check-http --url http://localhost:4567/404
HTTP WARNING: HTTP/1.1 404 Not Found  - 0 bytes in 0.021076 second response time

$ check-http --url http://localhost:4567/401 --status 400-499=OK
HTTP OK: HTTP/1.1 401 Unauthorized  - 0 bytes in 0.010508 second response time

$ check-http --url http://localhost:4567/404 --status 400-499=OK
HTTP OK: HTTP/1.1 404 Not Found  - 0 bytes in 0.013790 second response time

404 はデフォルトでは WARNING だけど,--status 400-499=CRITICAL を設定すると CRITICAL になる.

$ check-http --url http://localhost:4567/404
HTTP WARNING: HTTP/1.1 404 Not Found  - 0 bytes in 0.009807 second response time

$ check-http --url http://localhost:4567/404 --status 400-499=CRITICAL
HTTP CRITICAL: HTTP/1.1 404 Not Found  - 0 bytes in 0.006045 second response time

検証(矛盾のある設定をした場合)

最後は個人的に気になって「矛盾のある設定」を検証してみた.具体的には --status 200=OK --status 200-599=CRITICAL--status 200-599=CRITICAL --status 200=OK のように 200 の設定を重複させてみた.OKCRITICAL のどちらになるのだろう?

結論としては「順番通りに優先される」となる.ようするに1個目の --status が優先される.実装を読んでもそうなっている.基本的にこんな設定はしないと思うけど,警告などは出なかった.

$ check-http --url http://localhost:4567/200 --status 200=OK --status 200-599=CRITICAL
HTTP OK: HTTP/1.1 200 OK  - 0 bytes in 0.026561 second response time

$ check-http --url http://localhost:4567/200 --status 200-599=CRITICAL --status 200=OK
HTTP CRITICAL: HTTP/1.1 200 OK  - 0 bytes in 0.007202 second response time

まとめ

  • 最近 Mackerel の check-http を使う機会があった
  • 使えるオプションを確認したところ --status をどう使えば良いのかわからなかった
  • 特定のリターンコードの監視結果を個別に設定するときに使えることがわかった

今年も「Mackerel アンバサダー」として,ブログを軸にアウトプットしていくぞ!

Try Envoy を "ほぼ" 完走した

2019年11月から Envoy の理解を深めるために,Envoy 公式の学習コンテンツ「Try Envoy」を試しながら,学んだことをブログにアウトプットしてきた.2020年1月末でやっと「ほぼ完走」することができたため,まとめ記事を書く.なお「Try Envoy」はどのコンテンツも「Estimated Time: 10 minutes」となっていて,ザッと流すならすぐ終わるけど,意味がないと思う.そこで,構築する構成図を描いたり,解説のなかったパラメータを調べたり,手順上の誤植を修正したり,自分なりに付加情報を意識しながらアウトプットすることを強く意識していた.

なぜ Try Envoy を選んだ?

新しい技術を学ぶときに,個人的に「できる限り手を動かすこと」を意識している.ただし,闇雲に手を動かすのではなく,体系的にステップバイステップに学びたく,どちらかと言うと「学習コンテンツ系(e-Learning / Hands-On / YouTube など)」を好む傾向にある.仕事柄,すぐに検証するプロダクション環境を持っていないという背景もある.そこで,今回は Envoy 公式の「Try Envoy」を選んだ.Katacoda をベースにしているため,環境構築の必要がないという点も初学者に優しい.

www.envoyproxy.io

www.katacoda.com

コンテンツ一覧

2020年1月末時点だと,Try Envoy では「計11個」のコンテンツが公開されている.以下にコンテンツ名とブログ記事をマッピングする.

Try Envoy kakakakakku blog
Getting Started with Envoy 「Try Envoy」で Envoy を学ぼう!「Getting Started with Envoy」を試した - kakakakakku blog
Migrating from NGINX to Envoy Proxy nginx と Envoy の設定を比較して学べる「Migrating from NGINX to Envoy Proxy」を試した - kakakakakku blog
Migrating from HAProxy to Envoy Proxy 実施なし (*1)
Securing traffic with HTTPS and SSL/TLS Envoy で HTTPS 接続をする設定を学べる「Securing traffic with HTTPS and SSL/TLS」を試した - kakakakakku blog
File Based Dynamic Routing Configuration Envoy のディスカバリサービス (xDS) を学べる「File Based Dynamic Routing Configuration」を試した - kakakakakku blog
API Based Dynamic Routing Configuration Envoy の EDS を REST API で体験する「API Based Dynamic Routing Configuration」を試した - kakakakakku blog
Detecting Down Services with Health Checks Envoy の Health Checking と Outlier Detection の違いを学べる「Detecting Down Services with Health Checks」を試した - kakakakakku blog
Implementing Blue / Green Rollouts Envoy の route.HeaderMatcher を使う「Implementing Blue / Green Rollouts」を試した - kakakakakku blog
Controlling load balancing policies Envoy の lb_policy は ROUND_ROBIN 以外にもある!「Controlling load balancing policies」を試した - kakakakakku blog
Implementing Metrics and Tracing Capabilities Envoy x Prometheus x Grafana x Jaeger に入門する「Implementing Metrics and Tracing Capabilities」を試した - kakakakakku blog
Debugging Envoy Proxy 実施なし (*2)

実は実施しなかった(できなかった)コンテンツが2個ある.よって,タイトルに "ほぼ" と書いた.

  • 実施なし (*1)
    • 個人的に HAProxy を使う場面はなく,nginx で十分だった
  • 実施なし (*2)

良いところ

何よりもまず「Try Envoy」をやり込むことにより,envoy.yaml を読めるようになった(はず).今でも「設定長いなぁ」とは思うものの,Envoy を学ぶ前と比較すると,圧倒的に envoy.yaml に直面したときの「ナニコレ感」はなくなった.これは大きなメリットと言える.

次に Envoy の醍醐味とも言える「xDS」を File Based と API Based で試せたのは良かった.記事にも書いた通り,正直なところ API Based (gRPC) を学びたかったけど,最低限の仕組みを把握できれば,残りは自分で試行錯誤できる.

最後は「ルーティング」の仕組みをたくさん学べた点で,nginx からのマイグレーションも,ロードバランシング,カナリーデプロイ,HTTP Header ベースルーティングも学べた.まだまだ Envoy の機能の一部ではあるものの,多機能であることは十分にわかった.

フィードバック

「Try Envoy」をより良くするためにフィードバックをまとめておく.

まず,Envoy を使った「ルーティング」を学ぶという側面が強く,例えば「マイクロサービス文脈(リトライ/サーキットブレイク/タイムアウト/スロットリング)」のコンテンツもあると良かった.とは言え,Envoy はあくまでデータプレーンなので,Istio などコントロールプレーン側のコンテンツで学ぶべきだ!と言われればそれも納得できるところではある.

なお,関連するコンテンツ「Learn Envoy」では,以下の分類になっていて,バランス良く構成されているように思う.

  • Getting Started
  • Dynamic Configuration
  • Observability
  • Deployment Models
  • Resilience
  • Building On Envoy

次に「コンテンツは古め」という点も気になる.Envoy 自体の進化も早く,ドキュメントが頻繁に書き換わるため,コンテンツからリンクされているドキュメントが 404 になっている場面もあった.正直 latest のドキュメントを参照していると,影響を受けすぎる気もする.

他にも envoy.yaml の記法として cluseterhostsEnvoy 1.8.0 (Oct 4, 2018) で既に deprecated になっていて,現在は load_assignment を使う必要があるのに,ほとんどのコンテンツは hosts のままになっていた.経験者なら気付けるけど,初学者だと「動くけど本当は deprecated」には気付けないと思う.最近の変更だと,Envoy 1.12.0 (October 31, 2019)tracing.operation_name も deprecated になっている.

www.envoyproxy.io

ただし,プルリクエストは定期的に merge してもらえる(デプロイはされていないけど).よって,コンテンツ自体も OSS であるという気持ちで,一緒に改善していくのが良さそう.

github.com

まとめ

これで「Try Envoy」の連載は終わり!

今後 Envoy を学ぶ人たちの参考になれば嬉しいなーと😃

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 関連

Envoy の lb_policy は ROUND_ROBIN 以外にもある!「Controlling load balancing policies」を試した

今回は「Try Envoy」「Controlling load balancing policies」を紹介する.Envoy でサポートされている「ロードバランスポリシー」の種類を学べる.ただし,Weighted round robin の動作確認は期待通りに動かず,消化不良な感じになってしまった.個人的には「Controlling load balancing policies」は実施しなくて良いと思う.可能なら Katacoda 側で内容を見直してもらえると良さそう.

Detecting Down Services with Health Checks

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

  • Step.1 「Load balancing policies」
  • Step.2 「Weighted round robin」
  • Step.3 「Generating Traffic」

なお,最近 Try Envoy にあるリンクは 404 エラーになってしまった(年末までは見れていた).ただ Katacoda を使えば,引き続き同じコンテンツを実施できる.

www.katacoda.com

Step.1 「Load balancing policies」

Envoy では Cluster の lb_policy「ロードバランスポリシー」を設定できる.今まで試してきた Try Envoy では,全て ROUND_ROBIN を使っていたけど,実際には多くの種類が実装されている.

  • Weighted round robin (ROUND_ROBIN)
    • デフォルト設定
  • Weighted least request (LEAST_REQUEST)
  • Ring hash (RING_HASH)
  • Random (RANDOM)
  • Original destination (ORIGINAL_DST_LB)
    • Envoy v1.12.0 から非推奨で CLUSTER_PROVIDED を使う
  • Maglev (MAGLEV)
  • Cluster Provided (CLUSTER_PROVIDED)

RING_HASH は名前の通り Consistent Hashing の実装となる.ドキュメントを読むと ketama という C で実装されたライブラリのリンクがあり,Envoy の内部で使われているとのことだった.また MAGLEV は今回はじめて知ったけど,Google から論文が出ているアルゴリズムらしく,ketama よりも高速とのこと.気になる!

github.com

「ロードバランスポリシー」の詳細は以下のドキュメントに載っている.

www.envoyproxy.io

www.envoyproxy.io

Step.2 「Weighted round robin」

envoy.yamllb_policyROUND_ROBIN を設定する.今までの Try Envoy で何度も試したため,正直言うと他のロードバランスポリシーを試したかった.なお,今回は clusters の中に hosts を設定せず,新しく load_assignment を設定していた.よくよく調べると,Envoy v1.8.0 から hosts は非推奨になり load_assignment が推奨になっていた.今までの Try Envoy は非推奨の設定を使っていたことに気付く.ううう!

www.envoyproxy.io

さらに load_assignment の挿入場所に誤りがあり,Envoy の起動時にエラーになる.正しくは clusters のパラメータなので,以下のように lb_policy と並べる必要がある.修正はプルリクエストを送っているけど,取り込まれるまでは要注意!

envoyproxy.io

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
          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
    load_assignment:
        cluster_name: targetCluster
        endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                    socket_address:
                        address: 172.18.0.3
                        port_value: 80
            load_balancing_weight: 90
        - lb_endpoints:
            - endpoint:
                address:
                    socket_address:
                        address: 172.18.0.4
                        port_value: 80

そして,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;

Step.3 「Generating Traffic」

実際に while で Envoy にリクエストを送り続ける.

ドキュメントを読むと,endpoint.LocalityLbEndpointsendpoint.LbEndpoint に対する load_balancing_weight があり,混乱した.今回は前者の設定となり,172.18.0.3 側に多くのリクエストが送られるのかと予想したけど,動作確認をしてもルーティングに差は出なかった.うーん?理解が間違っている?よくわからず,もう少し Try Envoy として解説を書いて欲しいなと思う.

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

まとめ

  • 「Try Envoy」のコンテンツ「Controlling load balancing policies」を試した
  • Weighted round robin の動作確認は期待通りに動かず,消化不良な感じになってしまった
    • 実施しなくて良いと思う 😇

残るは1個!引き続き,進めていくぞ!

プルリクエスト

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

github.com

Try Envoy 関連