Тема
Добавление и удаление узлов кластера
Предисловие
В данном разделе описано, как добавить новый узел (worker) к существующему управляющему кластеру платформы Боцман и как удалить узел из кластера.
Добавить узел можно двумя способами:
- Автоматический способ — установка пакета
byoh-agentи саморегистрация (self-registration). Агент сам генерирует ключ и CSR, сам регистрируется в управляющем кластере по автообнаружению через UDP-broadcast. Применяется при стандартной установке и является рекомендуемым методом. - Ручная регистрация через CSR — применяется только для сетей без общего broadcast-домена, где автообнаружение кластера (auto discovery) не работает.
Как это работает
Управляющий кластер платформы Боцман управляет машинами через механизм BYOH (bring-your-own-host). На каждой машине работает host-agent — агент (бинарник byoh-agent, systemd-юнит host-agent.service), который регистрируется в управляющем кластере и создаёт ресурс ByoHost.
Дальнейший сценарий добавления воркера устроен так:
host-agentна новой машине регистрируется в управляющем кластере и создаёт объектByoHost(kindByoHost, short namebyoh, apiVersioninfrastructure.cluster.x-k8s.io/v1beta1).- Пока у объекта
ByoHostОТСУТСТВУЕТ меткаcluster.x-k8s.io/cluster-name, хост считается свободным (доступным) — он ещё не привязан ни к какому кластеру. - В Web-интерфейсе на странице управления кластером в разделе
WorkerPoolнажмите кнопку добавления ноды. Это увеличивает полеWorkerPool.spec.replicasна 1. - Увеличение числа реплик создаёт
MachineDeployment, затем CAPI-объектMachineиByoMachine. Планировщик выбирает любой свободныйByoHostи привязывает его, проставляя меткуcluster.x-k8s.io/cluster-name. - Выбранная машина присоединяется к кластеру в роли воркера.
Схема объектных абстракций:
provisioning.WorkerPool — абстракция пула воркеров (управляется пользователем)
└── MachineDeployment — CAPI-объект, управляет репликами машин
└── Machine — CAPI-объект, представляет одну машину
└── ByoMachine — инфраструктурный объект провайдера BYOH
└── ByoHost — зарегистрированный хост (привязывается меткой)Таким образом, для добавления воркера достаточно, чтобы в кластере существовал хотя бы один свободный ByoHost, прошедший проверки и подходящий по меткам селектору WorkerPool.
Подготовка
Новая машина должна соответствовать требованиям, предъявляемым к узлам кластера. Подробно процесс подготовки описан в разделе Требования к подготовке инфраструктуры.
Общие требования:
- инфраструктура совместима с одним из поддерживаемых провайдеров кластера;
- установлена поддерживаемая операционная система;
- машина доступна по сети из управляющего кластера;
- выполнены требования к ресурсам (CPU, RAM, диск).
Способ 1. Автоматическое добавление
Установка и настройка host-agent
Установите host-agent из комплекта поставки на новую машину. Используйте файл, соответствующий операционной системе:
bash
sudo dpkg --install /home/bootsman/byoh-agent-{++version++}-amd64.debbash
sudo dpkg --install /home/bootsman/byoh-agent-{++version++}-amd64.debbash
sudo rpm -U /home/bootsman/byoh-agent-{++version++}-1.el7.x86_64.rpmПакет устанавливает бинарный файл /usr/bin/byoh-agent и systemd-юнит host-agent.service.
Настройка роли узла
Чтобы новая машина могла быть выбрана целевым WorkerPool, на неё нужно добавить ролевую метку role=<роль> — так же, как это делается при подготовке узлов управляющего кластера. Для воркера роль — worker.
Добавьте ролевую метку в юнит host-agent:
bash
export ROLE=worker
sudo sed -i "s#ExecStart=\"/usr/bin/byoh-agent\"#ExecStart=\"/usr/bin/byoh-agent\" --label role=${ROLE}#" /usr/lib/systemd/system/host-agent.serviceПроверьте результат:
bash
cat /usr/lib/systemd/system/host-agent.serviceВ секции [Service] строка запуска должна иметь вид:
bash
ExecStart=/usr/bin/byoh-agent --label role=workerВажно!
Метка роли должна совпадать с селектором целевого WorkerPool (по умолчанию role=worker). Если метка не совпадёт, планировщик отфильтрует хост и воркер не добавится.
Перезапустите агент:
bash
sudo systemctl daemon-reload
sudo systemctl restart host-agentФлаги агента
Ключевые флаги запуска агента:
--label имя=значение— метка на ресурсеByoHost. Флаг можно указывать несколько раз. Например,--label role=worker. Именно по меткам планировщик подбирает хост под селекторWorkerPool, поэтому ролевая метка обязательна (см. раздел выше).--namespace— пространство имён управляющего кластера, в которое регистрируется хост. По умолчанию —default. Укажите то же пространство имён, в котором размещён управляющий кластер, если оно отличается отdefault.--registration-server <адрес>и--target-cluster <имя кластера>— укажите, если машина НЕ находится в том же broadcast-домене, что и управляющий кластер. Если машина в том же broadcast-домене, работает автообнаружение кластера по UDP-broadcast.--discoveryWaitWindow— время поиска кластера. По умолчанию — 60 секунд.
Запуск и регистрация
Включите и запустите юнит:
bash
sudo systemctl enable --now host-agentЗаметка
Конфигурация агента записывается в /root/.byoh/config. При наличии этого файла агент повторно не регистрируется. Если нужно перерегистрировать машину, удалите файл и перезапустите агент (см. инструкцию по очистке ноды от компонентов k8s).
Проверка регистрации
Дождитесь регистрации хоста в управляющем кластере. Проверьте появление объекта ByoHost:
bash
kubectl get byoh {++HOSTNAME++}Убедитесь, что хост свободен — метка кластера отсутствует:
bash
kubectl get byoh {++HOSTNAME++} -o jsonpath='{.metadata.labels.cluster\.x-k8s\.io/cluster-name}'Команда должна вернуть пустую строку. Пустой вывод означает, что хост свободен и может быть выбран планировщиком при добавлении воркера.
Добавление воркера в Web-UI
Войдите в Web-интерфейс Боцмана и откройте раздел управления кластерами. В списке выберите нужный кластер.
На странице кластера перейдите к секции WorkerPool — здесь отображаются узлы и настройки пула. Число реплик пула соответствует числу воркеров кластера.


Увеличьте число реплик с помощью стрелок или укажите их числом.
Число реплик WorkerPool увеличится, платформа создаст MachineDeployment, а планировщик привяжет к нему свободный ByoHost.
Убедитесь, что новая машина появилась в кластере: число узлов в пуле увеличилось на 1, а у соответствующего объекта ByoHost появилась метка cluster.x-k8s.io/cluster-name.
Заметка
Внешний вид страницы управления кластером зависит от версии платформы и выбранного провайдера. Кнопка добавления узла всегда расположена в секции WorkerPool целевого кластера.
Альтернатива: добавление через CLI
Тот же результат можно получить, увеличив число реплик WorkerPool на 1 командой:
bash
kubectl patch workerpool.provisioning.bootsman.tech {++POOL_NAME++} --type=merge -p='{"spec":{"replicas": {++NEW_REPLICA_COUNT++}}}'Где:
<mark>POOL_NAME</mark>— имя пулаWorkerPool, к которому добавляется воркер;<mark>NEW_REPLICA_COUNT</mark>— новое число реплик (текущее значение, увеличенное на 1).
Получите список пулов кластера:
bash
kubectl get workerpool.provisioning.bootsman.techСпособ 2. Ручная регистрация через CSR
Иногда нет возможности разместить серверы внутри одного broadcast-домена. В этом случае машину можно добавить самостоятельно, без механизма auto discovery.
Для выполнения этой инструкции понадобится:
- openssl;
- base64;
- kubectl;
- kubeconfig администратора;
- адрес (K8SCPIP) и CA controlplane.
Подготовка
Подробно процесс подготовки описан в разделе Требования к подготовке инфраструктуры. Выполните все шаги из этой инструкции.
Генерация конфигурации для host-agent
Генерация нового приватного ключа
bash
openssl genrsa -out {++HOSTNAME++}.key 2048Генерация CSR и кодирование его в base64
Внимание!
При генерации CSR очень важно заполнить поля Organization Name (O) и Common Name (CN).
Organization Name всегда должен быть равен byoh:hosts.
Common Name заполните по следующему паттерну: byoh:host:<mark>HOSTNAME</mark>.
Запустите генерацию CSR:
bash
openssl req -new -key {++HOSTNAME++}.key -out {++HOSTNAME++}.csrПоявится помощник с интерактивными вопросами. Для регистрации сервера в кластере заполните их без ошибок.
Ответы на интерактивные вопросы
Organization Name (eg, company) [Internet Widgits Pty Ltd]: byoh:hosts
Common Name (e.g. server or YOUR name) []: byoh:host:HOSTNAME
Получите содержимое запроса сертификата в base64:
bash
cat {++HOSTNAME++}.csr | base64 | tr -d '\n'Получившуюся строку сохраните, она понадобится позже. В месте её использования будет переменная <mark>CSR_BASE64</mark>.
Создайте CertificateSigningRequest:
yaml
---
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: byoh-csr-{++HOSTNAME++}
spec:
request: {++CSR_BASE64++}
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
expirationSeconds: 31536000Примените его в управляющем кластере с помощью kubectl apply.
Проверьте его статус:
bash
kubectl get csr byoh-csr-{++HOSTNAME++}В правой колонке должно быть Approved, Issued.
Получение сертификата
bash
kubectl get csr byoh-csr-{++HOSTNAME++} -o jsonpath='{.status.certificate}'Получившуюся строку сохраните, она понадобится далее. В месте её использования будет переменная <mark>CERT_BASE64</mark>.
Закодируйте ключ в base64:
bash
cat {++HOSTNAME++}.key | base64 | tr -d '\n'Получившуюся строку сохраните, она понадобится далее. В месте её использования будет переменная <mark>KEY_BASE64</mark>.
Создание kubeconfig для машины
Переменные <mark>API_SERVER_ADDRESS</mark> и <mark>API_SERVER_CA</mark> можно скопировать с уже зарегистрированных машин или из <mark>cluster-admin kubeconfig</mark>, который хранится на любом мастере по пути /etc/kubernetes/admin.conf.
Заметка
kubeconfig из веб-интерфейса не подойдёт.
yaml
---
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: {++API_SERVER_CA++}
server: {++API_SERVER_ADDRESS++}
name: default-cluster
contexts:
- context:
cluster: default-cluster
namespace: default
user: default-auth
name: default-context
current-context: default-context
kind: Config
preferences: {}
users:
- name: default-auth
user:
client-certificate-data: {++CERT_BASE64++} # можно получить с помощью kubectl get csr byoh-csr-{++HOSTNAME++} -o jsonpath='{.status.certificate}'
client-key-data: {++KEY_BASE64++} # можно получить с помощью cat {++HOSTNAME++}.key | base64 | tr -d '\n'Сохраните этот конфиг на машине, которую планируете завести в кластер, по пути /root/.byoh/config.
Владелец и группа файла должны быть root, права 0600 (rw-------).
Запустите агент:
bash
sudo systemctl start host-agentПроверьте в управляющем кластере появление машины:
bash
kubectl get byoh {++HOSTNAME++}Ручное удаление узлов из кластера
Предисловие
Боцман в стандартном исполнении реализует подход cattle для управления инфраструктурой. Это значит, что он относится к серверам, на которых он работает, как к стаду. При запуске процесса уменьшения количества серверов (ScaleDown) он выберет случайный сервер и удалит его из кластера.
Но иногда требуется контролировать, какой именно сервер будет удалён из кластера. Такой подход называется pet. С этой инструкцией вы сможете самостоятельно управлять процессом удаления машин из кластера.
Подготовка к удалению
Рекомендуется использовать мягкий способ удаления, особенно в высоконагруженных кластерах. Для этого выполните действия:
- отправьте машину в
cordon; - отправьте машину в
drain; - перенесите с неё реплики
Longhorn.
Внимание!
Жёсткий способ подразумевает удаление без ручного переноса реплик и приложений. Это может привести к простоям, особенно в нагруженных средах.
Удаление
Есть две опции удаления:
- удалить узел и получить новый взамен;
- удалить узел, уменьшая число узлов в
WorkerPool(узел взамен удалённого создан не будет).
Заметка
При удалении с уменьшением числа узлов удостоверьтесь, что сумма реплик WorkerPool целевого кластера после уменьшения будет всё ещё больше 3.
Удаление с помощью UI
Войдите в Web-интерфейс Боцмана и на главной странице выберите «Manage».

Выберите интересующий кластер и нажмите на его имя. Управление узлами для управляющего и подчинённого кластера идентично.

Для удаления узла и получения нового используйте опцию «Delete» в панели управления узлом.

Для удаления узла с уменьшением общего числа узлов.

Удаление с помощью изменения YAML-манифестов
Пример работы с объектами Kubernetes будет производиться с помощью kubectl, но вы можете использовать и другие способы.
Получите список всех узлов и найдите интересующий вас узел:
bash
kubectl get machine.cluster.x-k8s.ioИнтересующий узел далее будет указан как <mark>NODE_NAME</mark>.
Для удаления и создания нового узла взамен
bash
kubectl delete machine.cluster.x-k8s.io {++NODE_NAME++}Для удаления с уменьшением общего числа узлов.
Проставьте аннотацию для удаления. Этот шаг ещё не запустит удаление.
bash
kubectl annotate machine.cluster.x-k8s.io {++NODE_NAME++} cluster.x-k8s.io/delete-machine="true"Уменьшите число реплик в WorkerPool, к которому принадлежит <mark>NODE_NAME</mark>:
bash
kubectl patch workerpool.provisioning.bootsman.tech --type=merge -p="{\"spec\": {\"replicas\": {++NEW_REPLICA_COUNT++} }}" \
$(kubectl get machinedeployment.cluster.x-k8s.io -o jsonpath='{.metadata.labels.provisioning\.bootsman\.tech/workerpool}' \
$(kubectl get machine.cluster.x-k8s.io {++NODE_NAME++} -o jsonpath='{.metadata.labels.cluster\.x-k8s\.io/deployment-name}'))Где:
<mark>NEW_REPLICA_COUNT</mark>— уменьшенное на 1 число реплик.
Примечания и ограничения
Внимание!
Планировщик выбирает любой свободный ByoHost, поэтому метки, заданные агенту флагом --label, должны совпадать с селектором целевого WorkerPool. При несовпадении хост будет отфильтрован и воркер не добавится.
- Свободный хост должен пройти проверки
host-agent. Хост, не прошедший проверки, не будет выбран планировщиком. - Убедитесь, что на новой машине достаточно ресурсов под профиль воркера (CPU, RAM, диск).
- Если машина не в том же broadcast-домене, что и управляющий кластер, задайте при запуске агента
--registration-serverи--target-cluster. - Для замены вышедшей из строя машины сначала очистите вышедший из строя узел (см. Очистка ноды от компонентов k8s), затем добавьте новый воркер по описанному сценарию.
- Для очистки кластера от зарегистрированного агента см. Очистка кластера от зарегистрированного агента.