envoyをGraceful shutdownする


概要

KubernetesにデプロイしたenvoyのPodが停止する際、処理時間の長いリクエストを受けていてもクライアントにエラーが返らないようにしたい

調査

こちらのPRを見ていると、envoy自体にGraceful shutdownは実装されてなさそう?

PRのコメントにはメトリクスを見てねとあります

Scripting around /healthcheck/fail and sleeping is also what we do for draining. After failing the healthcheck we watch the listeners' downstream_rq_active metric to drop to an acceptable range before terminating.

KubernetesのPreStopを使って、コンテナの終了前にメトリクスを見て判定をしようと思います

実装

spec:
  template:
    spec:
      containers:
        - name: envoy
          image: envoyproxy/envoy:latest
          ...
          lifecycle:
            preStop:
              exec:
                command: 
                  - /bin/sh
                  - -c
                  - |
                    curl -X POST --unix /tmp/envoy.admin http://localhost/healthcheck/fail
                    for i in `seq 60`
                    do
                      cx=$(curl localhost:9000/stats?filter=http.ingress_http.downstream_cx_active -s | cut -d ' ' -f 2)
                      if [ $cx = 0 ]; then
                        break
                      fi
                      sleep 1
                    done

やってること

  • コンテナが終了する前に/healthcheck/failを叩いてヘルスチェックが失敗するようにする(Readiness Probedeで/readyを見ておけば新規のリクエストが来なくなる)
  • メトリクスを見てアクティブなコネクションが無くなるまで最大60秒程待つ

参考