How do I add a master nodes to a cloud cluster (single-master to a multi-master)? | |||||||||||||||||||||||||||||||||||||||||||||||||||||
Как добавить master-узлы в облачном кластере? | |||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I reduce the number of master nodes in a cloud cluster (multi-master to single-master)? | Как конвертировать кластер с одним master-узлом в мультикластерный описано в FAQ модуля control-plane-manager. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Static nodes | Как уменьшить число master-узлов в облачном кластере? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Как конвертировать мультимастерный кластер в кластер с одним master-узлом описано в FAQ модуля control-plane-manager. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You can add a static node to the cluster manually (an example) or by using Cluster API Provider Static. | Статические узлы | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I add a static node to a cluster (Cluster API Provider Static)? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
To add a static node to a cluster (bare metal server or virtual machine), follow these steps: | Добавить статический узел в кластер можно вручную (пример) или с помощью Cluster API Provider Static. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Как добавить статический узел в кластер (Cluster API Provider Static)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Чтобы добавить статический узел в кластер (сервер bare-metal или виртуальную машину), выполните следующие шаги: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell useradd -m -s /bin/bash caps usermod -aG sudo caps |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell caps ALL=(ALL) NOPASSWD: ALL | shell useradd -m -s /bin/bash caps usermod -aG sudo caps | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell sudo systemctl restart sshd | shell caps ALL=(ALL) NOPASSWD: ALL | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell ssh-keygen -t rsa -f caps-id -C “” -N “” | shell sudo systemctl restart sshd | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The public and private keys of the caps user will be stored in the |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell ssh-keygen -t rsa -f caps-id -C “” -N “” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell mkdir -p /home/caps/.ssh cat caps-id.pub » /home/caps/.ssh/authorized_keys chmod 700 /home/caps/.ssh chmod 600 /home/caps/.ssh/authorized_keys chown -R caps:caps /home/caps/ | Приватный и публичный ключи будут сохранены в файлах | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
An example of adding a static node. | shell mkdir -p /home/caps/.ssh cat caps-id.pub » /home/caps/.ssh/authorized_keys chmod 700 /home/caps/.ssh chmod 600 /home/caps/.ssh/authorized_keys chown -R caps:caps /home/caps/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I add a batch of static nodes to a cluster manually? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Use an existing one or create a new NodeGroup custom resource (example of the | Пример добавления статического узла. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You can automate the bootstrap process with any automation platform you prefer. The following is an example for Ansible. | Как добавить несколько статических узлов в кластер вручную? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Используйте существующий или создайте новый кастомный ресурс (Custom Resource) NodeGroup (пример | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell kubectl -n default get ep kubernetes -o json | jq ‘.subsets[0].addresses[0].ip + “:” + (.subsets[0].ports[0].port | tostring)’ -r | Автоматизировать процесс добавления узлов можно с помощью любой платформы автоматизации. Далее приведен пример для Ansible. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Check the K8s version. If the version >= 1.25, create |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell kubectl create token node-group –namespace d8-cloud-instance-manager –duration 1h | shell kubectl -n default get ep kubernetes -o json | jq ‘.subsets[0].addresses[0].ip + “:” + (.subsets[0].ports[0].port | tostring)’ -r | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Save the token you got and add it to the | Проверьте версию K8s. Если версия >= 1.25, создайте токен | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell kubectl create token node-group –namespace d8-cloud-instance-manager –duration 1h | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl -n d8-cloud-instance-manager get $(kubectl -n d8-cloud-instance-manager get secret -o name | grep node-group-token) | Сохраните полученный токен, и добавьте в поле | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl -n d8-cloud-instance-manager get $(kubectl -n d8-cloud-instance-manager get secret -o name | grep node-group-token) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| yaml
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
text [system] system-0 system-1 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
[system:vars] node_group=system |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
[worker] worker-0 worker-1 | text [system] system-0 system-1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[worker:vars] node_group=worker | [system:vars] node_group=system | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| [worker] worker-0 worker-1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I clean up a static node manually? | [worker:vars] node_group=worker | ||||||||||||||||||||||||||||||||||||||||||||||||||||
This method is valid for both manually configured nodes (using the bootstrap script) and nodes configured using CAPS. |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
To decommission a node from the cluster and clean up the server (VM), run the following command on the node: | Как вручную очистить статический узел? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Can I delete a StaticInstance? | Инструкция справедлива как для узла, настроенного вручную (с помощью бутстрап-скрипта), так и для узла, настроенного с помощью CAPS. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
A StaticInstance that is in the | Чтобы вывести из кластера узел и очистить сервер (ВМ), выполните следующую команду на узле: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
To delete a StaticInstance in any state other than | shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Можно ли удалить StaticInstance? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example command for adding a label: | StaticInstance, находящийся в состоянии | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell d8 k label staticinstance d8cluster-worker node.deckhouse.io/allow-bootstrap=false | Чтобы удалить StaticInstance находящийся в любом состоянии, отличном от | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
To check the status of StaticInstance, use the command: | Пример команды для добавления лейбла: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell d8 k get staticinstances | shell d8 k label staticinstance d8cluster-worker node.deckhouse.io/allow-bootstrap=false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example command for deleting StaticInstance: | Для проверки статуса StaticInstance используйте команду: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell d8 k delete staticinstance d8cluster-worker | shell d8 k get staticinstances | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I change the IP address of a StaticInstance? | Пример команды для удаления StaticInstance: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You cannot change the IP address in the | shell d8 k delete staticinstance d8cluster-worker | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I migrate a manually configured static node under CAPS control? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
You need to clean up the node, then hand over the node under CAPS control. | Как изменить IP-адрес StaticInstance? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I change the NodeGroup of a static node? | Изменить IP-адрес в ресурсе | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Note that if a node is under CAPS control, you cannot change the | Как мигрировать статический узел настроенный вручную под управление CAPS? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
To switch an existing manually created static node to another | Необходимо выполнить очистку узла, затем добавить узел под управление CAPS. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl label node –overwrite | Как изменить NodeGroup у статического узла? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Applying the changes will take some time. |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to clean up a node for adding to the cluster? | Если узел находится под управлением CAPS, то изменить принадлежность к | ||||||||||||||||||||||||||||||||||||||||||||||||||||
This is only needed if you have to move a static node from one cluster to another. Be aware these operations remove local storage data. If you just need to change a NodeGroup, follow this instruction. | Чтобы перенести существующий статический узел созданный вручную из одной | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Evict resources from the node and remove the node from LINSTOR/DRBD using the instruction if the node you are cleaning up has LINSTOR/DRBD storage pools. | shell
kubectl label node –overwrite | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Применение изменений потребует некоторого времени. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl drain | Как очистить узел для последующего ввода в кластер? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Это необходимо только в том случае, если нужно переместить статический узел из одного кластера в другой. Имейте в виду, что эти операции удаляют данные локального хранилища. Если необходимо просто изменить | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing | Если на зачищаемом узле есть пулы хранения LINSTOR/DRBD, то предварительно перенесите ресурсы с узла и удалите узел LINSTOR/DRBD, следуя инструкции. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I know if something went wrong? | shell
kubectl drain | ||||||||||||||||||||||||||||||||||||||||||||||||||||
If a node in a nodeGroup is not updated (the value of |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
To view the logs of the | shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell journalctl -fu bashible |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of output when the | Как понять, что что-то пошло не так? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console May 25 04:39:16 kube-master-0 systemd[1]: Started Bashible service. May 25 04:39:16 kube-master-0 bashible.sh[1976339]: Configuration is in sync, nothing to do. May 25 04:39:16 kube-master-0 systemd[1]: bashible.service: Succeeded. | Если узел в NodeGroup не обновляется (значение | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I know what is running on a node while it is being created? | Чтобы проверить логи сервиса | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You can analyze | shell journalctl -fu bashible | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Пример вывода, когда все необходимые действия выполнены: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell kubectl get instances | grep Pending | console May 25 04:39:16 kube-master-0 systemd[1]: Started Bashible service. May 25 04:39:16 kube-master-0 bashible.sh[1976339]: Configuration is in sync, nothing to do. May 25 04:39:16 kube-master-0 systemd[1]: bashible.service: Succeeded. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
An example: | Как посмотреть, что в данный момент выполняется на узле при его создании? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell $ kubectl get instances | grep Pending dev-worker-2a6158ff-6764d-nrtbj Pending 46s | Если необходимо узнать, что происходит на узле (например, узел долго создается), можно проверить логи | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell kubectl get instances dev-worker-2a6158ff-6764d-nrtbj -o yaml | grep ‘bootstrapStatus’ -B0 -A2 | shell kubectl get instances | grep Pending | ||||||||||||||||||||||||||||||||||||||||||||||||||||
An example: | Пример: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell $ kubectl get instances dev-worker-2a6158ff-6764d-nrtbj -o yaml | grep ‘bootstrapStatus’ -B0 -A2 bootstrapStatus: description: Use ‘nc 192.168.199.178 8000’ to get bootstrap logs. logsEndpoint: 192.168.199.178:8000 | shell $ kubectl get instances | grep Pending dev-worker-2a6158ff-6764d-nrtbj Pending 46s | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
The logs of the initial node configuration are located at | shell kubectl get instances dev-worker-2a6158ff-6764d-nrtbj -o yaml | grep ‘bootstrapStatus’ -B0 -A2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I update kernel on nodes? | Пример: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Debian-based distros | shell $ kubectl get instances dev-worker-2a6158ff-6764d-nrtbj -o yaml | grep ‘bootstrapStatus’ -B0 -A2 bootstrapStatus: description: Use ‘nc 192.168.199.178 8000’ to get bootstrap logs. logsEndpoint: 192.168.199.178:8000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Create a |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:
| Логи первоначальной настройки узла находятся в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
desired_version=”5.15.0-53-generic” | Как обновить ядро на узлах? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bb-event-on ‘bb-package-installed’ ‘post-install’ post-install() { bb-log-info “Setting reboot flag due to kernel was updated” bb-flag-set reboot } | Для дистрибутивов, основанных на Debian | ||||||||||||||||||||||||||||||||||||||||||||||||||||
version_in_use=”$(uname -r)” | Создайте ресурс | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if [[ “$version_in_use” == “$desired_version” ]]; then exit 0 fi | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
bb-deckhouse-get-disruptive-update-approval bb-apt-install “linux-image-${desired_version}” | desired_version=”5.15.0-53-generic” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
CentOS-based distros | bb-event-on ‘bb-package-installed’ ‘post-install’ post-install() { bb-log-info “Setting reboot flag due to kernel was updated” bb-flag-set reboot } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Create a | version_in_use=”$(uname -r)” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:
| if [[ “$version_in_use” == “$desired_version” ]]; then exit 0 fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
desired_version=”3.10.0-1160.42.2.el7.x86_64” | bb-deckhouse-get-disruptive-update-approval bb-apt-install “linux-image-${desired_version}” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bb-event-on ‘bb-package-installed’ ‘post-install’ post-install() { bb-log-info “Setting reboot flag due to kernel was updated” bb-flag-set reboot } | Для дистрибутивов, основанных на CentOS | ||||||||||||||||||||||||||||||||||||||||||||||||||||
version_in_use=”$(uname -r)” | Создайте ресурс | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if [[ “$version_in_use” == “$desired_version” ]]; then exit 0 fi | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
bb-deckhouse-get-disruptive-update-approval bb-dnf-install “kernel-${desired_version}” | desired_version=”3.10.0-1160.42.2.el7.x86_64” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
NodeGroup parameters and their result | bb-event-on ‘bb-package-installed’ ‘post-install’ post-install() { bb-log-info “Setting reboot flag due to kernel was updated” bb-flag-set reboot } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| version_in_use=”$(uname -r)” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Refer to the description of the NodeGroup custom resource for more information about the parameters. | if [[ “$version_in_use” == “$desired_version” ]]; then exit 0 fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Changing the | bb-deckhouse-get-disruptive-update-approval bb-dnf-install “kernel-${desired_version}” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
During the disruption update, an evict of the pods from the node is performed. If any pod failes to evict, the evict is repeated every 20 seconds until a global timeout of 5 minutes is reached. After that, the pods that failed to evict are removed. | Какие параметры NodeGroup к чему приводят? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I redeploy ephemeral machines in the cloud with a new configuration? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
If the Deckhouse configuration is changed (both in the node-manager module and in any of the cloud providers), the VMs will not be redeployed. The redeployment is performed only in response to changing | Подробно о всех параметрах можно прочитать в описании кастомного ресурса NodeGroup. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
To force the redeployment of all Machines, you need to add/modify the | В случае изменения параметров | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I allocate nodes to specific loads? | При обновлении, которое требует прерывания работы узла (disruption update), выполняется процесс вытеснения подов с узла. Если какой-либо под не может быть вытеснен, попытка повторяется каждые 20 секунд до достижения глобального таймаута в 5 минут. После истечения этого времени, поды, которые не удалось вытеснить, удаляются принудительно. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You cannot use the | Как пересоздать эфемерные машины в облаке с новой конфигурацией? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There are two ways to solve this problem: | При изменении конфигурации Deckhouse (как в модуле | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Чтобы принудительно пересоздать все узлы, связанные с ресурсом | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Deckhouse tolerates the | Как выделить узлы под специфические нагрузки? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
To use custom keys for | Запрещено использование домена | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to allocate nodes to system components? | Для решений данной задачи существуют два механизма: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frontend |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
For Ingress controllers, use the | Deckhouse по умолчанию поддерживает использование taint’а с ключом | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml nodeTemplate: labels: node-role.deckhouse.io/frontend: “” taints:
| Если требуется использовать другие ключи для taints (например, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
System components | Подробности в статье на Habr. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Как выделить узлы под системные компоненты? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml nodeTemplate: labels: node-role.deckhouse.io/system: “” taints:
| Фронтенд | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I speed up node provisioning on the cloud when scaling applications horizontally? | Для Ingress-контроллеров используйте | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The most efficient way is to have some extra nodes “ready”. In this case, you can run new application replicas on them almost instantaneously. The obvious disadvantage of this approach is the additional maintenance costs related to these nodes. | yaml nodeTemplate: labels: node-role.deckhouse.io/frontend: “” taints:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Here is how you should configure the target | Системные | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Для компонентов подсистем Deckhouse параметр | ||||||||||||||||||||||||||||||||||||||||||||||||||||
An example: | yaml nodeTemplate: labels: node-role.deckhouse.io/system: “” taints:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml cloudInstances: maxPerZone: 10 minPerZone: 1 standby: 10% standbyHolder: overprovisioningRate: 30% | Как ускорить заказ узлов в облаке при горизонтальном масштабировании приложений? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I disable machine-controller-manager/CAPI in the case of potentially cluster-damaging changes? | Самое действенное — держать в кластере некоторое количество предварительно подготовленных узлов, которые позволят новым репликам ваших приложений запускаться мгновенно. Очевидным минусом данного решения будут дополнительные расходы на содержание этих узлов. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Use this switch only if you know what you are doing and clearly understand the consequences. | Необходимые настройки целевой | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Set the |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml mcmEmergencyBrake: true | Пример: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
For disabling CAPI, set the | yaml cloudInstances: maxPerZone: 10 minPerZone: 1 standby: 10% standbyHolder: overprovisioningRate: 30% | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml capiEmergencyBrake: true | Как выключить machine-controller-manager/CAPI в случае выполнения потенциально деструктивных изменений в кластере? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I restore the master node if kubelet cannot load the control plane components? | Использовать эту настройку допустимо только тогда, когда вы четко понимаете, зачем это необходимо. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Such a situation may occur if images of the control plane components on the master were deleted in a cluster that has a single master node (e.g., the directory | Для того чтобы временно отключить machine-controller-manager (MCM) и предотвратить его автоматические действия, которые могут повлиять на инфраструктуру кластера (например, удаление или пересоздание узлов), установите следующий параметр в конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Below is an instruction on how you can restore the master node. | yaml mcmEmergencyBrake: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
containerd | Для отключения CAPI установите следующий параметр в конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Execute the following command to restore the master node in any cluster running under Deckhouse: | yaml capiEmergencyBrake: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell kubectl -n d8-system get secrets deckhouse-registry -o json | jq -r ‘.data.”.dockerconfigjson”’ | base64 -d | jq -r ‘.auths.”registry.deckhouse.io”.auth’ | Как восстановить master-узел, если kubelet не может загрузить компоненты control plane? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Copy the command’s output and use it for setting the | Подобная ситуация может возникнуть, если в кластере с одним master-узлом на нем были удалены образы компонентов control plane (например, удалена директория | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Next, you need to pull images of | Далее приведена инструкция по восстановлению master-узла. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell for image in $(grep “image:” /etc/kubernetes/manifests/* | awk ‘{print $3}’); do crictl pull –auth $AUTH $image done | containerd | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You need to restart | Для восстановления работоспособности master-узла нужно в любом рабочем кластере под управлением Deckhouse выполнить команду: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to change CRI for NodeGroup? | shell kubectl -n d8-system get secrets deckhouse-registry -o json | jq -r ‘.data.”.dockerconfigjson”’ | base64 -d | jq -r ‘.auths.”registry.deckhouse.io”.auth’ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
CRI can only be switched from | Вывод команды нужно скопировать и присвоить переменной | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Set NodeGroup | Далее на поврежденном master-узле нужно загрузить образы компонентов | ||||||||||||||||||||||||||||||||||||||||||||||||||||
NodeGroup YAML example: | shell for image in $(grep “image:” /etc/kubernetes/manifests/* | awk ‘{print $3}’); do crictl pull –auth $AUTH $image done | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: nodeType: Static cri: type: Containerd | После загрузки образов необходимо перезапустить | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Also, this operation can be done with patch: | Как изменить CRI для NodeGroup? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Смена CRI возможна только между | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl patch nodegroup | Для изменения CRI для NodeGroup, установите параметр cri.type в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Пример YAML-манифеста NodeGroup: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl patch nodegroup | yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: nodeType: Static cri: type: Containerd | ||||||||||||||||||||||||||||||||||||||||||||||||||||
While changing | Также эту операцию можно выполнить с помощью патча: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
After setting up a new CRI for NodeGroup, the node-manager module drains nodes one by one and installs a new CRI on them. Node update
is accompanied by downtime (disruption). Depending on the |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to change CRI for the whole cluster? | shell kubectl patch nodegroup <имя NodeGroup=""> --type merge -p '{"spec":{"cri":{"type":"Containerd"}}}'имя> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
CRI can only be switched from |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
It is necessary to use the | shell kubectl patch nodegroup <имя NodeGroup=""> --type merge -p '{"spec":{"cri":{"type":"NotManaged"}}}'имя> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Also, this operation can be done with the following patch: | При изменении | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| После изменения CRI для NodeGroup модуль | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell data=”$(kubectl -n kube-system get secret d8-cluster-configuration -o json | jq -r ‘.data.”cluster-configuration.yaml”’ | base64 -d | sed “s/NotManaged/Containerd/” | base64 -w0)” kubectl -n kube-system patch secret d8-cluster-configuration -p “{"data":{"cluster-configuration.yaml":"$data"}}” | Как изменить CRI для всего кластера? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Смена CRI возможна только между | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell data=”$(kubectl -n kube-system get secret d8-cluster-configuration -o json | jq -r ‘.data.”cluster-configuration.yaml”’ | base64 -d | sed “s/Containerd/NotManaged/” | base64 -w0)” kubectl -n kube-system patch secret d8-cluster-configuration -p “{"data":{"cluster-configuration.yaml":"$data"}}” | Для изменения CRI для всего кластера, необходимо с помощью утилиты | ||||||||||||||||||||||||||||||||||||||||||||||||||||
If it is necessary to leave some NodeGroup on another CRI, then before changing the | Также возможно выполнить эту операцию с помощью | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Changing |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
When changing the CRI in the cluster, additional steps are required for the master nodes: | shell data=”$(kubectl -n kube-system get secret d8-cluster-configuration -o json | jq -r ‘.data.”cluster-configuration.yaml”’ | base64 -d | sed “s/NotManaged/Containerd/” | base64 -w0)” kubectl -n kube-system patch secret d8-cluster-configuration -p “{"data":{"cluster-configuration.yaml":"$data"}}” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell kubectl get nodes -l node-role.kubernetes.io/control-plane=”” -o json | jq ‘.items[] | select(.metadata.annotations.”update.node.deckhouse.io/approved”==””) | .metadata.name’ -r | shell data=”$(kubectl -n kube-system get secret d8-cluster-configuration -o json | jq -r ‘.data.”cluster-configuration.yaml”’ | base64 -d | sed “s/Containerd/NotManaged/” | base64 -w0)” kubectl -n kube-system patch secret d8-cluster-configuration -p “{"data":{"cluster-configuration.yaml":"$data"}}” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если необходимо, чтобы отдельные NodeGroup использовали другой CRI, перед изменением | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shell
kubectl annotate node | Изменение | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| При изменении CRI в кластере для master-узлов необходимо выполнить дополнительные шаги: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to add node configuration step? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Additional node configuration steps are set via the NodeGroupConfiguration custom resource. | shell kubectl get nodes -l node-role.kubernetes.io/control-plane=”” -o json | jq ‘.items[] | select(.metadata.annotations.”update.node.deckhouse.io/approved”==””) | .metadata.name’ -r | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to automatically put custom labels on the node? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell kubectl annotate node <имя master-узла=""> update.node.deckhouse.io/disruption-approved=имя> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Как добавить шаг для конфигурации узлов? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console example-label=test | Дополнительные шаги для конфигурации узлов задаются с помощью кастомного ресурса NodeGroupConfiguration. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Как автоматически проставить на узел кастомные лейблы? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
When adding a node to the cluster, the labels specified in the files will be automatically affixed to the node. |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Please note that it is not possible to add labels used in DKP in this way. This method will only work with custom labels that do not overlap with those reserved for Deckhouse. |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to deploy custom containerd configuration? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
The example of | console example-label=test | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Adding custom settings causes a restart of the containerd service. |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bashible on nodes merges main Deckhouse containerd config with configs from | При добавлении узла в кластер указанные в файлах лейблы будут автоматически проставлены на узел. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
You can override the values of the parameters that are specified in the file | Обратите внимание, что добавить таким образом лейблы, использующиеся в DKP, невозможно. Работать такой метод будет только с кастомными лейблами, не пересекающимися с зарезервированными для Deckhouse. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-option-config.sh spec: bundles:
| Как развернуть кастомный конфигурационный файл containerd? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_option.toml - « EOF oom_score = 500 [metrics] address = “127.0.0.1” grpc_histogram = true EOF nodeGroups:
| Пример | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to add configuration for an additional registry? | Добавление кастомных настроек вызывает перезапуск сервиса containerd. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Containerd supports two methods for registry configuration: the old method and the new method. To check for the presence of the old configuration method, run the following commands on the cluster nodes: | Bashible на узлах объединяет конфигурацию containerd для Deckhouse с конфигурацией из файла | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash cat /etc/containerd/config.toml | grep ‘plugins.”io.containerd.grpc.v1.cri”.registry.mirrors’ cat /etc/containerd/config.toml | grep ‘plugins.”io.containerd.grpc.v1.cri”.registry.configs’ | Вы можете переопределять значения параметров, которые заданы в файле | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example output: | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-option-config.sh spec: bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
[plugins.”io.containerd.grpc.v1.cri”.registry.mirrors] | mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_option.toml - « EOF oom_score = 500 [metrics] address = “127.0.0.1” grpc_histogram = true EOF nodeGroups:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
[plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.” | Как добавить конфигурацию для дополнительного registry? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[plugins.”io.containerd.grpc.v1.cri”.registry.configs] | В containerd существует два способа описания конфигурации registry: старый и новый. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[plugins.”io.containerd.grpc.v1.cri”.registry.configs.” | Для проверки наличия старого способа конфигурации выполните на узлах кластера следующие команды: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
To check for the presence of the new configuration method, run the following command on the cluster nodes: | bash cat /etc/containerd/config.toml | grep ‘plugins.”io.containerd.grpc.v1.cri”.registry.mirrors’ cat /etc/containerd/config.toml | grep ‘plugins.”io.containerd.grpc.v1.cri”.registry.configs’ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash cat /etc/containerd/config.toml | grep ‘/etc/containerd/registry.d’ | Пример вывода: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example output: | [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config_path = “/etc/containerd/registry.d” | [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Old Method | [plugins.”io.containerd.grpc.v1.cri”.registry.configs] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
This containerd configuration format is deprecated. | [plugins.”io.containerd.grpc.v1.cri”.registry.configs.” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The configuration is described in the main containerd configuration file | Для проверки наличия нового способа конфигурации выполните на узлах кластера следующую команду: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
toml [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.”${REGISTRY_URL}”] endpoint = [“https://${REGISTRY_URL}”] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.auth] auth = “${BASE_64_AUTH}” username = “${USERNAME}” password = “${PASSWORD}” [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] ca_file = “${CERT_DIR}/${CERT_NAME}.crt” insecure_skip_verify = true | bash cat /etc/containerd/config.toml | grep ‘/etc/containerd/registry.d’ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Adding custom settings through the | Пример вывода: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to add additional registry auth (old method)? | config_path = “/etc/containerd/registry.d” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of adding authorization to a additional registry when using the old configuration method: | Старый способ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: To add a file before the ‘032_configure_containerd.sh’ step weight: 31 bundles:
| Этот формат конфигурации containerd устарел (deprecated). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - « EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.”${REGISTRY_URL}”] endpoint = [“https://${REGISTRY_URL}”] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.auth] username = “username” password = “password” OR auth = “dXNlcm5hbWU6cGFzc3dvcmQ=” EOF | Конфигурация описывается в основном конфигурационном файле containerd | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to configure a certificate for an additional registry (old method)? | Пользовательская конфигурация добавляется через механизм | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of configuring a certificate for an additional registry when using the old configuration method: | Пример конфигурационного файла для директории | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-tls.sh spec: To add a file before the ‘032_configure_containerd.sh’ step weight: 31 bundles:
| toml [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.”${REGISTRY_URL}”] endpoint = [“https://${REGISTRY_URL}”] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.auth] auth = “${BASE_64_AUTH}” username = “${USERNAME}” password = “${PASSWORD}” [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] ca_file = “${CERT_DIR}/${CERT_NAME}.crt” insecure_skip_verify = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p ${CERTS_FOLDER} bb-sync-file “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” - « EOF —–BEGIN CERTIFICATE—– … —–END CERTIFICATE—– EOF | Добавление кастомных настроек через механизм | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - « EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] ca_file = “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” EOF | Как добавить авторизацию в дополнительный registry (старый способ)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
In addition to containerd, the certificate can be added into the OS. | Пример добавления авторизации в дополнительный registry при использовании старого способа конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to add TLS skip verify (old method)? | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: Для добавления файла перед шагом ‘032_configure_containerd.sh’ weight: 31 bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of adding TLS skip verify when using the old configuration method: | mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - « EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.”${REGISTRY_URL}”] endpoint = [“https://${REGISTRY_URL}”] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.auth] username = “username” password = “password” OR auth = “dXNlcm5hbWU6cGFzc3dvcmQ=” EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-skip-tls.sh spec: To add a file before the ‘032_configure_containerd.sh’ step weight: 31 bundles:
| Как настроить сертификат для дополнительного registry (старый способ)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - « EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] insecure_skip_verify = true EOF | Пример настройки сертификата для дополнительного registry при использовании старого способа конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
After applying the configuration file, verify access to the registry from the nodes using the command: | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-tls.sh spec: Для добавления файла перед шагом ‘032_configure_containerd.sh’ weight: 31 bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash | mkdir -p ${CERTS_FOLDER} bb-sync-file “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” - « EOF —–BEGIN CERTIFICATE—– … —–END CERTIFICATE—– EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Via the CRI interface crictl pull private.registry.example/image/repo:tag | mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - « EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] ca_file = “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
New Method | Помимо сontainerd, сертификат можно добавить в операционную систему. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Used in containerd v2. | Как добавить TLS skip verify (старый способ)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The configuration is defined in the | Пример добавления TLS skip verify при использовании старого способа конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash /etc/containerd/registry.d ├── private.registry.example:5001 │ ├── ca.crt │ └── hosts.toml └── registry.deckhouse.ru ├── ca.crt └── hosts.toml | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-skip-tls.sh spec: Для добавления файла перед шагом ‘032_configure_containerd.sh’ weight: 31 bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example contents of the | mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - « EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.registry] [plugins.”io.containerd.grpc.v1.cri”.registry.configs] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] insecure_skip_verify = true EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
toml [host] Mirror 1 [host.”https://${REGISTRY_URL_1}”] capabilities = [“pull”, “resolve”] ca = [”${CERT_DIR}/${CERT_NAME}.crt”] | После применения конфигурационного файла проверьте доступ к registry с узлов, используя команду: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[host.”https://${REGISTRY_URL_1}”.auth] username = “${USERNAME}” password = “${PASSWORD}” | bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Mirror 2 [host.”http://${REGISTRY_URL_2}”] capabilities = [“pull”, “resolve”] skip_verify = true | Через cri-интерфейс crictl pull private.registry.example/image/repo:tag | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Configuration changes do not cause the containerd service to restart. | Новый способ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to add additional registry auth (new method)? | Используется в containerd v2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of adding authorization to a additional registry when using the new configuration method: | Конфигурация описывается в каталоге | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: The step can be arbitrary, as restarting the containerd service is not required weight: 0 bundles:
| bash /etc/containerd/registry.d ├── private.registry.example:5001 │ ├── ca.crt │ └── hosts.toml └── registry.deckhouse.ru ├── ca.crt └── hosts.toml | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p “/etc/containerd/registry.d/${REGISTRY_URL}” bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml” - « EOF [host] [host.”https://${REGISTRY_URL}”] capabilities = [“pull”, “resolve”] [host.”https://${REGISTRY_URL}”.auth] username = “username” password = “password” EOF | Пример содержимого файла | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to configure a certificate for an additional registry (new method)? | toml [host] Mirror 1 [host.”https://${REGISTRY_URL_1}”] capabilities = [“pull”, “resolve”] ca = [”${CERT_DIR}/${CERT_NAME}.crt”] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of configuring a certificate for an additional registry when using the new configuration method: | [host.”https://${REGISTRY_URL_1}”.auth] username = “${USERNAME}” password = “${PASSWORD}” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-tls.sh spec: The step can be arbitrary, as restarting the containerd service is not required weight: 0 bundles:
| Mirror 2 [host.”http://${REGISTRY_URL_2}”] capabilities = [“pull”, “resolve”] skip_verify = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p “/etc/containerd/registry.d/${REGISTRY_URL}” | Изменения конфигураций не приводят к перезапуску сервиса containerd. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/ca.crt” - « EOF —–BEGIN CERTIFICATE—– … —–END CERTIFICATE—– EOF | Как добавить авторизацию в дополнительный registry (новый способ)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml” - « EOF [host] [host.”https://${REGISTRY_URL}”] capabilities = [“pull”, “resolve”] ca = [“/etc/containerd/registry.d/${REGISTRY_URL}/ca.crt”] EOF | Пример добавления авторизации в дополнительный registry при использовании нового способа конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
In addition to containerd, the certificate can be added into the OS. | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: Шаг может быть любой, т.к. не требуется перезапуск сервиса containerd weight: 0 bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to add TLS skip verify (new method)? | mkdir -p “/etc/containerd/registry.d/${REGISTRY_URL}” bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml” - « EOF [host] [host.”https://${REGISTRY_URL}”] capabilities = [“pull”, “resolve”] [host.”https://${REGISTRY_URL}”.auth] username = “username” password = “password” EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example of adding TLS skip verify when using the new configuration method: | Как настроить сертификат для дополнительного registry (новый способ)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-skip-tls.sh spec: The step can be arbitrary, as restarting the containerd service is not required weight: 0 bundles:
| Пример настройки сертификата для дополнительного registry? при использовании нового способа конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
mkdir -p “/etc/containerd/registry.d/${REGISTRY_URL}” bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml” - « EOF [host] [host.”https://${REGISTRY_URL}”] capabilities = [“pull”, “resolve”] skip_verify = true EOF | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-tls.sh spec: Шаг может быть любой, тк не требуется перезапуск сервиса containerd weight: 0 bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
After applying the configuration file, check access to the registry from the nodes using the following commands: | mkdir -p “/etc/containerd/registry.d/${REGISTRY_URL}” | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash | bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/ca.crt” - « EOF —–BEGIN CERTIFICATE—– … —–END CERTIFICATE—– EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Via the CRI interface crictl pull private.registry.example/image/repo:tag | bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml” - « EOF [host] [host.”https://${REGISTRY_URL}”] capabilities = [“pull”, “resolve”] ca = [“/etc/containerd/registry.d/${REGISTRY_URL}/ca.crt”] EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Via ctr with the configuration directory specified ctr -n k8s.io images pull –hosts-dir=/etc/containerd/registry.d/ private.registry.example/image/repo:tag | Помимо containerd, сертификат можно добавить в операционную систему. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Via ctr for an HTTP registry ctr -n k8s.io images pull –hosts-dir=/etc/containerd/registry.d/ –plain-http private.registry.example/image/repo:tag | Как добавить TLS skip verify (новый способ)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to use NodeGroup’s priority feature | Пример добавления TLS skip verify при использовании нового способа конфигурации: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The priority field of the | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-skip-tls.sh spec: Шаг может быть любой, тк не требуется перезапуск сервиса containerd weight: 0 bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Here is an example of creating two | mkdir -p “/etc/containerd/registry.d/${REGISTRY_URL}” bb-sync-file “/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml” - « EOF [host] [host.”https://${REGISTRY_URL}”] capabilities = [“pull”, “resolve”] skip_verify = true EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yamlapiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker-spot spec: cloudInstances: classReference: kind: AWSInstanceClass name: worker-spot maxPerZone: 5 minPerZone: 0 priority: 50 nodeType: CloudEphemeral — apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: cloudInstances: classReference: kind: AWSInstanceClass name: worker maxPerZone: 5 minPerZone: 0 priority: 30 nodeType: CloudEphemeral | После применения конфигурационного файла проверьте доступ к registry с узлов, используя команды: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
In the above example, | bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Once the | Через cri интерфейс crictl pull private.registry.example/image/repo:tag | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Note that node templates (labels/taints) for | Через ctr с указанием директории с конфигурациями ctr -n k8s.io images pull –hosts-dir=/etc/containerd/registry.d/ private.registry.example/image/repo:tag | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to interpret Node Group states? | Через ctr для http репозитория ctr -n k8s.io images pull –hosts-dir=/etc/containerd/registry.d/ –plain-http private.registry.example/image/repo:tag | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Ready — the node group contains the minimum required number of scheduled nodes with the status Ready for all zones. | Как использовать NodeGroup с приоритетом? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example 1. A group of nodes in the | С помощью параметра priority кастомного ресурса | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 1 status: conditions:
| Пример создания двух | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example 2. A group of nodes in the | yamlapiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker-spot spec: cloudInstances: classReference: kind: AWSInstanceClass name: worker-spot maxPerZone: 5 minPerZone: 0 priority: 50 nodeType: CloudEphemeral — apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: cloudInstances: classReference: kind: AWSInstanceClass name: worker maxPerZone: 5 minPerZone: 0 priority: 30 nodeType: CloudEphemeral | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: conditions:
| В приведенном выше примере, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Updating — a node group contains at least one node in which there is an annotation with the prefix update.node.deckhouse.io (for example, update.node.deckhouse.io/waiting-for-approval). | После того как NodeGroup | ||||||||||||||||||||||||||||||||||||||||||||||||||||
WaitingForDisruptiveApproval - a node group contains at least one node that has an annotation update.node.deckhouse.io/disruption-required and there is no annotation update.node.deckhouse.io/disruption-approved. | Шаблоны узлов (labels/taints) для NodeGroup | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Scaling — calculated only for node groups with the type CloudEphemeral. The state True can be in two cases: | Как интерпретировать состояние группы узлов? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ready — группа узлов содержит минимально необходимое число запланированных узлов с состоянием | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The desired number of nodes is the sum of all replicas in the node group. | Пример 1. Группа узлов в состоянии | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Example. The desired number of nodes is 2: | yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 1 status: conditions:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: … desired: 2 … | Пример 2. Группа узлов в состоянии | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Error — contains the last error that occurred when creating a node in a node group. | yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: conditions:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I make werf ignore the Ready conditions in a node group? | Updating — группа узлов содержит как минимум один узел, в котором присутствует аннотация с префиксом | ||||||||||||||||||||||||||||||||||||||||||||||||||||
werf checks the Ready status of resources and, if available, waits for the value to become True. | WaitingForDisruptiveApproval — группа узлов содержит как минимум один узел, в котором присутствует аннотация | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Creating (updating) a nodeGroup resource in a cluster can take a significant amount of time to create the required number of nodes. When deploying such a resource in a cluster using werf (e.g., as part of a CI/CD process), deployment may terminate when resource readiness timeout is exceeded. To make werf ignore the nodeGroup status, the following | Scaling — рассчитывается только для групп узлов с типом | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml metadata: annotations: werf.io/fail-mode: IgnoreAndContinueDeployProcess werf.io/track-termination-mode: NonBlocking |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
What is an Instance resource? | Желаемое число узлов — это сумма всех реплик, входящих в группу узлов. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
An Instance resource contains a description of an implementation-independent ephemeral machine resource. For example, machines created by MachineControllerManager or Cluster API Provider Static will have a corresponding Instance resource. | Пример. Желаемое число узлов равно 2: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The object does not contain a specification. The status contains: | yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: … desired: 2 … | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Error — содержит последнюю ошибку, возникшую при создании узла в группе узлов. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
When a machine is created/deleted, the Instance object is created/deleted accordingly. You cannot create an Instance resource yourself, but you can delete it. In this case, the machine will be removed from the cluster (the removal process depends on implementation details). | Как заставить werf игнорировать состояние Ready в группе узлов? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
When is a node reboot required? | werf проверяет состояние | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Node reboots may be required after configuration changes. For example, after changing certain sysctl settings, specifically when modifying the | Создание (обновление) ресурса nodeGroup в кластере может потребовать значительного времени на развертывание необходимого количества узлов. При развертывании такого ресурса в кластере с помощью werf (например, в рамках процесса CI/CD) развертывание может завершиться по превышении времени ожидания готовности ресурса. Чтобы заставить werf игнорировать состояние | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How do I work with GPU nodes? | yaml metadata: annotations: werf.io/fail-mode: IgnoreAndContinueDeployProcess werf.io/track-termination-mode: NonBlocking | ||||||||||||||||||||||||||||||||||||||||||||||||||||
GPU-node management is available in Enterprise Edition only. | Что такое ресурс Instance? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Step-by-step procedure for adding a GPU node to the cluster | Ресурс | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Starting with Deckhouse 1.71, if a | Объект не содержит спецификации. Статус содержит: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Always specify the desired mode in | При создании или удалении машины создается или удаляется соответствующий объект Instance.
Самостоятельно ресурс | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Manual containerd configuration (via | Когда требуется перезагрузка узлов? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
To add a GPU node to the cluster, perform the following steps: | Некоторые операции по изменению конфигурации узлов могут потребовать перезагрузки. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перезагрузка узла может потребоваться при изменении некоторых настроек sysctl, например, при изменении параметра | ||||||||||||||||||||||||||||||||||||||||||||||||||||
An example with TimeSlicing enabled ( | Как работать с GPU-узлами? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: gpu spec: nodeType: CloudStatic # or Static/CloudEphemeral — depending on your infrastructure gpu: sharing: TimeSlicing timeSlicing: partitionCount: 4 nodeTemplate: labels: node-role/gpu: “” taints:
| Управление GPU-узлами доступно только в Enterprise Edition. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Порядок действий по добавлению GPU-узла в кластер | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Full field schema: see NodeGroup CR documentation. | Начиная с Deckhouse 1.71, если в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Install the NVIDIA driver and NVIDIA Container Toolkit on the nodes—either manually or via a NodeGroupConfiguration. Below are NodeGroupConfiguration examples for the gpu NodeGroup | Для корректной работы необходимо явно указать режим в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Ubuntu | Ручная конфигурация containerd (через | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:
| Чтобы добавить GPU-узел в кластер, выполните следующие действия: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if [ ! -f “/etc/apt/sources.list.d/nvidia-container-toolkit.list” ]; then distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/ sources.list.d/nvidia-container-toolkit.list fi bb-apt-install nvidia-container-toolkit nvidia-driver-535-server nvidia-ctk config –set nvidia-container-runtime.log-level=error –in-place nodeGroups:
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
CentOS | Пример с включённым TimeSlicing ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:
| yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: gpu spec: nodeType: CloudStatic # или Static/CloudEphemeral — по вашей инфраструктуре gpu: sharing: TimeSlicing timeSlicing: partitionCount: 4 nodeTemplate: labels: node-role/gpu: “” taints:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
if [ ! -f “/etc/yum.repos.d/nvidia-container-toolkit.repo” ]; then
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
After these configurations are applied, perform bootstrap and reboot the nodes so that settings are applied and the drivers get installed. | Полная схема полей находится в описании кастомного ресурса | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash nvidia-smi | Установку драйвера NVIDIA и NVIDIA Container Toolkit выполняйте на самих узлах — вручную или с помощью | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Expected healthy output (example): | Ubuntu | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console root@k8s-dvp-w1-gpu:~# nvidia-smi Tue Aug 5 07:08:48 2025 +—————————————————————————————+ | NVIDIA-SMI 535.247.01 Driver Version: 535.247.01 CUDA Version: 12.2 | |—————————————–+———————-+———————-+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla V100-PCIE-32GB Off | 00000000:65:00.0 Off | 0 | | N/A 32C P0 35W / 250W | 0MiB / 32768MiB | 0% Default | | | | N/A | +—————————————–+———————-+———————-+ +—————————————————————————————+ | Processes: | | No running processes found | +—————————————————————————————+ | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| CentOS | ||||||||||||||||||||||||||||||||||||||||||||||||||||
NVIDIA Pods in | yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl -n d8-nvidia-gpu get pod | if [ ! -f “/etc/yum.repos.d/nvidia-container-toolkit.repo” ]; then
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Expected healthy output (example): | После того как конфигурации будут применены, необходимо провести бутстрап и перезагрузить узлы, чтобы применить настройки и установить драйвера. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console NAME READY STATUS RESTARTS AGE gpu-feature-discovery-80ceb7d-r842q 2/2 Running 0 2m53s nvidia-dcgm-exporter-w9v9h 1/1 Running 0 2m53s nvidia-dcgm-njqqb 1/1 Running 0 2m53s nvidia-device-plugin-80ceb7d-8xt8g 2/2 Running 0 2m53s |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
NFD Pods in | bash nvidia-smi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl -n d8-cloud-instance-manager get pods | egrep ‘^(NAME|node-feature-discovery)’ | Ожидаемый корректный вывод (пример): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Expected healthy output (example): | console root@k8s-dvp-w1-gpu:~# nvidia-smi Tue Aug 5 07:08:48 2025 +—————————————————————————————+ | NVIDIA-SMI 535.247.01 Driver Version: 535.247.01 CUDA Version: 12.2 | |—————————————–+———————-+———————-+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla V100-PCIE-32GB Off | 00000000:65:00.0 Off | 0 | | N/A 32C P0 35W / 250W | 0MiB / 32768MiB | 0% Default | | | | N/A | +—————————————–+———————-+———————-+ +—————————————————————————————+ | Processes: | | No running processes found | +—————————————————————————————+ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console NAME READY STATUS RESTARTS AGE node-feature-discovery-gc-6d845765df-45vpj 1/1 Running 0 3m6s node-feature-discovery-master-74696fd9d5-wkjk4 1/1 Running 0 3m6s node-feature-discovery-worker-5f4kv 1/1 Running 0 3m8s |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Resource exposure on the node: | Поды NVIDIA в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash
kubectl describe node | bash kubectl -n d8-nvidia-gpu get pod | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Output snippet (example): | Ожидаемый корректный вывод (пример): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console Capacity: cpu: 40 memory: 263566308Ki nvidia.com/gpu: 4 Allocatable: cpu: 39930m memory: 262648294441 nvidia.com/gpu: 4 | console NAME READY STATUS RESTARTS AGE gpu-feature-discovery-80ceb7d-r842q 2/2 Running 0 2m53s nvidia-dcgm-exporter-w9v9h 1/1 Running 0 2m53s nvidia-dcgm-njqqb 1/1 Running 0 2m53s nvidia-device-plugin-80ceb7d-8xt8g 2/2 Running 0 2m53s | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Поды NFD в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Option A. Invoke | bash kubectl -n d8-cloud-instance-manager get pods | egrep ‘^(NAME|node-feature-discovery)’ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Create a Job: | Ожидаемый корректный вывод (пример): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: batch/v1 kind: Job metadata: name: nvidia-cuda-test namespace: default spec: completions: 1 template: spec: restartPolicy: Never nodeSelector: node.deckhouse.io/group: gpu containers:
| console NAME READY STATUS RESTARTS AGE node-feature-discovery-gc-6d845765df-45vpj 1/1 Running 0 3m6s node-feature-discovery-master-74696fd9d5-wkjk4 1/1 Running 0 3m6s node-feature-discovery-worker-5f4kv 1/1 Running 0 3m8s | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Check the logs using the command: | Публикация ресурсов на узле: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl logs job/nvidia-cuda-test | bash kubectl describe node <имя-ноды>имя-ноды> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Output example: | Фрагмент вывода (пример): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console Tue Aug 5 07:48:02 2025 +—————————————————————————————+ | NVIDIA-SMI 535.247.01 Driver Version: 535.247.01 CUDA Version: 12.2 | |—————————————–+———————-+———————-+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla V100-PCIE-32GB Off | 00000000:65:00.0 Off | 0 | | N/A 31C P0 23W / 250W | 0MiB / 32768MiB | 0% Default | | | | N/A | +—————————————–+———————-+———————-+ +—————————————————————————————+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | No running processes found | +—————————————————————————————+ | bash Capacity: cpu: 40 memory: 263566308Ki nvidia.com/gpu: 4 Allocatable: cpu: 39930m memory: 262648294441 nvidia.com/gpu: 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Option B. CUDA sample (vectoradd). |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Create a Job: | Вариант A. Вызов | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml apiVersion: batch/v1 kind: Job metadata: name: gpu-operator-test namespace: default spec: completions: 1 template: spec: restartPolicy: Never nodeSelector: node.deckhouse.io/group: gpu containers:
| Создайте в кластере задачу (Job): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Check the logs using the command:: | yaml apiVersion: batch/v1 kind: Job metadata: name: nvidia-cuda-test namespace: default spec: completions: 1 template: spec: restartPolicy: Never nodeSelector: node.deckhouse.io/group: gpu containers:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl logs job/gpu-operator-test | Проверьте логи командой: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Output example: | bash kubectl logs job/nvidia-cuda-test | ||||||||||||||||||||||||||||||||||||||||||||||||||||
console [Vector addition of 50000 elements] Copy input data from the host memory to the CUDA device CUDA kernel launch with 196 blocks of 256 threads Copy output data from the CUDA device to the host memory Test PASSED Done | Пример вывода: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to monitor GPUs? | console Tue Aug 5 07:48:02 2025 +—————————————————————————————+ | NVIDIA-SMI 535.247.01 Driver Version: 535.247.01 CUDA Version: 12.2 | |—————————————–+———————-+———————-+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla V100-PCIE-32GB Off | 00000000:65:00.0 Off | 0 | | N/A 31C P0 23W / 250W | 0MiB / 32768MiB | 0% Default | | | | N/A | +—————————————–+———————-+———————-+ +—————————————————————————————+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | No running processes found | +—————————————————————————————+ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Deckhouse Kubernetes Platform automatically deploys DCGM Exporter; GPU metrics are scraped by Prometheus and available in Grafana. | Вариант B. CUDA sample (vectoradd). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Which GPU modes are supported? | Создайте в кластере Job: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| yaml apiVersion: batch/v1 kind: Job metadata: name: gpu-operator-test namespace: default spec: completions: 1 template: spec: restartPolicy: Never nodeSelector: node.deckhouse.io/group: gpu containers:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
See examples in Examples → GPU nodes. | Проверьте логи командой: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
How to view available MIG profiles in the cluster? | shell kubectl logs job/gpu-operator-test | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Пример вывода: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Pre-defined profiles are stored in the | console [Vector addition of 50000 elements] Copy input data from the host memory to the CUDA device CUDA kernel launch with 196 blocks of 256 threads Copy output data from the CUDA device to the host memory Test PASSED Done | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl -n d8-nvidia-gpu get cm mig-parted-config -o json | jq -r ‘.data[“config.yaml”]’ | Как мониторить GPU? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
The | Deckhouse Kubernetes Platform автоматически устанавливает DCGM Exporter; метрики GPU попадают в Prometheus и доступны в Grafana. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
MIG profile does not activate — what to check? | Какие режимы работы GPU поддерживаются? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Поддерживаются следующие режимы работы GPU: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
yaml gpu: sharing: MIG mig: partedConfig: all-1g.5gb |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Примеры см. в разделе Примеры → GPU-узлы. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
This process can take several minutes. | Как посмотреть доступные MIG-профили в кластере? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
While it is running, the node is tainted with |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Предустановленные профили находятся в ConfigMap | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| bash kubectl -n d8-nvidia-gpu get cm mig-parted-config -o json | jq -r ‘.data[“config.yaml”]’ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| В разделе mig-configs вы увидите конкретные модели ускорителей (по PCI-ID) и список совместимых MIG-профилей для каждой из них.
Найдите свою видеокарту и выберите подходящий профиль — его имя указывается в | ||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl -n d8-nvidia-gpu logs daemonset/nvidia-mig-manager nvidia-smi -L | Для GPU не активируется MIG-профиль — что проверить? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Are AMD or Intel GPUs supported? |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
At this time, Deckhouse Kubernetes Platform automatically configures NVIDIA GPUs only. Support for AMD (ROCm) and Intel GPUs is being worked on and is planned for future releases. | yaml gpu: sharing: MIG mig: partedConfig: all-1g.5gb | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
Этот процесс может занять несколько минут. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
Пока операция идёт, на узле стоит taint | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||
bash kubectl -n d8-nvidia-gpu logs daemonset/nvidia-mig-manager nvidia-smi -L | |||||||||||||||||||||||||||||||||||||||||||||||||||||
Поддерживаются ли AMD или Intel GPU? | |||||||||||||||||||||||||||||||||||||||||||||||||||||
Сейчас Deckhouse Kubernetes Platform автоматически настраивает только NVIDIA GPU. Поддержка AMD (ROCm) и Intel GPU находится в проработке и планируется к добавлению в будущих релизах. |