We are using a self-hosted microk8s cluster (single-node for now) for our internal staging workloads. From time to time, the server becomes unresponsive and I can't even ssh into it. The only way out is a restart.
I can see that before the server crashes, its memory usage goes to the limit and the CPU load shoots up to over 1000. So running out of resources is likely to blame.
That brings me to the question - how can I set global limits for microk8s to not consume everything?
I know there are resource limits that can be assigned to Kubernetes pods, and ResourceQuotas to limit aggregate namespace resources. But that has the downside of low resource utilization (if I understand those right). For simplicity, let's say:
- each pod is the same
- its real memory needs can go from
50 MiB
to500 MiB
- each pod is running in its own namespace
- there are 30 pods
- the server has 8 GiB of RAM
I assign
request: 50 Mi
andlimit: 500 Mi
to the pod. As long as the node has at least50 * 30 Mi = 1500 Mi
of memory, it should run all the requested pods. But there is nothing stopping all of the pods using450 Mi
of memory each, which is under the individual limits, but still in total being450 Mi * 30 = 13500 Mi
, which is more than the server can handle. And I suspect this is what leads to the server crash in my case.I assign
request: 500 Mi
andlimit: 500 Mi
to the pod to ensure the total memory usage never goes above what I anticipate. This will of course allow me to only schedule 16 pods. But when the pods run with no real load and using just50 Mi
of memory, there is severe RAM underutilization.I am looking for a third option. Something to let me schedule pods freely and only start evicting/killing them when the total memory usage goes above a certain limit. And that limit needs to be configurable and lower than the total memory of the server, so that it does not die.
We are using microk8s but I expect this is a problem all self-hosted nodes face, as well as something AWS/Google/Azure have to deal with too.
Thanks