Compare languages | Managing nodes: FAQ

How do I add a master nodes to a cloud cluster (single-master to a multi-master)?

See the control-plane-manager module FAQ.

Как добавить master-узлы в облачном кластере?

How do I reduce the number of master nodes in a cloud cluster (multi-master to single-master)?

Как конвертировать кластер с одним master-узлом в мультикластерный описано в FAQ модуля control-plane-manager.

See the control-plane-manager module FAQ.

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.

  1. Prepare the required resources:

Как добавить статический узел в кластер (Cluster API Provider Static)?

  • Allocate a server or virtual machine and ensure that the node has the necessary network connectivity with the cluster.

Чтобы добавить статический узел в кластер (сервер bare-metal или виртуальную машину), выполните следующие шаги:

  • If necessary, install additional operating system packages and configure the mount points that will be used on the node.
  1. Подготовьте необходимые ресурсы:
  1. Create a user with sudo` privileges:
  • Выделите сервер или виртуальную машину и убедитесь, что узел имеет необходимую сетевую связанность с кластером.
  • Add a new user (in this example, caps) with sudo privileges:
  • При необходимости установите дополнительные пакеты ОС и настройте точки монтирования, которые будут использоваться на узле.

shell useradd -m -s /bin/bash caps usermod -aG sudo caps

  1. Создайте пользователя с правами sudo:
  • Allow the user to run sudo commands without having to enter a password. For this, add the following line to the sudo configuration on the server (you can either edit the /etc/sudoers file, or run the sudo visudo command, or use some other method):
  • Добавьте нового пользователя (в данном примере — caps) с правами выполнения команд через sudo:

shell caps ALL=(ALL) NOPASSWD: ALL

shell useradd -m -s /bin/bash caps usermod -aG sudo caps

  1. Set UsePAM to yes in /etc/ssh/sshd_config on server and restart sshd service:
  • Разрешите пользователю выполнять команды через sudo без ввода пароля. Для этого отредактируйте конфигурацию sudo (отредактировав файл /etc/sudoers, выполнив команду sudo visudo или другим способом):

shell sudo systemctl restart sshd

shell caps ALL=(ALL) NOPASSWD: ALL

  1. Generate a pair of SSH keys with an empty passphrase on the server:
  1. На сервере откройте файл /etc/ssh/sshd_config и убедитесь, что параметр UsePAM установлен в значение yes. Затем перезапустите службу sshd:

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 caps-id.pub and caps-id files in the current directory on the server.

  1. Сгенерируйте на сервере пару SSH-ключей с пустой парольной фразой:
  1. Add the generated public key to the /home/caps/.ssh/authorized_keys file of the caps user by executing the following commands in the keys directory on the server:

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/

Приватный и публичный ключи будут сохранены в файлах caps-id и caps-id.pub соответственно в текущей директории.

  1. Create the SSHCredentials resource.
  2. Create the StaticInstance resource.
  3. Create the NodeGroup resource with the Static nodeType, specify the desired number of nodes in the group and, if necessary, the filter for StaticInstance.
  1. Добавьте полученный публичный ключ в файл /home/caps/.ssh/authorized_keys пользователя 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?

  1. Создайте ресурс SSHCredentials.
  2. Создайте ресурс StaticInstance.
  3. Создайте ресурс NodeGroup с nodeType Static, указав желаемое количество узлов в группе и, при необходимости, фильтр выбора StaticInstance.

Use an existing one or create a new NodeGroup custom resource (example of the NodeGroup called worker). The nodeType parameter for static nodes in the NodeGroup must be Static or CloudStatic.

Пример добавления статического узла.

You can automate the bootstrap process with any automation platform you prefer. The following is an example for Ansible.

Как добавить несколько статических узлов в кластер вручную?

  1. Pick up one of Kubernetes API Server endpoints. Note that this IP must be accessible from nodes that are being added to the cluster:

Используйте существующий или создайте новый кастомный ресурс (Custom Resource) NodeGroup (пример NodeGroup с именем worker).

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 node-group token:

  1. Получите один из адресов Kubernetes API-сервера. Обратите внимание, что IP-адрес должен быть доступен с узлов, которые добавляются в кластер:

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 token: field of the Ansible playbook in the next steps.

Проверьте версию K8s. Если версия >= 1.25, создайте токен node-group:

  1. If the Kubernetes version is smaller than 1.25, get a Kubernetes API token for a special ServiceAccount that Deckhouse manages:

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)
-o json | jq ‘.data.token’ -r | base64 -d && echo “”

Сохраните полученный токен, и добавьте в поле token: playbook’а Ansible на дальнейших шагах.

  1. Create Ansible playbook with vars replaced with values from previous steps:
  1. Если версия Kubernetes меньше 1.25, получите Kubernetes API-токен для специального ServiceAccount’а, которым управляет Deckhouse:

shell kubectl -n d8-cloud-instance-manager get $(kubectl -n d8-cloud-instance-manager get secret -o name | grep node-group-token)
-o json | jq ‘.data.token’ -r | base64 -d && echo “”

yaml

  • hosts: all become: yes gather_facts: no vars: kube_apiserver: token: tasks:
  • name: Check if node is already bootsrapped stat: path: /var/lib/bashible register: bootstrapped
  • name: Get bootstrap secret uri: url: “https://{{ kube_apiserver }}/api/v1/namespaces/d8-cloud-instance-manager/secrets/manual-bootstrap-for-{{ node_group }}” return_content: yes method: GET status_code: 200 body_format: json headers: Authorization: “Bearer {{ token }}” validate_certs: no register: bootstrap_secret when: bootstrapped.stat.exists == False
  • name: Run bootstrap.sh shell: “{{ bootstrap_secret.json.data[‘bootstrap.sh’] | b64decode }}” args: executable: /bin/bash ignore_errors: yes when: bootstrapped.stat.exists == False
  • name: wait wait_for_connection: delay: 30 when: bootstrapped.stat.exists == False
  1. Создайте Ansible playbook с vars, которые заменены на полученные на предыдущих шагах значения:
  1. Specify one more node_group variable. This variable must be the same as the name of NodeGroup to which node will belong. Variable can be passed in different ways, for example, by using an inventory file.:

yaml

  • hosts: all become: yes gather_facts: no vars: kube_apiserver: token: tasks:
  • name: Check if node is already bootsrapped stat: path: /var/lib/bashible register: bootstrapped
  • name: Get bootstrap secret uri: url: “https://{{ kube_apiserver }}/api/v1/namespaces/d8-cloud-instance-manager/secrets/manual-bootstrap-for-{{ node_group }}” return_content: yes method: GET status_code: 200 body_format: json headers: Authorization: “Bearer {{ token }}” validate_certs: no register: bootstrap_secret when: bootstrapped.stat.exists == False
  • name: Run bootstrap.sh shell: “{{ bootstrap_secret.json.data[‘bootstrap.sh’] | b64decode }}” args: executable: /bin/bash ignore_errors: yes when: bootstrapped.stat.exists == False
  • name: wait wait_for_connection: delay: 30 when: bootstrapped.stat.exists == False

text [system] system-0 system-1

[system:vars] node_group=system

  1. Определите дополнительную переменную node_group. Значение переменной должно совпадать с именем NodeGroup, которой будет принадлежать узел. Переменную можно передать различными способами, например с использованием inventory-файла:

[worker] worker-0 worker-1

text [system] system-0 system-1

[worker:vars] node_group=worker

[system:vars] node_group=system

  1. Run the playbook with the inventory file.

[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.

  1. Запустите выполнение playbook’а с использованием inventory-файла.

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 Pending state can be deleted with no adverse effects.

Чтобы вывести из кластера узел и очистить сервер (ВМ), выполните следующую команду на узле:

To delete a StaticInstance in any state other than Pending (Running, Cleaning, Bootstrapping), you need to:

shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing

  1. Add the label "node.deckhouse.io/allow-bootstrap": "false" to the StaticInstance.
  2. Wait until the StaticInstance status becomes Pending.
  3. Delete the StaticInstance.
  4. Decrease the NodeGroup.spec.staticInstances.count field by 1.

Можно ли удалить StaticInstance?

How do I change the IP address of a StaticInstance?

StaticInstance, находящийся в состоянии Pending можно удалять без каких-либо проблем.

You cannot change the IP address in the StaticInstance resource. If an incorrect address is specified in StaticInstance, you have to delete the StaticInstance and create a new one.

Чтобы удалить StaticInstance находящийся в любом состоянии, отличном от Pending (Running, Cleaning, Bootstrapping), выполните следующие шаги:

How do I migrate a manually configured static node under CAPS control?

  1. Добавьте метку "node.deckhouse.io/allow-bootstrap": "false" в StaticInstance.
  2. Дождитесь, пока StaticInstance перейдет в статус Pending.
  3. Удалите StaticInstance.
  4. Уменьшите значение параметра NodeGroup.spec.staticInstances.count на 1.

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-адрес в ресурсе StaticInstance нельзя. Если в StaticInstance указан ошибочный адрес, то нужно удалить StaticInstance и создать новый.

Note that if a node is under CAPS control, you cannot change the NodeGroup membership of such a node. The only alternative is to delete StaticInstance and create a new one.

Как мигрировать статический узел настроенный вручную под управление CAPS?

To switch an existing manually created static node to another NodeGroup, you need to change its group label:

Необходимо выполнить очистку узла, затем добавить узел под управление CAPS.

shell kubectl label node –overwrite node.deckhouse.io/group= kubectl label node node-role.kubernetes.io/-

Как изменить NodeGroup у статического узла?

Applying the changes will take some time.

How to clean up a node for adding to the cluster?

Если узел находится под управлением CAPS, то изменить принадлежность к NodeGroup у такого узла нельзя. Единственный вариант — удалить StaticInstance и создать новый.

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.

Чтобы перенести существующий статический узел созданный вручную из одной NodeGroup в другую, необходимо изменить у узла лейбл группы:

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 node.deckhouse.io/group= kubectl label node node-role.kubernetes.io/-

  1. Delete the node from the Kubernetes cluster:

Применение изменений потребует некоторого времени.

shell kubectl drain --ignore-daemonsets --delete-local-data kubectl delete node

Как очистить узел для последующего ввода в кластер?

  1. Run cleanup script on the node:

Это необходимо только в том случае, если нужно переместить статический узел из одного кластера в другой. Имейте в виду, что эти операции удаляют данные локального хранилища. Если необходимо просто изменить NodeGroup, следуйте этой инструкции.

shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing

Если на зачищаемом узле есть пулы хранения LINSTOR/DRBD, то предварительно перенесите ресурсы с узла и удалите узел LINSTOR/DRBD, следуя инструкции.

  1. Run the bootstrap.sh script after reboot of the node.
  1. Удалите узел из кластера Kubernetes:

How do I know if something went wrong?

shell kubectl drain --ignore-daemonsets --delete-local-data kubectl delete node

If a node in a nodeGroup is not updated (the value of UPTODATE when executing the kubectl get nodegroup command is less than the value of NODES) or you assume some other problems that may be related to the node-manager module, then you need to look at the logs of the bashible service. The bashible service runs on each node managed by the node-manager module.

  1. Запустите на узле скрипт очистки:

To view the logs of the bashible service on a specific node, run the following command:

shell bash /var/lib/bashible/cleanup_static_node.sh –yes-i-am-sane-and-i-understand-what-i-am-doing

shell journalctl -fu bashible

  1. После перезагрузки узла запустите скрипт bootstrap.sh.

Example of output when the bashible service has performed all necessary actions:

Как понять, что что-то пошло не так?

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 не обновляется (значение UPTODATE при выполнении команды kubectl get nodegroup меньше значения NODES) или вы предполагаете какие-то другие проблемы, которые могут быть связаны с модулем node-manager, нужно проверить логи сервиса bashible. Сервис bashible запускается на каждом узле, управляемом модулем node-manager.

How do I know what is running on a node while it is being created?

Чтобы проверить логи сервиса bashible, выполните на узле следующую команду:

You can analyze cloud-init to find out what’s happening on a node during the bootstrapping process:

shell journalctl -fu bashible

  1. Find the node that is currently bootstrapping:

Пример вывода, когда все необходимые действия выполнены:

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

Если необходимо узнать, что происходит на узле (например, узел долго создается), можно проверить логи cloud-init. Для этого выполните следующие шаги:

  1. Get information about connection parameters for viewing logs:
  1. Найдите узел, который находится в стадии бутстрапа:

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

  1. Run the command you got (nc 192.168.199.115 8000 according to the example above) to see cloud-init logs and determine the cause of the problem on the node.
  1. Получите информацию о параметрах подключения для просмотра логов:

The logs of the initial node configuration are located at /var/log/cloud-init-output.log.

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 Node Group Configuration resource by specifying the desired kernel version in the desired_version variable of the shell script (the resource’s spec.content parameter):

  1. Выполните полученную команду (в примере выше — nc 192.168.199.178 8000), чтобы просмотреть логи cloud-init и определить, на каком этапе остановилась настройка узла.

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:

  • ‘*’ nodeGroups:
  • ‘*’ weight: 32 content: | Copyright 2022 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Логи первоначальной настройки узла находятся в /var/log/cloud-init-output.log.

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)”

Создайте ресурс NodeGroupConfiguration, указав в переменной desired_version shell-скрипта (параметр spec.content ресурса) желаемую версию ядра:

if [[ “$version_in_use” == “$desired_version” ]]; then exit 0 fi

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:

  • ‘*’ nodeGroups:
  • ‘*’ weight: 32 content: | Copyright 2022 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

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 Node Group Configuration resource by specifying the desired kernel version in the desired_version variable of the shell script (the resource’s spec.content parameter):

version_in_use=”$(uname -r)”

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:

  • ‘*’ nodeGroups:
  • ‘*’ weight: 32 content: | Copyright 2022 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

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)”

Создайте ресурс NodeGroupConfiguration, указав в переменной desired_version shell-скрипта (параметр spec.content ресурса) желаемую версию ядра:

if [[ “$version_in_use” == “$desired_version” ]]; then exit 0 fi

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-kernel.sh spec: bundles:

  • ‘*’ nodeGroups:
  • ‘*’ weight: 32 content: | Copyright 2022 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

bb-deckhouse-get-disruptive-update-approval bb-yum-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 }

The NodeGroup parameter Disruption update Node provisioning Kubelet restart
chaos - - -
cloudInstances.classReference - + -
cloudInstances.maxSurgePerZone - - -
cri.containerd.maxConcurrentDownloads - - +
cri.type - (NotManaged) / + (other) - -
disruptions - - -
kubelet.maxPods - - +
kubelet.rootDir - - +
kubernetesVersion - - +
nodeTemplate - - -
static - - +
update.maxConcurrent - - -

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 InstanceClass or instancePrefix parameter in the Deckhouse configuration won’t result in a RollingUpdate. Deckhouse will create new MachineDeployments and delete the old ones. The number of machinedeployments ordered at the same time is determined by the cloud Instances.maxSurgePerZone parameter.

bb-deckhouse-get-disruptive-update-approval bb-yum-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?

Параметр NG Disruption update Перезаказ узлов Рестарт kubelet
chaos - - -
cloudInstances.classReference - + -
cloudInstances.maxSurgePerZone - - -
cri.containerd.maxConcurrentDownloads - - +
cri.type - (NotManaged) / + (other) - -
disruptions - - -
kubelet.maxPods - - +
kubelet.rootDir - - +
kubernetesVersion - - +
nodeTemplate - - -
static - - +
update.maxConcurrent - - -

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 InstanceClass or NodeGroup objects.

Подробно о всех параметрах можно прочитать в описании кастомного ресурса NodeGroup.

To force the redeployment of all Machines, you need to add/modify the manual-rollout-id annotation to the NodeGroup: kubectl annotate NodeGroup name_ng "manual-rollout-id=$(uuidgen)" --overwrite.

В случае изменения параметров InstanceClass или instancePrefix в конфигурации Deckhouse не будет происходить RollingUpdate. Deckhouse создаст новые MachineDeployment, а старые удалит. Количество заказываемых одновременно MachineDeployment определяется параметром cloudInstances.maxSurgePerZone.

How do I allocate nodes to specific loads?

При обновлении, которое требует прерывания работы узла (disruption update), выполняется процесс вытеснения подов с узла. Если какой-либо под не может быть вытеснен, попытка повторяется каждые 20 секунд до достижения глобального таймаута в 5 минут. После истечения этого времени, поды, которые не удалось вытеснить, удаляются принудительно.

You cannot use the deckhouse.io domain in labels and taints keys of the NodeGroup. It is reserved for Deckhouse components. Please, use the dedicated or dedicated.client.com keys.

Как пересоздать эфемерные машины в облаке с новой конфигурацией?

There are two ways to solve this problem:

При изменении конфигурации Deckhouse (как в модуле node-manager, так и в любом из облачных провайдеров) виртуальные машины не будут перезаказаны. Пересоздание происходит только после изменения ресурсов InstanceClass или NodeGroup.

  1. You can set labels to NodeGroup’s spec.nodeTemplate.labels, to use them in the Pod’s spec.nodeSelector or spec.affinity.nodeAffinity parameters. In this case, you select nodes that the scheduler will use for running the target application.
  2. You cat set taints to NodeGroup’s spec.nodeTemplate.taints and then remove them via the Pod’s spec.tolerations parameter. In this case, you disallow running applications on these nodes unless those applications are explicitly allowed.

Чтобы принудительно пересоздать все узлы, связанные с ресурсом Machines, следует добавить/изменить аннотацию manual-rollout-id в NodeGroup: kubectl annotate NodeGroup имя_ng "manual-rollout-id=$(uuidgen)" --overwrite.

Deckhouse tolerates the dedicated by default, so we recommend using the dedicated key with any value for taints on your dedicated nodes.️

Как выделить узлы под специфические нагрузки?

To use custom keys for taints (e.g., dedicated.client.com), you must add the key’s value to the modules.placement.customTolerationKeys parameters. This way, deckhouse can deploy system components (e.g., cni-flannel) to these dedicated nodes.

Запрещено использование домена deckhouse.io в ключах labels и taints у NodeGroup. Он зарезервирован для компонентов Deckhouse. Следует отдавать предпочтение в пользу ключей dedicated или dedicated.client.com.

How to allocate nodes to system components?

Для решений данной задачи существуют два механизма:

Frontend

  1. Установка меток в NodeGroup spec.nodeTemplate.labels для последующего использования их в Pod spec.nodeSelector или spec.affinity.nodeAffinity. Указывает, какие именно узлы будут выбраны планировщиком для запуска целевого приложения.
  2. Установка ограничений в NodeGroup spec.nodeTemplate.taints с дальнейшим снятием их в Pod spec.tolerations. Запрещает исполнение не разрешенных явно приложений на этих узлах.

For Ingress controllers, use the NodeGroup with the following configuration:

Deckhouse по умолчанию поддерживает использование taint’а с ключом dedicated, поэтому рекомендуется применять этот ключ с любым значением для taints на ваших выделенных узлах.

yaml nodeTemplate: labels: node-role.deckhouse.io/frontend: “” taints:

  • effect: NoExecute key: dedicated.deckhouse.io value: frontend

Если требуется использовать другие ключи для taints (например, dedicated.client.com), необходимо добавить соответствующее значение ключа в параметр modules.placement.customTolerationKeys. Это обеспечит разрешение системным компонентам, таким как cni-flannel, использовать эти узлы.

System components

Подробности в статье на Habr.

NodeGroup for components of Deckhouse subsystems will look as follows:

Как выделить узлы под системные компоненты?

yaml nodeTemplate: labels: node-role.deckhouse.io/system: “” taints:

  • effect: NoExecute key: dedicated.deckhouse.io value: system

Фронтенд

How do I speed up node provisioning on the cloud when scaling applications horizontally?

Для Ingress-контроллеров используйте NodeGroup со следующей конфигурацией:

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:

  • effect: NoExecute key: dedicated.deckhouse.io value: frontend

Here is how you should configure the target NodeGroup:

Системные

  1. Specify the number of “ready” nodes (or a percentage of the maximum number of nodes in the group) using the cloudInstances.standby paramter.
  2. If there are additional service components on nodes that are not handled by Deckhouse (e.g., the filebeat DaemonSet), you can specify the percentage of node resources they can consume via the standbyHolder.overprovisioningRate parameter.
  3. This feature requires that at least one group node is already running in the cluster. In other words, there must be either a single replica of the application, or the cloudInstances.minPerZone parameter must be set to 1.

Для компонентов подсистем Deckhouse параметр NodeGroup будет настроен с параметрами:

An example:

yaml nodeTemplate: labels: node-role.deckhouse.io/system: “” taints:

  • effect: NoExecute key: dedicated.deckhouse.io value: system

yaml cloudInstances: maxPerZone: 10 minPerZone: 1 standby: 10% standbyHolder: overprovisioningRate: 30%

Как ускорить заказ узлов в облаке при горизонтальном масштабировании приложений?

How do I disable machine-controller-manager in the case of potentially cluster-damaging changes?

Самое действенное — держать в кластере некоторое количество предварительно подготовленных узлов, которые позволят новым репликам ваших приложений запускаться мгновенно. Очевидным минусом данного решения будут дополнительные расходы на содержание этих узлов.

Use this switch only if you know what you are doing and clearly understand the consequences.

Необходимые настройки целевой NodeGroup будут следующие:

Set the mcmEmergencyBrake parameter to true:

  1. Указать абсолютное количество предварительно подготовленных узлов (или процент от максимального количества узлов в этой группе) в параметре cloudInstances.standby.
  2. При наличии на узлах дополнительных служебных компонентов, не обслуживаемых Deckhouse (например, DaemonSet filebeat), задать их процентное потребление ресурсов узла можно в параметре standbyHolder.overprovisioningRate.
  3. Для работы этой функции требуется, чтобы как минимум один узел из группы уже был запущен в кластере. Иными словами, либо должна быть доступна одна реплика приложения, либо количество узлов для этой группы cloudInstances.minPerZone должно быть 1.

yaml mcmEmergencyBrake: true

Пример:

How do I restore the master node if kubelet cannot load the control plane components?

yaml cloudInstances: maxPerZone: 10 minPerZone: 1 standby: 10% standbyHolder: overprovisioningRate: 30%

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 /var/lib/containerd was deleted). In this case, kubelet cannot pull images of the control plane components when restarted since the master node lacks authorization parameters required for accessing registry.deckhouse.io.

Как выключить machine-controller-manager в случае выполнения потенциально деструктивных изменений в кластере?

Below is an instruction on how you can restore the master node.

Использовать эту настройку допустимо только тогда, когда вы четко понимаете, зачем это необходимо.

containerd

Для того чтобы временно отключить machine-controller-manager (MCM) и предотвратить его автоматические действия, которые могут повлиять на инфраструктуру кластера (например, удаление или пересоздание узлов), установите следующий параметр в конфигурации:

Execute the following command to restore the master node in any cluster running under Deckhouse:

yaml mcmEmergencyBrake: 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 AUTH variable on the corrupted master.

Подобная ситуация может возникнуть, если в кластере с одним master-узлом на нем были удалены образы компонентов control plane (например, удалена директория /var/lib/containerd). В этом случае kubelet при рестарте не сможет скачать образы компонентов control plane, поскольку на master-узле нет параметров авторизации в registry.deckhouse.io.

Next, you need to pull images of control plane components to the corrupted master:

Далее приведена инструкция по восстановлению 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 kubelet after pulling the images.

Для восстановления работоспособности 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 Containerd to NotManaged and back (the cri.type parameter).

Вывод команды нужно скопировать и присвоить переменной AUTH на поврежденном master-узле.

Set NodeGroup cri.type to Containerd or NotManaged.

Далее на поврежденном master-узле нужно загрузить образы компонентов control-plane:

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

После загрузки образов необходимо перезапустить kubelet.

Also, this operation can be done with patch:

Как изменить CRI для NodeGroup?

  • For Containerd:

Смена CRI возможна только между Containerd на NotManaged и обратно (параметр cri.type).

shell kubectl patch nodegroup --type merge -p '{"spec":{"cri":{"type":"Containerd"}}}'

Для изменения CRI для NodeGroup, установите параметр cri.type в Containerd или в NotManaged.

  • For NotManaged:

Пример YAML-манифеста NodeGroup:

shell kubectl patch nodegroup --type merge -p '{"spec":{"cri":{"type":"NotManaged"}}}'

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: nodeType: Static cri: type: Containerd

While changing cri.type for NodeGroups, created using dhctl, you must change it in dhctl config edit provider-cluster-configuration and in NodeGroup object.

Также эту операцию можно выполнить с помощью патча:

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 disruption setting for NodeGroup, the node-manager module either automatically allows node updates or requires manual confirmation.

  • Для Containerd:

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 Containerd to NotManaged and back (the cri.type parameter).

  • Для NotManaged:

It is necessary to use the dhctl utility to edit the defaultCRI parameter in the cluster-configuration config.

shell kubectl patch nodegroup <имя NodeGroup=""> --type merge -p '{"spec":{"cri":{"type":"NotManaged"}}}'

Also, this operation can be done with the following patch:

При изменении cri.type для NodeGroup, созданных с помощью dhctl, необходимо обновить это значение в dhctl config edit provider-cluster-configuration и настройках объекта NodeGroup.

  • For Containerd:

После изменения CRI для NodeGroup модуль node-manager будет поочередно перезагружать узлы, применяя новый CRI. Обновление узла сопровождается простоем (disruption). В зависимости от настройки disruption для NodeGroup, модуль node-manager либо автоматически выполнит обновление узлов, либо потребует подтверждения вручную.

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 для всего кластера?

  • For NotManaged:

Смена CRI возможна только между Containerd на NotManaged и обратно (параметр cri.type).

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 для всего кластера, необходимо с помощью утилиты dhctl отредактировать параметр defaultCRI в конфигурационном файле cluster-configuration.

If it is necessary to leave some NodeGroup on another CRI, then before changing the defaultCRI it is necessary to set CRI for this NodeGroup, as described here.

Также возможно выполнить эту операцию с помощью kubectl patch.

Changing defaultCRI entails changing CRI on all nodes, including master nodes. If there is only one master node, this operation is dangerous and can lead to a complete failure of the cluster! The preferred option is to make a multi-master and change the CRI type.

  • Для Containerd:

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"}}”

  1. Deckhouse updates nodes in master NodeGroup one by one, so you need to discover which node is updating right now:
  • Для NotManaged:

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"}}”

  1. Confirm the disruption of the master node that was discovered in the previous step:

Если необходимо, чтобы отдельные NodeGroup использовали другой CRI, перед изменением defaultCRI необходимо установить CRI для этой NodeGroup, как описано в документации.

shell kubectl annotate node update.node.deckhouse.io/disruption-approved=

Изменение defaultCRI влечет за собой изменение CRI на всех узлах, включая master-узлы. Если master-узел один, данная операция является опасной и может привести к полной неработоспособности кластера. Рекомендуется использовать multimaster-конфигурацию и менять тип CRI только после этого.

  1. Wait for the updated master node to switch to Ready state. Repeat steps for the next master node.

При изменении CRI в кластере для master-узлов необходимо выполнить дополнительные шаги:

How to add node configuration step?

  1. Чтобы определить, какой узел в текущий момент обновляется в master NodeGroup, используйте следующую команду:

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?

  1. Подтвердите остановку (disruption) для master-узла, полученного на предыдущем шаге:
  1. On the node, create the directory /var/lib/node_labels.

shell kubectl annotate node <имя master-узла=""> update.node.deckhouse.io/disruption-approved=

  1. Create a file or files containing the necessary labels in it. The number of files can be any, as well as the number of subdirectories containing them.
  1. Дождаитесь перехода обновленного master-узла в Ready. Выполните итерацию для следующего master-узла.
  1. Add the necessary labels to the files in the key=value format. For example:

Как добавить шаг для конфигурации узлов?

console example-label=test

Дополнительные шаги для конфигурации узлов задаются с помощью кастомного ресурса NodeGroupConfiguration.

  1. Save the files.

Как автоматически проставить на узел кастомные лейблы?

When adding a node to the cluster, the labels specified in the files will be automatically affixed to the node.

  1. На узле создайте каталог /var/lib/node_labels.

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.

  1. Создайте в нём файл или файлы, содержащие необходимые лейблы. Количество файлов может быть любым, как и вложенность подкаталогов, их содержащих.

How to use containerd with Nvidia GPU support?

  1. Добавьте в файлы нужные лейблы в формате key=value. Например:

Create NodeGroup for GPU-nodes.

console example-label=test

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: gpu spec: chaos: mode: Disabled disruptions: approvalMode: Automatic nodeType: CloudStatic

  1. Сохраните файлы.

Create NodeGroupConfiguration for containerd configuration of NodeGroup gpu:

При добавлении узла в кластер указанные в файлах лейблы будут автоматически проставлены на узел.

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config.sh spec: bundles:

  • ‘*’ content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Обратите внимание, что добавить таким образом лейблы, использующиеся в DKP, невозможно. Работать такой метод будет только с кастомными лейблами, не пересекающимися с зарезервированными для Deckhouse.

mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/nvidia_gpu.toml - « “EOF” [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.containerd] default_runtime_name = “nvidia” [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes] [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.runc] [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.nvidia] privileged_without_host_devices = false runtime_engine = “” runtime_root = “” runtime_type = “io.containerd.runc.v1” [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.nvidia.options] BinaryName = “/usr/bin/nvidia-container-runtime” SystemdCgroup = false EOF nodeGroups:

  • gpu weight: 31

Как использовать containerd с поддержкой Nvidia GPU?

Create NodeGroupConfiguration for Nvidia drivers setup on NodeGroup gpu.

Необходимо создать отдельную NodeGroup для GPU-узлов:

Ubuntu

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: gpu spec: chaos: mode: Disabled disruptions: approvalMode: Automatic nodeType: CloudStatic

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:

  • ubuntu-lts content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Далее создайте NodeGroupConfiguration для NodeGroup gpu для конфигурации containerd:

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:

  • gpu weight: 30

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config.sh spec: bundles:

  • ‘*’ content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Centos

mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/nvidia_gpu.toml - « “EOF” [plugins] [plugins.”io.containerd.grpc.v1.cri”] [plugins.”io.containerd.grpc.v1.cri”.containerd] default_runtime_name = “nvidia” [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes] [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.runc] [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.nvidia] privileged_without_host_devices = false runtime_engine = “” runtime_root = “” runtime_type = “io.containerd.runc.v1” [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.nvidia.options] BinaryName = “/usr/bin/nvidia-container-runtime” SystemdCgroup = false EOF nodeGroups:

  • gpu weight: 31

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:

  • centos content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Добавьте NodeGroupConfiguration для установки драйверов Nvidia для NodeGroup gpu.

if [ ! -f “/etc/yum.repos.d/nvidia-container-toolkit.repo” ]; then distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo fi bb-yum-install nvidia-container-toolkit nvidia-driver nvidia-ctk config –set nvidia-container-runtime.log-level=error –in-place nodeGroups:

  • gpu weight: 30

Ubuntu

Bootstrap and reboot node.

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:

  • ubuntu-lts content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

How to check if it was successful?

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:

  • gpu weight: 30

Deploy the Job:

Centos

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:

  • name: nvidia-cuda-test image: nvidia/cuda:11.6.2-base-ubuntu20.04 imagePullPolicy: “IfNotPresent” command:
  • nvidia-smi

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: install-cuda.sh spec: bundles:

  • centos content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

And check the logs:

if [ ! -f “/etc/yum.repos.d/nvidia-container-toolkit.repo” ]; then distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo fi bb-yum-install nvidia-container-toolkit nvidia-driver nvidia-ctk config –set nvidia-container-runtime.log-level=error –in-place nodeGroups:

  • gpu weight: 30

shell $ kubectl logs job/nvidia-cuda-test Tue Jan 24 11:36:18 2023 +—————————————————————————–+ | NVIDIA-SMI 525.60.13 Driver Version: 525.60.13 CUDA Version: 12.0 | |——————————-+———————-+———————-+ | 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 T4 Off | 00000000:8B:00.0 Off | 0 | | N/A 45C P0 25W / 70W | 0MiB / 15360MiB | 0% Default | | | | N/A | +——————————-+———————-+———————-+

После того как конфигурации будут применены, необходимо провести бутстрап и перезагрузить узлы, чтобы применить настройки и установить драйвера.

+—————————————————————————–+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +—————————————————————————–+

Как проверить, что все прошло успешно?

Deploy the Job:

Создайте в кластере 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:

  • name: gpu-operator-test image: nvidia/samples:vectoradd-cuda10.2 imagePullPolicy: “IfNotPresent”

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:

  • name: nvidia-cuda-test image: nvidia/cuda:11.6.2-base-ubuntu20.04 imagePullPolicy: “IfNotPresent” command:
  • nvidia-smi

And check the logs:

Проверьте логи командой:

shell $ kubectl logs job/gpu-operator-test [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

shell $ kubectl logs job/nvidia-cuda-test Tue Jan 24 11:36:18 2023 +—————————————————————————–+ | NVIDIA-SMI 525.60.13 Driver Version: 525.60.13 CUDA Version: 12.0 | |——————————-+———————-+———————-+ | 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 T4 Off | 00000000:8B:00.0 Off | 0 | | N/A 45C P0 25W / 70W | 0MiB / 15360MiB | 0% Default | | | | N/A | +——————————-+———————-+———————-+

How to deploy custom containerd configuration?

+—————————————————————————–+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +—————————————————————————–+

The example of NodeGroupConfiguration uses functions of the script 032_configure_containerd.sh.

Создайте в кластере Job:

Adding custom settings causes a restart of the containerd service.

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:

  • name: gpu-operator-test image: nvidia/samples:vectoradd-cuda10.2 imagePullPolicy: “IfNotPresent”

Bashible on nodes merges main Deckhouse containerd config with configs from /etc/containerd/conf.d/*.toml.

Проверьте логи командой:

You can override the values of the parameters that are specified in the file /etc/containerd/deckhouse.toml, but you will have to ensure their functionality on your own. Also, it is better not to change the configuration for the master nodes (nodeGroup master).

shell $ kubectl logs job/gpu-operator-test [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

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-option-config.sh spec: bundles:

  • ‘*’ content: | Copyright 2024 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Как развернуть кастомный конфигурационный файл 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:

  • “worker” weight: 31

Пример NodeGroupConfiguration основан на функциях, заложенных в скрипте 032_configure_containerd.sh.

How to add additional registry auth?

Добавление кастомных настроек вызывает перезапуск сервиса containerd.

Deploy NodeGroupConfiguration script:

Bashible на узлах объединяет конфигурацию containerd для Deckhouse с конфигурацией из файла /etc/containerd/conf.d/*.toml.

yaml

apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config.sh spec: bundles:

  • ‘*’ content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. REGISTRY_URL=private.registry.example

Вы можете переопределять значения параметров, которые заданы в файле /etc/containerd/deckhouse.toml, но их работу придётся обеспечивать самостоятельно. Также, лучше изменением конфигурации не затрагивать master-узлы (nodeGroup master).

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.”docker.io”] endpoint = [“https://registry-1.docker.io”] [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 = “AAAABBBCCCDDD==” EOF nodeGroups:

  • “*” weight: 31

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-option-config.sh spec: bundles:

  • ‘*’ content: | Copyright 2024 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

How to configure a certificate for an additional registry?

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:

  • “worker” weight: 31

In addition to containerd, the certificate can be simultaneously added into the OS.

Как добавить авторизацию в дополнительный registry?

Example of the NodeGroupConfiguration resource for configuring a certificate for an additional registry:

Разверните скрипт NodeGroupConfiguration:

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: configure-cert-containerd.sh spec: bundles:

  • ‘*’ content: |- Copyright 2024 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config.sh spec: bundles:

  • ‘*’ content: | Copyright 2023 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. REGISTRY_URL=private.registry.example

REGISTRY_URL=private.registry.example CERT_FILE_NAME=${REGISTRY_URL} CERTS_FOLDER=”/var/lib/containerd/certs/” CERT_CONTENT=$(cat «“EOF” —–BEGIN CERTIFICATE—– MIIDSjCCAjKgAwIBAgIRAJ4RR/WDuAym7M11JA8W7D0wDQYJKoZIhvcNAQELBQAw JTEjMCEGA1UEAxMabmV4dXMuNTEuMjUwLjQxLjIuc3NsaXAuaW8wHhcNMjQwODAx MTAzMjA4WhcNMjQxMDMwMTAzMjA4WjAlMSMwIQYDVQQDExpuZXh1cy41MS4yNTAu NDEuMi5zc2xpcC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1p WLPr2c4SZX/i4IS59Ly1USPjRE21G4pMYewUjkSXnYv7hUkHvbNL/P9dmGBm2Jsl WFlRZbzCv7+5/J+9mPVL2TdTbWuAcTUyaG5GZ/1w64AmAWxqGMFx4eyD1zo9eSmN G2jis8VofL9dWDfUYhRzJ90qKxgK6k7tfhL0pv7IHDbqf28fCEnkvxsA98lGkq3H fUfvHV6Oi8pcyPZ/c8ayIf4+JOnf7oW/TgWqI7x6R1CkdzwepJ8oU7PGc0ySUWaP G5bH3ofBavL0bNEsyScz4TFCJ9b4aO5GFAOmgjFMMUi9qXDH72sBSrgi08Dxmimg Hfs198SZr3br5GTJoAkCAwEAAaN1MHMwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB /wQCMAAwUwYDVR0RBEwwSoIPbmV4dXMuc3ZjLmxvY2FsghpuZXh1cy41MS4yNTAu NDEuMi5zc2xpcC5pb4IbZG9ja2VyLjUxLjI1MC40MS4yLnNzbGlwLmlvMA0GCSqG SIb3DQEBCwUAA4IBAQBvTjTTXWeWtfaUDrcp1YW1pKgZ7lTb27f3QCxukXpbC+wL dcb4EP/vDf+UqCogKl6rCEA0i23Dtn85KAE9PQZFfI5hLulptdOgUhO3Udluoy36 D4WvUoCfgPgx12FrdanQBBja+oDsT1QeOpKwQJuwjpZcGfB2YZqhO0UcJpC8kxtU by3uoxJoveHPRlbM2+ACPBPlHu/yH7st24sr1CodJHNt6P8ugIBAZxi3/Hq0wj4K aaQzdGXeFckWaxIny7F1M3cIWEXWzhAFnoTgrwlklf7N7VWHPIvlIh1EYASsVYKn iATq8C7qhUOGsknDh3QSpOJeJmpcBwln11/9BGRP —–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.mirrors] [plugins.”io.containerd.grpc.v1.cri”.registry.mirrors.”docker.io”] endpoint = [“https://registry-1.docker.io”] [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 = “AAAABBBCCCDDD==” EOF nodeGroups:

  • “*” weight: 31

CONFIG_CONTENT=$(cat «EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] ca_file = “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” EOF )

Как настроить сертификат для дополнительного registry?

mkdir -p ${CERTS_FOLDER} mkdir -p /etc/containerd/conf.d

Помимо containerd, сертификат можно одновременно добавить и в операционной системе.

bb-tmp-file - Create temp file function. More information: http://www.bashbooster.net/#tmp

Пример NodeGroupConfiguration для настройки сертификата для дополнительного registry:

CERT_TMP_FILE=”$( bb-tmp-file )” echo -e “${CERT_CONTENT}” > “${CERT_TMP_FILE}”
CONFIG_TMP_FILE=”$( bb-tmp-file )” echo -e “${CONFIG_CONTENT}” > “${CONFIG_TMP_FILE}”

yaml apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: configure-cert-containerd.sh spec: bundles:

  • ‘*’ content: |- Copyright 2024 Flant JSC # Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

bb-sync-file - File synchronization function. More information: http://www.bashbooster.net/#sync “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” - Destination file ${CERT_TMP_FILE} - Source file

REGISTRY_URL=private.registry.example CERT_FILE_NAME=${REGISTRY_URL} CERTS_FOLDER=”/var/lib/containerd/certs/” CERT_CONTENT=$(cat «“EOF” —–BEGIN CERTIFICATE—– MIIDSjCCAjKgAwIBAgIRAJ4RR/WDuAym7M11JA8W7D0wDQYJKoZIhvcNAQELBQAw JTEjMCEGA1UEAxMabmV4dXMuNTEuMjUwLjQxLjIuc3NsaXAuaW8wHhcNMjQwODAx MTAzMjA4WhcNMjQxMDMwMTAzMjA4WjAlMSMwIQYDVQQDExpuZXh1cy41MS4yNTAu NDEuMi5zc2xpcC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1p WLPr2c4SZX/i4IS59Ly1USPjRE21G4pMYewUjkSXnYv7hUkHvbNL/P9dmGBm2Jsl WFlRZbzCv7+5/J+9mPVL2TdTbWuAcTUyaG5GZ/1w64AmAWxqGMFx4eyD1zo9eSmN G2jis8VofL9dWDfUYhRzJ90qKxgK6k7tfhL0pv7IHDbqf28fCEnkvxsA98lGkq3H fUfvHV6Oi8pcyPZ/c8ayIf4+JOnf7oW/TgWqI7x6R1CkdzwepJ8oU7PGc0ySUWaP G5bH3ofBavL0bNEsyScz4TFCJ9b4aO5GFAOmgjFMMUi9qXDH72sBSrgi08Dxmimg Hfs198SZr3br5GTJoAkCAwEAAaN1MHMwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB /wQCMAAwUwYDVR0RBEwwSoIPbmV4dXMuc3ZjLmxvY2FsghpuZXh1cy41MS4yNTAu NDEuMi5zc2xpcC5pb4IbZG9ja2VyLjUxLjI1MC40MS4yLnNzbGlwLmlvMA0GCSqG SIb3DQEBCwUAA4IBAQBvTjTTXWeWtfaUDrcp1YW1pKgZ7lTb27f3QCxukXpbC+wL dcb4EP/vDf+UqCogKl6rCEA0i23Dtn85KAE9PQZFfI5hLulptdOgUhO3Udluoy36 D4WvUoCfgPgx12FrdanQBBja+oDsT1QeOpKwQJuwjpZcGfB2YZqhO0UcJpC8kxtU by3uoxJoveHPRlbM2+ACPBPlHu/yH7st24sr1CodJHNt6P8ugIBAZxi3/Hq0wj4K aaQzdGXeFckWaxIny7F1M3cIWEXWzhAFnoTgrwlklf7N7VWHPIvlIh1EYASsVYKn iATq8C7qhUOGsknDh3QSpOJeJmpcBwln11/9BGRP —–END CERTIFICATE—– EOF )

bb-sync-file
“${CERTS_FOLDER}/${CERT_FILE_NAME}.crt”
${CERT_TMP_FILE}

CONFIG_CONTENT=$(cat «EOF [plugins] [plugins.”io.containerd.grpc.v1.cri”.registry.configs.”${REGISTRY_URL}”.tls] ca_file = “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” EOF )

bb-sync-file
“/etc/containerd/conf.d/${REGISTRY_URL}.toml”
${CONFIG_TMP_FILE} nodeGroups:

  • ‘*’
    weight: 31

mkdir -p ${CERTS_FOLDER} mkdir -p /etc/containerd/conf.d

How to use NodeGroup’s priority feature

bb-tmp-file - Create temp file function. More information: http://www.bashbooster.net/#tmp

The priority field of the NodeGroup CustomResource allows you to define the order in which nodes will be provisioned in the cluster. For example, cluster-autoscaler can first provision spot-nodes and switch to regular ones when they run out. Or it can provision larger nodes when there are plenty of resources in the cluster and then switch to smaller nodes once cluster resources run out.

CERT_TMP_FILE=”$( bb-tmp-file )” echo -e “${CERT_CONTENT}” > “${CERT_TMP_FILE}”
CONFIG_TMP_FILE=”$( bb-tmp-file )” echo -e “${CONFIG_CONTENT}” > “${CONFIG_TMP_FILE}”

Here is an example of creating two NodeGroups using spot-node nodes:

bb-sync-file - File synchronization function. More information: http://www.bashbooster.net/#sync “${CERTS_FOLDER}/${CERT_FILE_NAME}.crt” - Destination file ${CERT_TMP_FILE} - Source file

yaml

apiVersion: 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

bb-sync-file
“${CERTS_FOLDER}/${CERT_FILE_NAME}.crt”
${CERT_TMP_FILE}

In the above example, cluster-autoscaler will first try to provision a spot-node. If it fails to add such a node to the cluster within 15 minutes, the worker-spot NodeGroup will be paused (for 20 minutes), and cluster-autoscaler will start provisioning nodes from the worker NodeGroup. If, after 30 minutes, another node needs to be deployed in the cluster, cluster-autoscaler will first attempt to provision a node from the worker-spot NodeGroup before provisioning one from the worker NodeGroup.

bb-sync-file
“/etc/containerd/conf.d/${REGISTRY_URL}.toml”
${CONFIG_TMP_FILE} nodeGroups:

  • ‘*’
    weight: 31

Once the worker-spot NodeGroup reaches its maximum (5 nodes in the example above), the nodes will be provisioned from the worker NodeGroup.

Как использовать NodeGroup с приоритетом?

Note that node templates (labels/taints) for worker and worker-spot NodeGroups must be the same (or at least suitable for the load that triggers the cluster scaling process).

С помощью параметра priority кастомного ресурса NodeGroup можно задавать порядок заказа узлов в кластере. Например, можно сделать так, чтобы сначала заказывались узлы типа spot-node, а если они закончились — обычные узлы. Или чтобы при наличии ресурсов в облаке заказывались узлы большего размера, а при их исчерпании — узлы меньшего размера.

How to interpret Node Group states?

Пример создания двух NodeGroup с использованием узлов типа spot-node:

Ready — the node group contains the minimum required number of scheduled nodes with the status Ready for all zones.

yaml

apiVersion: 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

Example 1. A group of nodes in the Ready state:

В приведенном выше примере, cluster-autoscaler сначала попытается заказать узел типа _spot-node. Если в течение 15 минут его не получится добавить в кластер, NodeGroup worker-spot будет поставлен на паузу (на 20 минут) и cluster-autoscaler начнет заказывать узлы из NodeGroup worker. Если через 30 минут в кластере возникнет необходимость развернуть еще один узел, cluster-autoscaler сначала попытается заказать узел из NodeGroup worker-spot и только потом — из NodeGroup worker.

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 1 status: conditions:

  • status: “True” type: Ready — apiVersion: v1 kind: Node metadata: name: node1 labels: node.deckhouse.io/group: ng1 status: conditions:
  • status: “True” type: Ready

После того как NodeGroup worker-spot достигнет своего максимума (5 узлов в примере выше), узлы будут заказываться из NodeGroup worker.

Example 2. A group of nodes in the Not Ready state:

Шаблоны узлов (labels/taints) для NodeGroup worker и worker-spot должны быть одинаковыми, или как минимум подходить для той нагрузки, которая запускает процесс увеличения кластера.

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: conditions:

  • status: “False” type: Ready — apiVersion: v1 kind: Node metadata: name: node1 labels: node.deckhouse.io/group: ng1 status: conditions:
  • status: “True” type: Ready

Как интерпретировать состояние группы узлов?

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).

Ready — группа узлов содержит минимально необходимое число запланированных узлов с состоянием Ready для всех зон.

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.

Пример 1. Группа узлов в состоянии Ready:

Scaling — calculated only for node groups with the type CloudEphemeral. The state True can be in two cases:

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 1 status: conditions:

  • status: “True” type: Ready — apiVersion: v1 kind: Node metadata: name: node1 labels: node.deckhouse.io/group: ng1 status: conditions:
  • status: “True” type: Ready
  1. When the number of nodes is less than the desired number of nodes in the group, i.e. when it is necessary to increase the number of nodes in the group.
  2. When a node is marked for deletion or the number of nodes is greater than the desired number of nodes, i.e. when it is necessary to reduce the number of nodes in the group.

Пример 2. Группа узлов в состоянии Not Ready:

The desired number of nodes is the sum of all replicas in the node group.

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: conditions:

  • status: “False” type: Ready — apiVersion: v1 kind: Node metadata: name: node1 labels: node.deckhouse.io/group: ng1 status: conditions:
  • status: “True” type: Ready

Example. The desired number of nodes is 2:

Updating — группа узлов содержит как минимум один узел, в котором присутствует аннотация с префиксом update.node.deckhouse.io (например, update.node.deckhouse.io/waiting-for-approval).

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: … desired: 2 …

WaitingForDisruptiveApproval — группа узлов содержит как минимум один узел, в котором присутствует аннотация update.node.deckhouse.io/disruption-required и отсутствует аннотация update.node.deckhouse.io/disruption-approved.

Error — contains the last error that occurred when creating a node in a node group.

Scaling — рассчитывается только для групп узлов с типом CloudEphemeral. Состояние True может быть в двух случаях:

How do I make werf ignore the Ready conditions in a node group?

  1. Когда число узлов меньше желаемого числа узлов в группе, то есть когда нужно увеличить число узлов в группе.
  2. Когда какой-то узел помечается к удалению или число узлов больше желаемого числа узлов, то есть когда нужно уменьшить число узлов в группе.

werf checks the Ready status of resources and, if available, waits for the value to become True.

Желаемое число узлов — это сумма всех реплик, входящих в группу узлов.

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 nodeGroup annotations must be added:

Пример. Желаемое число узлов равно 2:

yaml metadata: annotations: werf.io/fail-mode: IgnoreAndContinueDeployProcess werf.io/track-termination-mode: NonBlocking

yaml apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: ng1 spec: nodeType: CloudEphemeral cloudInstances: maxPerZone: 5 minPerZone: 2 status: … desired: 2 …

What is an Instance resource?

Error — содержит последнюю ошибку, возникшую при создании узла в группе узлов.

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.

Как заставить werf игнорировать состояние Ready в группе узлов?

The object does not contain a specification. The status contains:

werf проверяет состояние Ready у ресурсов и в случае его наличия дожидается, пока значение станет True.

  1. A link to the InstanceClass if it exists for this implementation;
  2. A link to the Kubernetes Node object;
  3. Current machine status;
  4. Information on how to view machine creation logs (at the machine creation stage).

Создание (обновление) ресурса nodeGroup в кластере может потребовать значительного времени на развертывание необходимого количества узлов. При развертывании такого ресурса в кластере с помощью werf (например, в рамках процесса CI/CD) развертывание может завершиться по превышении времени ожидания готовности ресурса. Чтобы заставить werf игнорировать состояние nodeGroup, необходимо добавить к nodeGroup следующие аннотации:

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).

yaml metadata: annotations: werf.io/fail-mode: IgnoreAndContinueDeployProcess werf.io/track-termination-mode: NonBlocking

When is a node reboot required?

Что такое ресурс Instance?

Node reboots may be required after configuration changes. For example, after changing certain sysctl settings, specifically when modifying the kernel.yama.ptrace_scope parameter (e.g., using astra-ptrace-lock enable/disable in the Astra Linux distribution).

Ресурс Instance в Kubernetes представляет собой описание объекта эфемерной виртуальной машины, но без конкретной реализации. Это абстракция, которая используется для управления машинами, созданными с помощью таких инструментов, как MachineControllerManager или Cluster API Provider Static.

 

Объект не содержит спецификации. Статус содержит:

 
  1. Ссылку на InstanceClass, если он существует для данной реализации.
  2. Ссылку на объект Node Kubernetes.
  3. Текущий статус машины.
  4. Информацию о том, как проверить логи создания машины (появляется на этапе создания машины).
 

При создании или удалении машины создается или удаляется соответствующий объект Instance. Самостоятельно ресурс Instance создать нельзя, но можно удалить. В таком случае машина будет удалена из кластера (процесс удаления зависит от деталей реализации).

 

Когда требуется перезагрузка узлов?

 

Некоторые операции по изменению конфигурации узлов могут потребовать перезагрузки.

 

Перезагрузка узла может потребоваться при изменении некоторых настроек sysctl, например, при изменении параметра kernel.yama.ptrace_scope (изменяется при использовании команды astra-ptrace-lock enable/disable в Astra Linux).