Kubernetes theory
September 25, 2022

QOS

Поды не равны между собой по значимости. Одни поды более ценные, другие менее ценные. В тоже время ресурсы нод ограничены. Иными словами может сложиться ситуация когда кластеру придётся выбирать какой под запустить, а какой остановить из-за нехватки ресурсов. Или не выдать поду ресурсов. Чтобы управлять процессом значимости подов и придумали QOS классы.

Также QOS класс влияет на то, какие поды будут убиты OOM Killer, если памяти на нодах будет не хватать. Поведение подов при этом будет подчиняться тому что указано в поле restartPolicy.

У каждого пода есть свой класс QOS. Неважный, важный и самый важный.

Существует три QOS класса:

1. BestEffort — самый низкоприоритетный класс. Он назначается объектам, у которых не указаны requests и limits. В самом негативном случае такие объекты могут вообще не получить ресурсов. Они же — первые кандидаты на перемещение на другой узел при перераспределении ресурсов. Это QOS класс по-умолчанию.

2. Burstable — почти как Guaranteed, только с заданными requests < limits. И достаточно только одного ресурса CPU or Memory.

3. Guaranteed — назначается объектам с заданными requests = limits. Нужно задать эти значения для каждого контейнера, при этом запрошенное и лимитируемое значение cpu и ram должно быть идентичным. У этого класса наивысший приоритет.

Для выставления QOS классов Burstable и Guaranteed используются блок resources:

    resources:
      requests:
        cpu: 300m
        memory: 100Mi
      limits:
        cpu: 300m
        memory: 150Mi 

Pod c QOS классом BestEffort:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: cam-nginx
  labels:
    app: nginx
    environment: preprod
spec:
  containers:
  - image: nginx:latest
    name: cameda-nginx
    ports:
      - containerPort: 80
EOF
Кусочек дескрайба этого пода
QoS Class:                   BestEffort
Node-Selectors:              <none>

Pod c QOS классом Burstable:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: cam-nginx
spec:
  containers:
  - image: nginx:latest
    name: cam-nginx
    resources:
      requests:
        cpu: 200m
        memory: 100Mi
      limits:
        cpu: 300m
        memory: 150Mi 
EOF
Кусочек дескрайба этого пода
QoS Class:                   Burstable
Node-Selectors:              <none>

Pod c QOS классом Guaranteed:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: cam-nginx
spec:
  containers:
  - image: nginx:latest
    name: cam-nginx
    resources:
      requests:
        cpu: 300m
        memory: 150Mi
      limits:
        cpu: 300m
        memory: 150Mi 
EOF
Кусочек дескрайба этого пода
QoS Class:                   Guaranteed
Node-Selectors:              <none>

На сегодняшний момент, использование CPU limits является антипаттерном. Здесь доводы в пользу этой теории: https://home.robusta.dev/blog/stop-using-cpu-limits

Полезные ссылки.

https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/