Щоб скористатися цією функцією, вам (або адміністратору кластера) потрібно увімкнути функціональну можливість PodLevelResourceManagers для всіх відповідних компонентів у вашому кластері.
Перегляньте Увімкнення або вимкнення функціональних можливостей для отримання додаткової інформації.
Цей посібник демонструє, як налаштувати менеджери ресурсів kubelet (topology, CPU та memory) для підтримки специфікацій ресурсів на рівні подів. Ви можете визначити гібридні моделі розподілу, де деякі контейнери отримують ексклюзивні, вирівняні за NUMA інфраструктурні ресурси, тоді як інші спільно використовують решту ресурсів із спільного пулу на рівні пода.
Щоб дізнатися більше про концепції, що стоять за цією функціональною можливістю, прочитайте сторінку концепцій Менеджери ресурсів на рівні Podʼа.
pod менеджера Topology Manager, щоб досягти вирівнювання за одним NUMA-вузлом зі змішаними ексклюзивними та спільними контейнерами.container менеджера Topology Manager зі змішаними розподілами контейнерів.Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж v1.36.Для перевірки версії введіть kubectl version.
Для виконання цього посібника вам потрібно:
sudo) на робочому(их) вузлі(ах) для зміни конфігурації kubelet та перезапуску служби kubelet.kubectl з дозволом створювати простори імен та поди.Переконайтеся, що наступні функціональні можливості увімкнені для вашої панелі управління та для робочих вузлів:
PodLevelResourcesPodLevelResourceManagersСтворіть простір імен, щоб ресурси, створені в цьому посібнику, були ізольовані від решти вашого кластера:
kubectl create namespace plrm-tutorial
Коли область дії менеджера Topology Manager встановлено у pod, kubelet виконує єдине вирівнювання NUMA для всього Podʼа на основі .spec.resources. Отриманий бюджет ресурсів потім розподіляється: контейнери, які запитують ресурси Guaranteed, отримують ексклюзивні частки, тоді як контейнери, які не отримують ексклюзивного розподілу, спільно використовують решту бюджету у спільному пулі на рівні пода.
podЩоб увімкнути цю поведінку, налаштуйте kubelet на цільовому(их) робочому(их) вузлі(ах), де ви хочете запускати ці робочі навантаження, з необхідними політиками. Ви можете оновити конфігурацію kubelet для цих вузлів наступним чином:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cpuManagerPolicy: "static"
memoryManagerPolicy: "Static"
topologyManagerScope: "pod"
topologyManagerPolicy: "single-numa-node"
topologyManagerPolicy допустимими значеннями є single-numa-node, restricted або best-effort. Ви не можете вказати жодне інше значення під час використання управління ресурсами на рівні podʼа.Перезапустіть kubelet, щоб застосувати конфігурацію. Наприклад, на Linux з systemd: systemctl restart kubelet.service.
Розглянемо наступний приклад маніфесту пода. Под запитує загальний бюджет 4 CPU на рівні пода (.spec.resources). Усередині пода:
main-app запитує ексклюзивний розподіл 2 цілих ядер CPU (requests = limits = 2 CPU).metrics-sidecar та logging-sidecar не вказують запити на рівні контейнера, ці два контейнери sidecar спільно використовують ядра CPU, що залишилися зі спільного пулу на рівні пода: 2 ядра CPU.apiVersion: v1
kind: Pod
metadata:
name: pod-scope-mixed
annotations:
kubernetes.io/description: "A pod demonstrating pod-level scope where one container gets exclusive resources and others share the remaining pod resources in a shared pool."
spec:
# На рівні Podʼа, Pod має запит на CPU, рівний лімітам, і запит на памʼять також
# рівний лімітам памʼяті. Контейнер main-app відповідає вимогам для класу QoS
# Guaranteed на рівні контейнера, а sidecar контейнери не вказують жодного
# запиту на ресурси. У межах масштабу Podʼа kubelet може статично призначити
# 4 CPU для всього Podʼа, з яких 2 призначені ексклюзивно для контейнера
# main-app, а решта 2 спільно використовуються sidecar контейнерами.
resources:
requests:
cpu: "4"
memory: "4Gi"
limits:
cpu: "4"
memory: "4Gi"
initContainers:
- name: metrics-sidecar
# Примітка: Тут поле image є заповнювачем для демонстраційних цілей, а не
# справжнім допоміжним елементом метрик.
image: registry.k8s.io/pause:3.9
restartPolicy: Always
- name: logging-sidecar
# Примітка: Тут поле image є заповнювачем для демонстраційних цілей, а не
# справжнім агентом ведення журналів.
image: registry.k8s.io/pause:3.9
restartPolicy: Always
containers:
- name: main-app
# Примітка: Тут поле image є заповнювачем для демонстраційних цілей.
image: registry.k8s.io/pause:3.9
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "2"
memory: "2Gi"
Застосуйте маніфест до вашого кластера:
kubectl apply -f https://k8s.io/examples/pods/resource/pod-level-resource-managers-pod-scope-mixed.yaml --namespace=plrm-tutorial
Перевірте, що Pod успішно працює:
kubectl get pod pod-scope-mixed --namespace=plrm-tutorial
Зрозумійте, що відбулося за лаштунками:
flowchart TD
subgraph Pod["Pod-Level Budget: 4 CPUs, 4Gi Memory"]
direction TB
C1["main-app<br/>(Exclusive: 2 CPUs, 2Gi Memory)"]
subgraph Pool["Pod Shared Pool: 2 CPUs, 2Gi Memory"]
C2["metrics-sidecar"]
C3["logging-sidecar"]
end
endspec.resources) та призначив весь Pod одному NUMA-вузлу.main-app. Обмеження квоти CFS CPU вимкнено для main-app, що надає йому необмежений доступ до цих ексклюзивних ядер.metrics-sidecar та logging-sidecar не вказують ресурсів на рівні контейнера (resources: {}), тому вони працюють у цьому ізольованому для пода спільному пулі з увімкненим застосуванням квоти CFS. Хоча пул є спільним між цими двома контейнерами sidecar, він ізольований від зовнішніх робочих навантажень на вузлі, що надає контейнерам sidecar виділену локальність NUMA та захист від конкуренції за ресурси на рівні вузла.Під час використання області дії pod контроль допуску kubelet відхиляє специфікації подів, які призвели б до порожнього спільного пулу Podʼа, коли є контейнери, які потребують його.
Якщо сума ексклюзивних запитів ресурсів від контейнерів Guaranteed дорівнює загальному бюджету на рівні пода, і принаймні один інший контейнер потребує спільного пулу, kubelet відхиляє Pod.
Розглянемо наступний маніфест. Pod запитує загальний бюджет 4 CPU. container-a запитує ексклюзивний 1 CPU, а container-b запитує ексклюзивні 3 CPU (разом 4 CPU). container-c не запитує ексклюзивних ресурсів і потребує спільного пулу, але 0 CPU залишається:
Застосуйте маніфест:
kubectl apply -f https://k8s.io/examples/pods/resource/pod-level-resource-managers-empty-shared-pool.yaml --namespace=plrm-tutorial
Перегляньте події Podʼа, щоб побачити помилку допуску:
kubectl describe pod empty-shared-pool --namespace=plrm-tutorial
Зверніть увагу на повідомлення події, яке пояснює, що kubelet відхилив Pod, оскільки спільний пул на рівні podʼа був би порожнім для контейнерів, які потребують спільних ресурсів:
Status: Failed
Reason: TopologyAffinityError
Message: Pod was rejected: Pod Scope pod with pod-level resources failed admission under pod-scope topology manager
flowchart TD
subgraph Pod["Pod-Level Budget: 4 CPUs, 4Gi Memory"]
direction TB
C1["container-a<br/>(Exclusive: 1 CPU, 1Gi Memory)"]
C2["container-b<br/>(Exclusive: 3 CPUs, 3Gi Memory)"]
subgraph Pool["Pod Shared Pool: 0 CPUs, 0Gi Memory"]
C3["container-c<br/>(Requires shared pool)"]
end
end
Pool --> Rejection["Admission Error: Pod Rejected!"]
style Rejection fill:#ffcccc,stroke:#ff0000,stroke-width:2pxВи також можете налаштувати область дії Topology Manager на container. У цьому режимі kubelet оцінює кожен контейнер окремо для ексклюзивного розподілу, тоді як загальний бюджет Podʼа у .spec.resources все ще забезпечує межі QoS та cgroup лімітів.
containerОновіть конфігурацію kubelet на цільовому(их) робочому(их) вузлі(ах) для області дії container:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cpuManagerPolicy: "static"
memoryManagerPolicy: "Static"
topologyManagerScope: "container"
topologyManagerPolicy: "single-numa-node"
Перезапустіть kubelet, щоб застосувати конфігурацію. Наприклад, на Linux з systemd: systemctl restart kubelet.service.
containerРозглянемо наступний приклад маніфесту Podʼа. Pod має загальний бюджет 4 CPU:
infrastructure-sidecar запитує ексклюзивну частку у 2 CPU (requests = limits = 2 CPU).worker-1 та worker-2 не вказують запитів на рівні контейнера та працюють у загальному, спільному для всього вузла пулі.apiVersion: v1
kind: Pod
metadata:
name: container-scope-mixed
annotations:
kubernetes.io/description: "A pod demonstrating container-level scope where one container gets exclusive resources and others run in the node's shared pool."
spec:
# На рівні Podʼа, Pod має запит на CPU, рівний лімітам, і запит на памʼять також
# рівний лімітам памʼяті. Контейнер infrastructure-sidecar відповідає вимогам для
# класу QoS Guaranteed на рівні контейнера, а робочі контейнери не вказують
# жодного запиту на ресурси. У межах контейнерного масштабу kubelet оцінює
# контейнери індивідуально для ексклюзивного виділення. Це означає, що
# infrastructure-sidecar отримує ексклюзивний фрагмент CPU на 2 ядра, тоді як
# робочі контейнери працюють у загальному пулі вузла, все це обмежено загальними
# лімітами Podʼа.
resources:
requests:
cpu: "4"
memory: "4Gi"
limits:
cpu: "4"
memory: "4Gi"
initContainers:
- name: infrastructure-sidecar
# Примітка: Тут поле image є заповнювачем для демонстраційних цілей, а не
# справжнім допоміжним елементом інфраструктури.
image: registry.k8s.io/pause:3.9
restartPolicy: Always
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "2"
memory: "2Gi"
containers:
- name: worker-1
# Примітка: Тут поле image є заповнювачем для демонстраційних цілей.
image: registry.k8s.io/pause:3.9
- name: worker-2
# Примітка: Тут поле image є заповнювачем для демонстраційних цілей.
image: registry.k8s.io/pause:3.9
Застосуйте маніфест:
kubectl apply -f https://k8s.io/examples/pods/resource/pod-level-resource-managers-container-scope-mixed.yaml --namespace=plrm-tutorial
Перевірте, що Pod працює:
kubectl get pod container-scope-mixed --namespace=plrm-tutorial
Зрозумійте, що відбулося за лаштунками:
flowchart TD
subgraph Pod["Pod-Level Budget: 4 CPUs, 4Gi Memory"]
direction TB
C1["infrastructure-sidecar<br/>(Exclusive NUMA Slice: 2 CPUs, 2Gi Memory)"]
subgraph NodePool["Node Shared Pool: Pod-level limit"]
C3["worker-2"]
C2["worker-1"]
end
endcontainer kubelet оцінює контейнери окремо. infrastructure-sidecar отримує ексклюзивну, вирівняну за NUMA частку у 2 CPU безпосередньо з пулу розподілюваних ресурсів вузла.worker-1 та worker-2 не вказують запитів ресурсів на рівні контейнера (resources: {}), тому за області дії container вони працюють у загальному спільному пулі вузла (а не в ізольованому для podʼа пулі).spec.resources.limits).Видаліть простір імен та всі приклади подів, створені під час цього посібника:
kubectl delete namespace plrm-tutorial