Envoy に入門した話

この記事は、はてなエンジニア Advent Calendar 2019の11日目の記事です。

前置き

Envoyは今話題のIstioやApp Meshのコアに使われているなどサービスメッシュの文脈で名前が出ることが多いですが、Envoy自身はnginxはHAProxyのようなプロキシ・ロードバランサの一種なのでサービスメッシュ関係なく案外簡単に導入することができます。

そのEnvoyを利用する機会があったので、概念の整理とともにどうやって設定を書いていけば良いかまとめていきます。

ファイル分割

設定項目が多いのですぐに行数が増えていくのでファイル分割は最初から考えておくと良いです。

外部通信して設定更新するという仕組み(discovery service)があり、その仕組みの中でファイルから読み込む方法が取れるという世界観です。

機能ごとにCluster, Listener, Routerなどといった名前がついていてそれぞれが何を設定できるのか違ってます。

そしてそのClusterやRouterといった機能ごとの単位でしか分割できないので、さらに細かく区切るということはできません。

ファイル名の指定する場所も機能ごとに変わっていて、リスナとクラスタ設定であればdynamic_resourcesという部分で指定し、ルーティングの設定はリスナの中で指定します。

ファイル読み込みに関しては以下の記事が詳しいです。

www.katacoda.com

medium.com

フィルタ

リクエストを受け取ってなにか処理するものをフィルタと呼びます。

ルーティングするものはenvoy.router, Fault Injectionするものは envoy.fault というフィルタを使います。

フィルタは上に書いた順に処理されるので、ルーティングをするenvoy.routerは最後に書くのが普通です。

今紹介したフィルタはHTTPフィルタ*1 の一種で、他にはTCPフィルタやRedisフィルタなどもあります。

ログ

ログはリスナ設定のとこに書きます。*2

JSONでログを出す場合にはjson_formatというやつが使える...のですが、こちらはすべてクォートで囲まれて文字列になってしまい数値やboolなどを出せません。

なのでクォートで囲まれたくない場合は format で頑張ってJSONの形式を組み立てる必要があります。

まだ検証できていないけれどv1.12.2からあるtyped_json_format *3を使えば数値うまく出せるのかも知れません。

ちなみにログには必ずRESPONSE_FLAGSというものを出したほうが良いです。(デフォルトでも含まれています)

これはステータスコードの細かい理由が記録されるもので、サーキットブレーカー由来なのかそもそも接続に失敗したのかなどが書いてあります。

Envoyの設定チューニングする場合も、このフラグがどういう割合で出ているのか見ることが多いです。

設定ファイルの書式を確認する

ファイル分割をしていると起動->ファイル読み込みという順になり、設定に不備があってもその設定が読み込まれないだけで続行されるという感じになります。

またログもerrorではなくwarningなので知らないと気が付きにくいです。

なのでCI等で設定の検証を回したいなどの場合は、こういう感じで実際に数秒起動してみてwarningのログが出るかを見てチェックするのが良いです。

OUTPUT_FILE=/tmp/envoy.log
CONTAINER_ID=$(docker run -d -p 10000:10000 envoyproxy/envoy:latest envoy \
   --config-path /etc/envoy/envoy.yaml --service-node node \
   --service-cluster cluster --component-log-level \
   config:warning,upstream:error,main:error,runtime:error)
echo $CONTAINER_ID
sleep 5
docker logs $CONTAINER_ID 2> $OUTPUT_FILE
docker kill $CONTAINER_ID
if [ -s $OUTPUT_FILE ]; then
  cat $OUTPUT_FILE
  exit 1
fi

リトライ・タイムアウト

何回リトライするかとか、何秒でタイムアウトするとかを設定できます。

タイムアウトに関する設定はかなり多く最初は混乱しますが、基本的には timeoutper_try_timeout をよく考えるで良いです。

  • timeout:リトライも含む全体のタイムアウト
  • per_try_timeout: 1回のリクエストのタイムアウト
  • num_retries: リトライを何回するか

どういう場合にリトライするかも決められます。*4

5xx が他のルールを含んでいることもあり大体はカバーできているはずですが、POSTリクエストもある場合はretriable-4xxも入れておくとよいのかもしれません。

リトライのバックオフ間隔も変えることができますが*5、デフォルトで既に設定されているのであまり変えることはないかも知れません。

adminインタフェース

別のポートを指定して管理画面を起動することができます。

今動いている設定や統計情報がわかるのでメトリックを取りたい場合はこちらも立てておく必要があります。

多くの情報が確認できる上にこの管理画面からプロセスを落とすこともできるので間違って全世界に公開しないように気をつける必要があるのだけ注意です。

サーキットブレーカー

同時リクエスト数や同時リトライ数など設定できます*6

この中で一番有用なのはmax_retriesで、今このタイミングでリトライしている同時リクエスト数が一定値を超えている場合はそれ以上通信しません。

これにより特に難しいことしなくても詰まっている場合にだけ通信を減らすことができ影響を小さくすることができます。

そしてリトライが捌けたらまた通常通りリクエストを通すようになるという挙動です。

同時リトライ回数の他にもありますが総リクエスト数に影響されるものなので具体的に良い数字を決めるのは難しいと思います。

Fault Injection

Envoyが条件によって通信を遅延させたり、特定のステータスコードを返せる機能です。

これにより通信に時間がかかった際の表示や特定のステータスコードが返ってきた際の挙動を確認することができるので開発時にとても便利です。

確率や特定のヘッダを条件にできるので、ユーザから使われないヘッダで応答を変える条件を書いておいて、いつでも確認できる状態にしておくと良いと思います。

Keep-Alive を無効にする

毎回コネクションを切りたいときにどうすればよいかについて、前に記事を書きました。

通信先がHTTP/1.1だとわかっているなら最初から設定しておくと後ではまらなくていいと思います。

core.cohalz.co

終わりに

Envoyは設定項目が多くまだまだ知らないことがたくさんあります。

パフォーマンスチューニングなんかも全然できていないのでそこら辺も調べていきたいですね。

という記事を書いていたら Envoy Meetup Tokyo #1 というイベントを来年やるようでした。

envoytokyo.connpass.com

気づいたときには満員でLT枠も埋まっていたので行けるかどうかわからないですが...という話題でした

明日のはてなエンジニア Advent Calendar 2019担当は id:motemen です。

リンク集

  • Envoyをロードバランサとして利用する際にどう設定するか日本語で解説してくれている記事

i-beam.org

  • Envoyでユースケース別に設定を学べる
    • nginxやHAProxyとの構文比較もあり英語だけどかなり理解しやすいと思います。

www.katacoda.com

自動でMackerelの監視設定をGitHub上に管理してどうなったか

この記事は Mackerel Advent Calendar 2019 2日目 の記事です。

qiita.com

あらすじ

今年の4月にMackerelの監視ルールをGitHubで管理するというブログ記事を書きました。

developer.hatenastaff.com

この記事を書いたときはまだ導入したばかりでしたが、半年以上経った今実際どの様に便利になったかという記事になります。

変更がわかるようになった

監視ルールの変更はSlack等に通知することができますが、変更されたこととと今の設定しか確認することができません。

そのため、経緯を忘れないようメモに経緯や前の設定を書くということでカバーしていたということがありました。

しかし、追従を忘れるなどでそのメモも古びてしまうことがありました。

今はコミットのURLを共有することで以前との設定の違いを確認できるようになってとても便利になりました。

バックアップが取られることになり変更がしやすくなった

バックアップがあるということですぐ元の状態に戻せるようになりました。

今ままではメモを取っていないと過去の設定に戻すのは大変でしたが、前に説明したとおり変更がわかるので前の値を参照して戻すことが出きます。

バックアップの取られていないものを変更するというのは抵抗があるという場合でも変えやすくなり、これによってSRE(インフラエンジニア)だけではなくアプリケーションエンジニアも積極的に監視ルールを変更してもらえるようになりました。

チェック監視の方を既にgitで管理してデプロイしている場合であれば、それに近い状態だと思ってもらえるとわかりやすいと思います。

複数の監視ルールを一気に変更したくて mkr monitors push するという場合でもバックアップがあるため安心して実行できたという話もありました。

監視名自体を変えてしまった際もGitHub側のバックアップファイルには一意のidが振られているため探すことができます。

監視ルールの変更について様々な情報がわかるようになった

これが思っても見なかった効果で、今回紹介したかったものです。

そもそもとして、GitHubにバックアップを取る際のコミットメッセージにはこのような変更タイプ(作成・変更・削除)、監視ルールや変更した人が含まれています。

monitorUpdate: CPU % by cohalz

また監視ルールを変更したタイミングでコミットされるため時刻などもわかります。

そのため、git logを使って変更に関する情報を探したり集計して出すということもできるようになります。

いくつか便利なコマンドを紹介します。監視ルールを管理しているGitリポジトリ上で実行してください。

特定の監視ルールに関するgit logを出す

git log --grep="CPU %"

  • 単純にコミットメッセージで検索しているのでユーザ名を入れることでその人が行った変更を探すこともできます。

監視ルールの変更内容(作成・変更・削除)ごとに回数を出す

git log --oneline --pretty=format:"%s" | awk 'match($0, /^([^:]*?): (.*?) by (.*?)/, a){print a[1]}' | sort | uniq -c

  • 監視ルールが実際どういう変更が多いのか、どれくらい削除されているのか確認できます。

監視ルールを変更した人を変更回数の上位順に出す

git log --oneline --pretty=format:"%s" | awk 'match($0, /^([^:]*?): (.*?) by (.*?)/, a){print a[3]}' | sort | uniq -c | sort -nr

  • 監視ルールを変更する人が偏っていないかどうかわかります。

月別に監視ルールの変更回数を出す

git log --oneline --pretty=format:'%cd' --date=format-local:'%Y/%m' | uniq -c

  • 変更回数の多かった月に何があったのか振り返ってみても良いかも知れないです。

1時間ごとに監視ルールの変更回数を集計

  • git log --oneline --pretty=format:'%cd' --date=format-local:'%H' | sort | uniq -c

監視ルールがどの時間に変更されることが多いのか、深夜の時間帯にどのくらい変更されているのかがわかります。

終わりに

監視ルールをGitHubで管理することで変更がわかるようになり気軽に変更しやすくなったほか、git logを用いて統計を出すみたいなこともできるようになりました。

これで抜き出した統計情報をMackerelのグラフで見る、みたいなことも面白いかも知れないですね。

今回紹介したGitHub管理の仕組みは現在AWS Serverless Application Repositoryにて公開しており、簡単に使い始められるのでこの機会に是非使ってみてください。

developer.hatenastaff.com

iOS ショートカットで画像プレビューをする

「クイックルック」を使えば画像プレビューができる。

最近の写真を一枚プレビューするにはこういうショートカットを書けば良い。

アクションから「写真」とか「イメージ」で検索して全然見つからないし日本語で全然目的の情報も見つからないので、「ios shortcuts show photo」とか英語で検索したらredditがヒットしてたどり着くことができた。

www.reddit.com

Envoy で HTTP Keep-Alive を無効にする

Envoyではデフォルトで Keep-Alive が有効になっているが、これを無効化したい場面があったので調べた。

方法

max_requests_per_connectionの値を1にすれば良い。

公式ドキュメントにはSetting this parameter to 1 will effectively disable keep alive.*1と書いてあるように、 keepalive に関するパラメータがあってそこをいじるのかと思いきやそういう設定はなくイディオムのようになっている。

余談

Envoy からコネクションが残っているかは統計のupstream_cx_active*2から確認できる。

コネクション周り結構調査が難しくて特にコンテナだとコネクション残ってるのかどうか判断がしにくいけど、 Envoy の統計情報をから確認できるの結構便利だった。

core.cohalz.co

このタイミングでIngressの話をしたい

今いいタイミングだと思ったのでIngressのことを書く。

自分の場合

  • 2014年の10月に始めてから毎日必ずプレイしている
  • 歩いた距離 5000km
  • 出会ったポータルは3万4千
  • Swarmチェックイン履歴

f:id:cohalz:20190927081807p:plain:w300

どうしてこんなに続けられているのか

遊び方は人それぞれなのが良いと思う。例えばイベントに参加しまくる人もいれば地元でしか活動しない人もいる。

あと、やりたいときに思いっきりやれるというのも大きくて、スマホゲーでありがちなスタミナ制、メンテナンス、ダウンロードの待ち時間...などがない。

変わったこと

一番は旅行に行くようになったということで、海外を含め行くようになった。

イベントがいろんな地域で開催されるのでついでに旅行計画を立てていくとかもできる。

Ingressの実績の中に色んな所に行く必要があるものがあるので、特に行ったことない場所に行きたくなった。

あとは身近な場所に何があるか興味を持つようになったとか。

ポケモンGoについて

ポケモンGoもそこそこやっている。

f:id:cohalz:20190927094221p:plain:w300

もともとポケモンはかなりやっていたので結構楽しめているし、モンスターボールPlusなど使えばIngressと同時プレイも可能なのは嬉しい。

そもそもIngressと同じ会社なので信頼があるし、ポケモンGoで実装されているものはIngressでも実装されるかもという期待も持てる。

様々な思い出

  • 目的地への電車が人身事故で行けなくなり、途中下車してその場所で歩き回った。

  • 大学の先生(埼玉)と大阪で偶然出会う。

  • 石巻・女川に行って復旧の状態を目にした。

  • ソウルで現地の知り合いと偶然居合わせたボカロPと三人で一緒に中指立ててる写真を撮った。

 

京都での思い出

2015年の3月に京都で大きなイベントがあり、自分がIngressで初めて遠出した場所でもある。

それ移行もいくつか京都でイベントなどがあり、毎回参加していた。

例えばBivi京都二条にIngressの自販機があったり、

三条珍遊がイベントの協賛をしていてカードを配っていたりと結構思い出がある。

f:id:cohalz:20190927093053j:plain:w400

今のIngress

今のIngressはこんな感じの画面になっている。

f:id:cohalz:20190927092223p:plain:w300

昔と比べて結構UI変わっているけれど、これは現在進行中のリプレースに伴ってUIが変わっている。

リプレースはチート・スパム対策、周辺技術のサポート切れや新機能を追加しやすくするためにしばらく前から行っているもので、今月末についに移行が完了する。

いろいろな位置情報ゲームが出ている今、昔やってたという人も結局やらなかったという人も今がいいタイミングだと思う。

いい感じのタイトル

やあ (´・ω・`) ようこそ、バーボンハウスへ。 このテキーラはサービスだから、まず飲んで落ち着いて欲しい。

うん、「また」なんだ。済まない。 仏の顔もって言うしね、謝って許してもらおうとも思っていない。

でも、このスレタイを見たとき、君は、きっと言葉では言い表せない 「ときめき」みたいなものを感じてくれたと思う。 殺伐とした世の中で、そういう気持ちを忘れないで欲しい そう思って、このスレを立てたんだ。

じゃあ、注文を聞こうか。