Improving the Performance of Your Kubernetes Cluster

KubeCon + CloudNativeCon Europe 2020 1日目 のセッションである Improving the Performance of Your Kubernetes Cluster についてです。

Step 1: Calculating overhead

  • シングルプロセスのオーバヘッドを計算する: https://github.com/priyawadhwa/track-cpu

    • duration と interval を指定すると、その間の監視対象プロセスの平均/最大 cpu 使用率を出してくれる
    • 発表された方の自作ぽい
  • プロセス全体のオーバヘッドを計算する: https://github.com/tstromberg/cstat

    • iostat より 100 倍正確らしい (README より)

それぞれの動作環境で CPU 使用率はそれぞれ以下の結果となった。

  • VM only: 0-4 %
  • VM + Kubeadm: 10-15 %
  • Minikube: 20-40 %

どのように Kubernetes Cluster のパフォーマンスを向上させるか、Minikube を例に以降の発表が続く。

Learning to use performance tools

こんなツールを使うといいよってやつ

The USE Method

USE: Utilization, Saturation and Errors

それぞれ確認した項目、コマンド、結論について述べられている。

Component Command Conclusion
CPU (system wide) mpstat -P ALL 1 CPU の %sys は通常通りで、1コアに負荷が集中してるわけでもない
CPU (minikube process) pidstat 1 -C qemu -h minikube プロセスのオーバヘッドは平均 22% で、内 14.5 % は VM 内からくるもの
Memory capacity free -m 通常
Storage Device I/O (Utilization) iostat -xz 1 通常
Storage Device I/O (Utilization, per process) sudo iotop --only 一度に minikube のもつ複数プロセスがディスク書き込みをしていることが分かった

eBPF in Minikube

  • BCC tools *1 を推奨していた
    • Huge collection of tracing tools in Python
    • These tools profile and trace the Linux kernel
    • Instructions for running bcc tools in minikube can be found at

biosnoop (Block Device I/O をトレースしてPID ごとの latency を取得) を実行してみると、殆ど etcd

f:id:skitazawa1121:20200819115354p:plain

Flame graph

ホストで Flame graph を取ると、CPU_n/KVM というのが見える

f:id:skitazawa1121:20200819115407p:plain

CPU_0/KVM の内訳をみると、ほとんど ioctl syscall が占めている

f:id:skitazawa1121:20200819115417p:plain

Is there a way to tune how often etcd writes to disk?

とりあえずやってみたチューニング (not significant と言われている)

  • etcd のディスク書き込みの頻度を減らしたい!
  • とりあえず etcd の --snapshot-count オプションをチューニングしてみる
  • --snapshot-count=3000 にしたところ 2% しか向上しなかった

ここまでのまとめ

  1. オーバヘッドの調査をした
    • USE の解析より、 etcd が disk 書き込みをめっちゃやってるように見えた
    • Flame Graph より、ioctl 呼び出しが原因っぽい
  2. チューニング: etcd の snapshot count の数を減らした
  3. パフォーマンス向上は見られなかった

What are these spikes?

以下の図より、 CPU 使用率は断続的にスパイクがあるように見える

f:id:skitazawa1121:20200819115431p:plain

pidstat より kubectl apply -f /etc/kubernetes/addons の実行が頻繁に CPU を使ってるように見えた

f:id:skitazawa1121:20200819115447p:plain

What is the addon manager?

  • kube-addon-manager *2 により5秒ごとに kubectl apply が実行されている!

  • ポーリング間隔を延ばしてみてオーバヘッドが改善するか試した -> 改善した!

  • ポーリング間隔とユーザエクスペリエンスはトレードオフだけど、今回は完全にポーリングをやめてみた
  • 32% 削減! *3

kube-apiserver overhead

次にオーバヘッドがありそうな、 kube-apiserver の改善

pprof

kube-apiserver に対して Golang のプロファイリングツールである pprof を利用してみた

  • top で CPU 使用率を見ると syscall.Syscall が flat%: 10.76%, sum%: 50.00% だった

    • flat: 1 call 当たりにかかる時間
    • flat%: 該当 flat の全体に対する割合
    • sum%: 累計flat%
  • flame graph より以下が分かった

    • filters.ServeHTTP が 16%
    • transport.Reader が 12%

Leader election requests from scheduler & controller manager

kube-apiserver を -v=10 で起動してみたら、 Leader election が目立った *4

f:id:skitazawa1121:20200819115556p:plain

  • minikube はシングルノードなので leader election を切ってしまおう!
    • kube-scheduler , kube-controller-manager それぞれのオプションに --leader-elect=false を指定
  • 18% の削減!
    • ついでに codedns の replica 数も1にしたとしれっと書かれている

etcd overhead

etcd でも同じように pprof で見てみた

  • top で CPU 使用率を見ると syscall.Syscall が flat%: 40.00%, sum%: 40.00% だった
  • web でビジュアライズすると、 http.writeFrameAsync というメソッドが 40ms の始まりっぽいのが分かった

Searching through etcd code

  • etcd のソースコード内で Golanghttp ライブラリを使ってる箇所を調べた -> httpproxy パッケージを使っている箇所を発見!
  • refreshInterval がデフォルト30秒で設定されていて、--proxy-refresh-interval オプションで設定できることが分かった
    • --proxy-refresh-interval を 70000 (70秒) に設定 -> 4%削減!

Does changing the refresh interval make user experience worse?

  • --proxy-refresh-interval の値は、endpoint *5 の更新間隔
    • ソースコード *6 より、endpoint が存在しない場合は1秒おきに、存在する場合は --proxy-refresh-interval に設定した秒数おきに更新をかける

まとめ

  • 不必要なものを取り除いた
    • Addon manager
    • Coredns pod
    • Leader election
  • オーバヘッドとユーザエクスペリエンスのトレードオフは考慮しましょう
  • コラボレーションはめっちゃ重要
    • 分からないときには Slack で質問

f:id:skitazawa1121:20200819115613p:plain

感想

ツールを使って計測することで minikube のどこが重いかを調査する内容で、とてもおもしろかったです。 自分は ISUCON をやることがあるのですが、その中でよく使うツールがこの発表でも出てきたので 「おおー ISUCON だ」となりましたw

*1:https://github.com/iovisor/bcc

*2:https://qiita.com/inajob/items/300805e895eec6535dd2 (分かりやすかったので引用させていただきました)

*3:CPU使用率を32%減らした ではなく、最初の状態を100とした場合に32%性能が向上したってことぽい (多分)

*4:これを見て自分はそう思える自信がない・・・

*5:etcd のendpoint のこと?

*6:https://github.com/etcd-io/etcd/blob/cfdc296a3c4f21c7bba244f17b4c2d7f68595ece/proxy/httpproxy/director.go#L52-L68 (聴講後現在の master HEAD)