Ресурсы контейнера - ядра ЦПУ и оперативная память - в Kubernetes регулируются через requests и limits.
- Requests - это то количество ресурсов, которые контейнер в Поде скорей всего будет потреблять. Оркестратор использует эти значения, чтобы определить на какой сервер поместить Под.
- Limits - это жесткий лимит, который на уровне операционной системы выставляет cgroup на контейнер. Больше этих значений контейнер не сможет потребить ресурсов.
Проблема в том, что если необходимо изменить количество ресурсов, то Под нужно перезагрузить. Особенно это проблематично, если речь идет об автоматическом изменении ресурсов (VPA - Vertical Pod Autoscaler). В этом блоге мы рассмотрим in-place Pod resize, который впервые был добавлен в Kubernetes 1.27. Претерпев существенные изменения, он все так же остается в альфа стадии в 1.29. Но уже сейчас можно попробовать изменить ресурсы, не перезагружая Под.
Создание кластера
In-place доступен только через feature gates, поэтому есть вероятность что попробовать его на каком-нибудь сервисе не будет возможности. Например, только недавно Google Kubernetes Engine (GKE) разрешил протестировать этот функционал. Чтобы вы могли легко воспроизвести мои шаги, я буду использовать kind. Его можно развернуть локально или на любой виртуальной машине.
Перед установкой kind нужно установить docker (или podman) и kubectl. Самый быстрый способ установить kind, это скачать бинарник:
curl -L "https://kind.sigs.k8s.io/dl/v0.22.0/kind-$(uname)-amd64" -o /usr/local/bin/kind
chmod +x /usr/local/bin/kind
Запустим простейший кластер из следующего манифеста:
# cat kind.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
image: kindest/node:v1.29.0
- role: worker
image: kindest/node:v1.29.0
# kind create cluster --config kind.yaml
Без InPlacePodVerticalScaling
Запустим тестовый под с nginx:
# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: resize-test
spec:
containers:
- name: nginx
image: nginx:1.25.4
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
# kubectl apply -f nginx.yaml
Если мы попробуем изменить, например, requests.cpu, то получим ошибку:
resources:
requests:
- cpu: "250m"
+ cpu: "300m"
memory: "128Mi"
# kubectl apply -f nginx.yaml
The Pod "resize-test" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`,`spec.initContainers[*].image`,`spec.activeDeadlineSeconds`,`spec.tolerations` (only additions to existing tolerations),`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
...
Если бы у нас был Deployment или StatefulSet, то при их изменении был бы создан новый Pod, а старый уничтожен.
Включаем InPlacePodVerticalScaling
Уничтожим кластер:
kind delete cluster
Создаем новый кластер с включением нужного feature gate:
# cat kind.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
"InPlacePodVerticalScaling": true
nodes:
- role: control-plane
image: kindest/node:v1.29.0
- role: worker
image: kindest/node:v1.29.0
# kind create cluster --config kind.yaml
Создаем тот самый Pod nginx:
kubectl apply -f nginx.yaml
Попробуем теперь изменить requests.cpu:
resources:
requests:
- cpu: "300m"
+ cpu: "350m"
memory: "128Mi"
# kubectl apply -f nginx.yaml
Изменения применятся без ошибок. Проверяем, что под не перезагружался и новые параметры на месте:
# kubectl describe pod resize-test
...
Limits:
cpu: 500m
memory: 256Mi
Requests:
cpu: 350m
memory: 128Mi
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m59s default-scheduler Successfully assigned default/resize-test to kind-worker
Normal Pulling 2m58s kubelet Pulling image "nginx:1.25.4"
Normal Pulled 2m53s kubelet Successfully pulled image "nginx:1.25.4" in 5.292s (5.292s including waiting)
Normal Created 2m53s kubelet Created container nginx
Normal Started 2m53s kubelet Started container nginx
В Events никаких новых событий с запуска Пода.
Заключение
В заключение, функционал in-place Pod resize в Kubernetes открывает новые возможности для управления ресурсами контейнеров, значительно упрощая процесс масштабирования приложений в реальном времени без необходимости перезапуска Подов. Это особенно ценно для динамических сред, где требования к ресурсам могут часто изменяться. Хотя функция все еще находится в альфа-версии, ее потенциал и удобство использования уже очевидны, и она обещает стать важным инструментом в арсенале разработчиков Kubernetes.
Нужна помощь с Kubernetes? Свяжитесь с Лабораторией.