Unyablog.

のにれんのブログ

Vertical Pod Autoscaler の limits 周りの挙動について

Kubernetes で memory の requests を管理するのに Vertical Pod Autoscaler (VPA) を使っている。

github.com

VPA はリソースの使用量の実績に基づいて良い感じに limits と requests を調整してくれるものだが、 limits の設定に関してちょっと困ったのでメモ。

参考: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#limits-control

VPA がどう limits を設定するか

VPA が limits を設定するときは、 LimitResources などの制約がない場合、以下のようなアルゴリズムで設定される。

  1. VPA が requests を算出する
  2. 算出した requests に、元々設定されていた requests と limits の比をかけて新しい limits とする

すなわち、メモリの requests を 500Mi, limits を 1000Mi とした Pod に対して、VPA が新しい requests を 700Mi とすれば、新たな limits は 1400Mi となる。

requests を設定していないとき問題

ここで、Pod に limits のみを設定し、requests を設定していない場合はどうなるか。このとき、k8s は requests を limits と同じ量に設定するので、VPA は requests と同量の limits を推奨するようになる *1

requests は普段の使用量ベースで自動設定されるので、limits に同じ値が設定されるとほとんど burst できない Pod となってしまう。 起動時ちょっとだけメモリを多めに使う、みたいな Pod がある場合に OOM killer で落ち続けるようになってしまった。

解決策

解決策としては以下が考えられる。

  • limits だけではなく request を設定する

    request を設定する際には VPA の挙動を考慮する必要がある

  • limits を設定せず request のみを設定する

    こうすると VPA によって limits が減ることはない

今回はめんどくさかったので後者にした。

limits がない結果ノードのメモリが不足する可能性があるが、 requests は普段調整されるためそれほど起こらないはず。もし頻繁に起きるなら、普段は問題ないが Burst したときにメモリが足りないということであり、それは各ノードの余剰メモリが足りないということであるので、そういった問題として対処することにした *2

*1:requests が何らかの理由で設定されない場合も VPA によって同量になる https://github.com/kubernetes/autoscaler/blob/2542e8c884a8e25634d3b8f43243fa8706007f30/vertical-pod-autoscaler/pkg/utils/vpa/limit_and_request_scaling.go#L69-L72

*2:LimitRanges ぐらいは設定してもいいかもしれない