Це стабільна функція в Kubernetes, яка загальнодоступна починаючи з версії v1.35. Вперше вона зʼявилась у випуску v1.27. Ви більше не можете вимкнути або відмовитися від цієї функції чи поведінки (це заблоковано); якщо ви явно встановите значення для повʼязаної функціональної можливості InPlacePodVerticalScaling, Kubernetes проігнорує це, але не повідомить про помилку.
Ця сторінка пояснює як змінити запити та обмеження ресурсів CPU та памʼяті повʼязані з контейнером без перестворення Podʼу.
Зазвичай, зміна ресурсів Podʼа вимагає вилучення наявного Podʼа та створення його заміни, що виконується контролером робочого навантаження. Зміна розміру Podʼа на місці дозволяє змінювати виділені його контейнерам CPU/памʼять уникаючи потенційної перерви в роботі застосунку. Процес зміни розміру ресурсів Podʼів описано в розділі Зміна розміру ресурсів CPU та памʼяті, призначених для Podʼів.
Ключові концепції:
spec.containers[*].resources контейнера представляє бажані ресурси і є змінюваним для значень CPU та memory.status.containerStatuses[*].resources показує поточно налаштовані ресурси для запуску контейнера. Для контейнерів, що не були запущені воно показує ресурси виділені для наступного запуску контейнера.requests та limits в специфікації Podʼа. Це, як правило, робиться з використанням kubectl patch, kubectl apply або kubectl edit для Podʼа залучаючи субресурс resize. Коли бажаний ресурс не збігається з виділеними ресурсами, Kubelet намагатиметься змінити розмір контейнера.status.containerStatuses[*].allocatedResources відстежує значення ресурсів, що були підтверджені Kubelet, переважно використовується для внутрішньої логіки планування. Для більшості потреб моніторингу та валідації зосереджуйтесь на status.containerStatuses[*].resources.Якщо у вузлі є podʼи з очікуваною або незавершеною зміною розміру (див Статус Pod Resize нижче), планувальник буде використовувати максимальні запити на бажані ресурси контейнера, запити виділення та запити поточних ресурсів зі статусу для прийняття рішення.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж 1.33.Для перевірки версії введіть kubectl version.
Має бути увімкнено функціональну можливість InPlacePodVerticalScaling для вашої панелі управління і для всіх вузлів вашого кластера.
Щоб увімкнути автоматичне витіснення планувальником відкладених запитів на зміну розміру, функціональна можливість InPlacePodVerticalScalingSchedulerPreemption також має бути увімкнена для вашої панелі управління.
Щоб динамічно змінювати розмір томів emptyDir на основі памʼяті (medium: Memory), функціональна можливість InPlacePodVerticalScalingMemoryBackedVolumes також має бути увімкнена для вашої панелі управління та вузлів, а вузли повинні працювати з cgroup v2.
Версія клієнта kubectl має бути принаймні v1.32 для використання прапорця --subresource=resize.
Kubelet оновлює умови статусу Pod, щоб вказати стан запиту на зміну розміру:
type: PodResizePending: Kubelet не в змозі негайно виконати запит. Поле message надає пояснення чому.reason: Infeasible: Запитана зміна розміру є неможливою на поточному вузлі (наприклад, запитано ресурсів більше ніж є на вузлі).reason: Deferred: Запитана зміна ресурсу зараз є неможливою, але може стати можливою згодом (наприклад, інший pod буде вилучено). Kubelet спробує змінити розмір.type: PodResizeInProgress: Kubelet прийняв зміну розміру та розподілив ресурси, але зміни все ще застосовуються. Зазвичай це швидко, але може зайняти більше часу залежно від типу ресурсу та поведінки під час виконання. Будь-які помилки під час активації повідомляються в полі message (разом з reason: Error).Якщо запитана зміна розміру є Deferred, kubelet періодично повторно намагатиметься змінити розмір, наприклад, коли інший pod буде видалено або масштабовано вниз.
<div class="feature-state-notice feature-alpha" title="Функціональна можливість: InPlacePodVerticalScalingSchedulerPreemption">
<span class="feature-state-name">Стан функціоналу:</span>
<span class="feature-state-details">
<span class="feature-state-stage">Alpha</span> починаючи з Kubernetes v1.37; стандартно вимкнено
</span>
</div>
<div class="feature-alpha">
<details>
<summary>Докладніше про цей функціонал</summary>
<p>Щоб скористатися цією функцією, вам (або адміністратору кластера) потрібно увімкнути функціональну можливість <a href="/uk/docs/reference/command-line-tools-reference/feature-gates/#InPlacePodVerticalScalingSchedulerPreemption"><tt>InPlacePodVerticalScalingSchedulerPreemption</tt></a> для всіх відповідних компонентів у вашому кластері.</p>
Перегляньте Увімкнення або вимкнення функціональних можливостей для отримання додаткової інформації.
</details>
</div>
Коли функціональну можливість InPlacePodVerticalScalingSchedulerPreemption увімкнено, kube-scheduler відстежує поди зі статусом зміни розміру Deferred. Якщо вузлу бракує потужності для задоволення запиту на зміну розміру Podʼа з вищим пріоритетом, планувальник може витісняти (виселяти) поди з нижчим пріоритетом на цьому вузлі, щоб звільнити потужність CPU або памʼяті. Для отримання додаткових деталей див. Витіснення для зміни розміру Podʼа на місці.
Якщо є кілька відкладених змін розміру, вони повторно намагаються відповідно до наступного пріоритету:
Зміна розміру з вищим пріоритетом, позначена як така, що очікує на виконання, не блокуватиме спроби зміни розміру, що залишаються в очікуванні; всі інші очікуючі зміни розміру все ще будуть повторно спробовані, навіть якщо зміна розміру з вищим пріоритетом знову буде відкладена.
observedGenerationЦе стабільна функція в Kubernetes, яка загальнодоступна починаючи з версії v1.35. Вперше вона зʼявилась у випуску v1.33. Ви більше не можете вимкнути або відмовитися від цієї функції чи поведінки (це заблоковано); якщо ви явно встановите значення для повʼязаної функціональної можливості PodObservedGenerationTracking, Kubernetes проігнорує це, але не повідомить про помилку.
status.observedGeneration показує metadata.generation, що відповідає останній специфікації pod, яку визнала kubelet. Ви можете використовувати це, щоб визначити найостанніший запит на зміну розміру, який обробив kubelet.PodResizeInProgress поле conditions[].observedGeneration вказує на metadata.generation podSpec, коли була ініційована поточна зміна розміру.PodResizePending поле conditions[].observedGeneration вказує на metadata.generation podSpec, коли востаннє намагалися виділити ресурси для відкладеної зміни розміру.Ви можете вказати чи потрібно перезапускати контейнер під час зміни розміру за допомогою поля resizePolicy в специфікації контейнера. Це дозволяє докладний контроль за типами ресурсів (CPU чи memory).
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer
NotRequired: (типово) застосовувати зміну ресурсів без перезапуску контейнера.RestartContainer: перезапускати контейнер під час зміни ресурсів. Це часто необхідно для зміни memory оскільки багато застосунків та середовищ виконання не можуть підлаштовуватись до динамічної зміни виділення памʼяті.Якщо resizePolicy[*].restartPolicy не вказано для ресурсу, типовим значенням буде NotRequired.
restartPolicy має значення Never, тоді параметр resizePolicy кожного контейнера має бути NotRequired для всіх ресурсів. Ви не зможете налаштовувати зміну ресурсів, що вимагають перезапуску в таких PodʼахПриклад сценарію:
Уявіть контейнер з налаштованими restartPolicy: NotRequired для CPU та restartPolicy: RestartContainer для memory.
Щоб скористатися цією функцією, вам (або адміністратору кластера) потрібно увімкнути функціональну можливість InPlacePodVerticalScalingMemoryBackedVolumes для всіх відповідних компонентів у вашому кластері.
Перегляньте Увімкнення або вимкнення функціональних можливостей для отримання додаткової інформації.
Коли функціональну можливість InPlacePodVerticalScalingMemoryBackedVolumes увімкнено, субресурс Pod /resize підтримує оновлення sizeLimit томів emptyDir на основі памʼяті (medium: Memory) на запущених Podʼах без перезапуску контейнерів або перестворення Podʼа.
Коли sizeLimit тому оновлюється через субресурс /resize, Kubelet динамічно оновлює відповідне монтування tmpfs без переривання роботи контейнера, безпечно запобігаючи помилкам через брак памʼяті або хибним спрацьовуванням виселення.
Щоб змінити розмір тому emptyDir на основі памʼяті, оновіть spec.volumes[].emptyDir.sizeLimit, націлившись на субресурс resize Podʼа:
kubectl patch pod <pod-name> --subresource resize --patch \
'{"spec":{"volumes":[{"name":"cache-volume", "emptyDir":{"sizeLimit":"200Mi"}}]}}'
Ви можете відстежувати прогрес зміни розміру за допомогою станів статусу Podʼа (PodResizePending та PodResizeInProgress). Після завершення ви можете перевірити фактичну ємність тому всередині запущеного контейнера (наприклад, за допомогою kubectl exec, щоб виконати df -h).
Для Kubernetes 1.37 зміна розміру ресурсів podʼа на місці має наступні обмеження:
NotRequired (або не вказана), kubelet зробить спробу запобігти oom-kills при зменшенні лімітів памʼяті, але не надає жодних гарантій. Перед зменшенням лімітів памʼяті контейнера, якщо використання памʼяті перевищує запитуваний ліміт, зміна розміру буде пропущена, а статус залишиться в стані "In Progress". Це вважається найкращим варіантом, оскільки все ще існує ризик виникнення ситуації, коли використання памʼяті може різко зрости одразу після виконання перевірки.requests чи limits) не можуть бути додані (оскільки це призведе до зміни до Burstable або Guaranteed).resizePolicy для memory не встановлено у RestartContainer.emptyDir на основі памʼяті (medium: Memory) на місці вимагає вузлів, що працюють з cgroup v2. На вузлах з cgroup v1 запити на зміну розміру томів на місці відхиляються як неможливі. Томи emptyDir на основі диска та постійні томи не можуть бути змінені через субресурс Pod /resize.Ці обмеження можуть бути послаблені в наступних версіях Kubernetes.
Створіть простір імен, щоб ресурси, які ви створюєте в цій вправі, були ізольовані від решти кластера.
kubectl create namespace qos-example
Спочатку, створіть Pod створений для зміни розміру CPU на місці та такий що вимагає перезапуску під час зміни memory.
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
namespace: qos-example
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.8
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Це типове значення, вказане тут явно
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
Створіть Pod:
kubectl create -f pod-resize.yaml -n qos-example
Цей Pod запускається з класом Guaranteed QoS. Перевірте його початковий стан:
# Почекайте трохи доки pod запуститься
kubectl get pod resize-demo --output=yaml -n qos-example
Погляньте на spec.containers[0].resources та status.containerStatuses[0].resources. Вони мають відповідати маніфесту (700m CPU, 200Mi memory). Зверніть увагу на status.containerStatuses[0].restartCount (має бути 0).
Тепер збільште запит та ліміт CPU до 800m. Використовуйте kubectl patch з аргументом командного рядка --subresource resize.
kubectl patch pod resize-demo -n qos-example --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'
# Альтернативні методи:
# kubectl -n qos-example edit pod resize-demo --subresource resize
# kubectl -n qos-example apply -f <updated-manifest> --subresource resize --server-side
--subresource resize у вас має бути версія клієнта kubectl не менша ніж v1.32.0.Перевірте стан podʼа після накладання латки:
kubectl get pod resize-demo --output=yaml --namespace=qos-example
Ви маєте побачити:
spec.containers[0].resources тепер показує cpu: 800m.status.containerStatuses[0].resources також показує cpu: 800m, що означає, що зміна розміру на вузлі відбулась.status.containerStatuses[0].restartCount залишається 0, оскільки CPU resizePolicy було NotRequired.Тепер змінимо розмір memory в тому ж поді збільшивши її до 300Mi. Оскільки memory resizePolicy має значення RestartContainer, контейнер має перезапуститись.
kubectl patch pod resize-demo -n qos-example --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"memory":"300Mi"}, "limits":{"memory":"300Mi"}}}]}}'
Перевірте стан podʼа невдовзі після застосування латки:
kubectl get pod resize-demo --output=yaml --namespace=qos-example
Ви маєте побачити:
spec.containers[0].resources показує memory: 300Mi.status.containerStatuses[0].resources також показує memory: 300Mi.status.containerStatuses[0].restartCount збільшився до 1 (або більше, якщо до цього вже відбувались перезапуски), що вказує на те, що контейнер було перезапущено після застосування зміни розміру memory.Далі, спробуємо запитати якесь неможливе значення CPU, наприклад 1000 цілих ядер (записується як "1000", в той час, коли йдеться про міліядра це — "1000m"), що очевидно перевищує можливості вузла.
# Спроба застосувати латку з запитом явно більшої кількістю CPU
kubectl patch pod resize-demo -n qos-example --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"1000"}, "limits":{"cpu":"1000"}}}]}}'
Запитайте інформацію Podʼа:
kubectl get pod resize-demo --output=yaml --namespace=qos-example
Ви побачите зміни, що сповіщають про проблему:
spec.containers[0].resources показує бажаний стан (cpu: "1000").type: PodResizePending та reason: Infeasible було додано до Pod.message буде містити пояснення (Node didn't have enough capacity: cpu, requested: 800000, capacity: ...)status.containerStatuses[0].resources буде все ще показувати попередні значення (cpu: 800m, memory: 300Mi), тому що неможлива зміна розміру не була застосована Kubelet.restartCount не зміниться через невдалу спробу.Щоб виправити це, вам потрібно застосувати латку до podʼа з прийнятними параметрами.
Видаліть свій простір імен. Це видалить усі Podʼи, які ви створили для цього завдання:
kubectl delete namespace qos-example