Ответ
Kubernetes при нехватке ресурсов на узле (в первую очередь памяти) начинает эвакуировать поды, начиная с наименее приоритетных с точки зрения QoS (Quality of Service). Порядок следующий:
- BestEffort — поды, у которых для всех контейнеров не заданы ни
requests, ниlimits. У них самый низкий приоритет. - Burstable — поды, у которых для хотя бы одного контейнера заданы
requests, ноlimitsлибо не заданы, либо превышаютrequests. - Guaranteed — поды с наивысшим приоритетом. Для всех контейнеров в поде должны быть заданы и
requests, иlimits, причемrequests.memory == limits.memoryиrequests.cpu == limits.cpu.
Пример манифеста для Guaranteed QoS:
apiVersion: v1
kind: Pod
metadata:
name: guaranteed-pod
spec:
containers:
- name: app
image: nginx
resources:
requests:
memory: "100Mi"
cpu: "500m"
limits:
memory: "100Mi" # Должно равняться request
cpu: "500m" # Должно равняться request
Важные нюансы:
- Механизм убийства (eviction) срабатывает при давлении на вытесняемые ресурсы: память (
memory.available) и файловую систему узла (nodefs.available,imagefs.available). - Для CPU Kubernetes не убивает поды, а троттлит (ограничивает) процессы контейнеров, если они превышают свои лимиты.
- Внутри одного класса QoS Kubernetes может использовать другие приоритеты, например, сравнивать
usageконтейнеров против ихrequests. - OOM Killer на уровне ядра Linux может убить любой процесс, включая контейнеры, но он также учитывает
oom_score_adj, который Kubernetes выставляет в зависимости от QoS класса.