nekop's blog

OpenShift / JBoss / WildFly / Infinispanの中の人 http://twitter.com/nekop

OpenShiftのResource requestとlimit

OpenShift 全部俺 Advent Calendar 2017

最初はどのように指定したらいいかわかりづらいという質問がよくあるKubernetesのResource requestとlimitです。

https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

Podにはこのような定義でResource request, limit (リソース要求、制限)を記述します。

resources:
  requests:
    cpu: 100m
    memory: 64Mi
  limits:
    memory: 64Mi

CPUもメモリもrequestsを記述しないと、CPUはゼロ割り当てでまったく動かなくても構わない、メモリについてはいつメモリ不足で終了されても構わない、という意味になります。そのようなアプリケーションでない限り、これらは必ず指定してください。

スケジューラはrequestsを元にスケジューリングを行います。4CPU coresのノードにrequests.cpuが4のPodを割り当てたら、あとは上記のどうでもいいPod以外はそのノードにはスケジューリングされません。このPodは4CPU使えることが保証されます。

CPUについてはlimitsを指定すると、ノードにCPUが空いていてもそれ以上は利用できない、という意味になります。指定しなければ無制限です。普通のアプリケーションにとってはCPUが空いているのに使えないというのは基本的にデメリットしかありませんので、その場合はCPUについてはlimitsを指定する必要性はありません。もちろん、limitsが必要なケースはあり、たとえばユーザがビットコインを掘ることが想定されて過度な利用を制限したいというような場合はlimits指定が必要です。空いているCPUが他のPodに利用されていても、requests.cpuが指定されているPodがCPUを使おうとすればもちろんrequests.cpu分は優先してそちらに割り当てられるので、この空いているCPU利用は他のPodで確保されているCPU利用を阻害することはありません。

メモリについてはlimitsを指定しない場合(無制限)、もしくはrequestsよりlimitsを大きく指定する場合は、requestsを超えたメモリ使用量になった瞬間から、いつでもメモリ不足のため終了されても構わない、という状態になります。この「いつでもメモリ不足のため終了されても構わない」というアプリケーションはそれほど多くはないと思いますので、メモリについては基本的にrequests/limitsは同値指定で動作に十分な量を指定することが多いと思います。メモリ利用がlimits.memoryに達した場合はPodはoom-killerに殺されます。

というわけで、基本的にはrequests.cpuとrequests.memory == limits.memoryを指定しましょう。

あとはこの記事では解説しませんが、クラスタ管理者はノード保護のためkube-reservedとかevictionは適切に設定しましょう。

https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/