Резервирование CPU в кластере
Резервирование (pinning) CPU для etcd в кластере можно настроить в графическом или программном интерфейсе.
Резервирование CPU приводит к уменьшению доступных (Allocatable) CPU на узле. Это можно увидеть на странице узла или если сделать describe узла (разделы Capacity и Allocatable). Само резервирование никак не лимитирует CPU, а лишь устанавливает “веса” (приоритизацию). Т.е. pod без лимита всегда сможет потреблять 100% CPU, если в этот момент никто другой не претендует на CPU. Так же Allocatable учитывается на этапе планирования pod с указанными реквестами: если по реквестам не хватит ресурсов, то pod не будет запущен или будут вытесняться менее приоритетные поды.
Обратите внимание Рекомендуем, чтобы в результате резервирования на узле должно остаться не менее 6 свободных CPU.
Резервирование CPU в графическом интерфейсе
В интерфейсе кластера перейдите в раздел “Конфигурация узлов”, создайте новый объект NCI. Выберите раздел “Kubelet”. В селекторе узлов выберите ключ “node-role.kubernetes.io/control-plane”.
Скриншот
Заполните поля:
- Политика управления CPU (cpuManagerPolicy) со значением static. Это значение говорит kubelet, что можно привязывать поды к зарезервированным CPU.
- Перечень резервируемых CPU (reservedSystemCPUs) в виде диапазона или через запятую, например, “0-1”.
В блоке “Feature Gates” укажите параметры в формате ключ-значение:
- CPUManager: true
- CPUManagerPolicyOptions: true
- CPUManagerPolicyAlphaOptions: true
- CPUManagerPolicyBetaOptions: true
В блоке “Параметры управления CPU” (cpuManagerPolicyOptions) укажите параметры в формате ключ-значение:
- full-pcpus-only: “true”
- distribute-cpus-across-numa: “true”
- align-by-socket: “true”
Скриншот
Сохраните созданный объект. Kubelet будет перезапущен автоматически.
Резервирование CPU в программном интерфейсе
Подключитесь к кластеру из консоли.
Создайте манифест NCI
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
name: cpu-pinning-test
spec:
kubelet:
cpuManagerPolicy: static
featureGates:
CPUManager: true
CPUManagerPolicyOptions: true
CPUManagerPolicyAlphaOptions: true
CPUManagerPolicyBetaOptions: true
cpuManagerPolicyOptions:
align-by-socket: "true"
distribute-cpus-across-numa: "true"
full-pcpus-only: "true"
reservedSystemCPUs: 0-1
nodeconfigselector:
node-role.kubernetes.io/control-plane: ""
priority: 100
Примените созданный манифест.
Команда
kubectl apply -f cpu-pinning-test.yaml
Проверка состояния резервирования CPU
Для проверки состояния Kubelet CPU Manager.
Команда
cat /var/lib/kubelet/cpu_manager_state
Пример результата команды
{"policyName":"static","defaultCpuSet":"0-1,4-7","entries":{"3f6868ef501db41abc9cc55c40ab1020":{"etcd":"2-3"}},"checksum":4106740397}
Здесь можно увидеть, что:
- используется политика static
- по умолчанию все поды размещаются в распределенном пуле процессоров 0-1,4-7
- для пода etcd выделены CPU 2-3
В случае успешного резервирования CPU в логе kubelet будет сообщение.
Сообщение
policy_static.go:175] "Reserved CPUs not available for exclusive assignment" reservedSize=2 reserved="0-1" reservedPhysicalCPUs="0-1"
Обратите внимание! Есть вероятность, что на виртуальных машинах не заработает выравнивание по сокетам, если выставить больше, чем 1 сокет на VM, так как нет возможности повлиять на количество NUMA-node. В таком случае необходимо удалить параметр: align-by-socket: “true”.
Пример ошибки
I0613 19:29:30.525539 5408 cpu_manager.go:172] "Detected CPU topology" topology={"NumCPUs":8,"NumCores":8,"NumSockets":2,"NumNUMANodes":1,"CPUDetails":{"0":
{"NUMANodeID":0,"SocketID":0,"CoreID":0}
,"1":{"NUMANodeID":0,"SocketID":0,"CoreID":1},"2":{"NUMANodeID":0,"SocketID":0,"CoreID":2},"3":{"NUMANodeID":0,"SocketID":0,"CoreID":3},"4":{"NUMANodeID":0,"SocketID":1,"CoreID":4},"5":{"NUMANodeID":0,"SocketID":1,"CoreID":5},"6":{"NUMANodeID":0,"SocketID":1,"CoreID":6},"7":{"NUMANodeID":0,"SocketID":1,"CoreID":7}}}
июн 13 19:29:30 shturval-mycluster-cpu-master-qc2rv kubelet[5408]: E0613 19:29:30.525580 5408 container_manager_linux.go:329] "Failed to initialize cpu manager" err="new static policy error: Align by socket is not compatible with hardware where number of sockets are more than number of NUMA"
июн 13 19:29:30 shturval-mycluster-cpu-master-qc2rv kubelet[5408]: E0613 19:29:30.525610 5408 run.go:74] "command failed" err="failed to run Kubelet: new static policy error: Align by socket is not compatible with hardware where number of sockets are more than number of NUMA"
Условия использования зарезервированных ресурсов для подов
Резервирование CPU приводит к тому, что никакие поды не будут размещаться на выделенных под резервирование CPU выбранных узлов. Исключение представляют те поды, у которых выполняются все условия использования гарантированных ресурсов:
- должны присутствовать как requests и limits;
- requests и limits по CPU должны быть целыми числами;
- requests и limits должны совпадать.
Пример
spec:
containers:
- name: etcd
resources:
limits:
memory: "500Mi"
cpu: "2"
example.com/device: "1"
requests:
memory: "500Mi"
cpu: "2"
example.com/device: "1"
Если все условия выполнены, то после запуска пода в статусе будет указан тип QoS Class: Guaranteed.
Обратите внимание! На резервируемых процессорах в кластере могли быть зарезервированы/запущены поды до резервирования CPU. Убедитесь, что узлы перезапустились после применения настроек Kubelet. Резервирование CPU не означает, что на этих ресурсах не будут исполняться процессы ОС. Это гарантирует, что kubelet не будет размещать на зарезервированных CPU другие поды.