Резервирование CPU в кластере
Резервирование (pinning) CPU для etcd в кластере можно настроить в графическом или программном интерфейсе.
Обратите внимание Рекомендуем, чтобы в результате резервирования на узле должно остаться не менее 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 другие поды.