Установка KeyStack LCM в режиме высокой доступности¶
Данная инструкция описывает установку LCM (Lifecycle Manager) в режиме высокой доступности. В этом режиме LCM развёртывается на трёх Control-узлах, образующих Kubernetes-кластер на базе k0s. Такая архитектура обеспечивает отказоустойчивость самой системы управления жизненным циклом платформы.
Описание базовой установки LCM на одном узле приведено в разделе Установка KeyStack LCM.
Настройка компонента VMHA для обеспечения отказоустойчивости виртуальных машин описана в разделе VMHA — Высокая доступность ВМ.
Примечание
На текущий момент поддерживаются два варианта инсталлятора:
Новый инсталлятор k0s (описан в данной инструкции) — рекомендуется для новых установок
Классический инсталлятор — поддерживается для обеспечения совместимости с существующими установками
Оба варианта будут поддерживаться в переходный период. Выбор инсталлятора зависит от требований вашей инфраструктуры и планов миграции.
Требования к инфраструктуре¶
Аппаратные требования для HA LCM¶
Для развёртывания LCM в режиме высокой доступности предъявляются специальные требования к LCM-узлам:
Количество узлов: ровно 3 (для обеспечения кворума)
Оперативная память: минимум 32 ГБ на узел
Процессор: минимум 16 ядер x86-64/AMD64 на узел
Дисковая подсистема:
Системные диски: 2×500 ГБ SSD в конфигурации RAID 1 для операционной системы и системных компонентов
Диск для Ceph: минимум 1×500 ГБ SSD без RAID для распределённого хранилища Ceph
Предупреждение
Важно использовать отдельные физические диски для системы и Ceph. Размещение системы и Ceph на одном диске существенно снижает производительность и надёжность кластера.
Сетевые интерфейсы: 2×10 ГБ NIC для обеспечения резервирования сетевых подключений
Аппаратные требования для остальных узлов¶
Требования к остальным типам узлов платформы:
Требование / Тип узла |
Controller |
Compute |
Network |
Storage |
|---|---|---|---|---|
Обязательность |
Да |
Да |
Да |
Нет |
Минимальное количество узлов |
3 |
2 |
1 |
— |
Оперативная память |
256 ГБ |
— |
— |
— |
Процессор (ядер) |
2×8 |
2×12 |
2×8 |
— |
Архитектура процессора |
x86-64 / AMD64 |
x86-64 / AMD64 |
x86-64 / AMD64 |
— |
Место для хранения |
2×512 ГБ SSD (RAID 1) |
— |
— |
— |
Сетевая карта |
2×10 ГБ NIC |
2×10 ГБ NIC |
2× (2×10 ГБ NIC) |
— |
Программные требования¶
На всех узлах должна быть установлена ОС SberLinux 9.6.2.
Установщик запускается только от непривилегированного пользователя (не root). У пользователя должны быть права для выполнения команд sudo. Установщик не нужно запускать через sudo — он сам выполнит повышенные команды по мере необходимости.
Примечание
Установщик автоматически применяет необходимые настройки ядра ОС и устанавливает требуемые системные пакеты в процессе развёртывания. Все необходимые оптимизации и зависимости включены в дистрибутив и применяются на этапе выполнения installer.sh.
Сетевые требования¶
Для работы LCM требуется настроенная DNS-зона со следующими записями:
gitlab.<доменная зона>— для управления жизненным циклом платформы (CI),nexus.<доменная зона>— для хранения артефактов платформы,vault.<доменная зона>— для хранения паролей и сертификатов,netbox.<доменная зона>— для настроек Baremetal-узлов,minio.<доменная зона>— для работы GitLab,docker.<доменная зона>— для хранения контейнеров,grafana.<доменная зона>— для мониторинга платформы,k0s.<доменная зона>— для API Kubernetes.
Для всех перечисленных записей укажите в DNS один и тот же адрес, который должен совпадать со значением параметра ext_vip_address (VIP-адрес сетевого интерфейса data, обеспечивающего доступ к сервисам LCM и к сети регионов OpenStack), задаваемого на этапе установки инсталлятора.
Также для всех Baremetal-узлов инфраструктуры требуется создать DNS-записи вида <IP-адрес> <имя узла>-rmi.<доменная зона>.
Подготовительные шаги¶
Перед началом установки выполните следующие действия:
Настройка узлов¶
Убедитесь, что на всех узлах время в BIOS настроено в зоне UTC. На LCM-узлах под управлением ОС SberLinux выполните команду:
$ timedatectl set-local-rtc 0
Убедитесь, что у непривилегированного пользователя есть права
sudoна выполнение команд отroot.Убедитесь, что на всех узлах включена аппаратная виртуализация:
$ egrep '(vmx|svm)' /proc/cpuinfo
Вывод должен содержать параметр
vmxилиsvm. Если он отсутствует, включите аппаратную виртуализацию в настройках BIOS.Получите дистрибутив KeyStack одним из вариантов поставки.
Создайте SSH-ключ и разместите его на LCM-узлы, чтобы обеспечить беспарольный вход с первого узла на другие узлы. SSH-ключ размещается для пользователя, который будет указан в параметре
ssh_usernameфайлаlcm-config.yaml, конфигурация которого производится на этапе установки инсталлятора.Отключение фаервола и SELinux выполняется инсталлятором автоматически. Если отключение не выполнилось, то необходимо отключить фаервол и SELinux на всех LCM-узлах:
$ sudo systemctl disable firewalld Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service". Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service". $ sestatus SELinux status: disabled
Убедитесь, что на свободных дисках (особенно на дисках, предназначенных для Ceph) нет никакой информации, разделов и других данных. Диски должны быть полностью очищены.
Настройка сетевой связности¶
На LCM-узле проверьте сетевую связность:
Для всех Baremetal-узлов создайте пользователя с правами
administratorв IPMI-интерфейсе управления.
Установка инсталлятора¶
Установка выполняется на первом LCM-узле.
Подключитесь по SSH к первому LCM-узлу.
Скопируйте дистрибутив KeyStack на него любым удобным способом.
Распакуйте дистрибутив платформы:
$ tar -xf installer-k0s-ks2026.1-sberlinux-offline.tgz $ cd installer $ tar -xf mutiple-node-k0s-ks2026.1.tar.gz
Откройте файл конфигурации:
$ vi mutiple-node/lcm-config.yaml
Настройте параметры установки.
Предупреждение
Параметры, перечисленные ниже, необходимо задать корректно до запуска этапов установки order 1 и order 2. Способов устранить ошибку в значении любого из них без полного повторного развёртывания нет — в этом случае потребуется полная переустановка платформы с чистой установкой ОС на каждом узле (ручная очистка артефактов k0s и Ceph нецелесообразна).
Основные параметры:
ssh_username— имя непривилегированного пользователя, от которого выполняется установка.fqdn_cp1,fqdn_cp2,fqdn_cp3— DNS-имена LCM-узлов.domain_name— доменная зона для региона. В этой зоне должны быть зарегистрированы все сервисы LCM.mgt_vip_address— VIP-адрес управления Kubernetes (K0s).ext_vip_address— VIP-адрес доступа к сервисам LCM (GitLab, NetBox, Vault, Nexus). Должен быть зарегистрирован в DNS в зонеdomain_name.keepalived_passwd— пароль для keepalived (максимум 8 символов).ironic_enable— управление сервисом Ironic для работы с Baremetal-узлами. При первичной установке укажите"false". Ironic можно будет включить позже через настройки мониторинга после развёртывания основных компонентов.
Пример конфигурации:
ssh_username: "cloud-user" fqdn_cp1: "cp-1.testdomain.local" fqdn_cp2: "cp-2.testdomain.local" fqdn_cp3: "cp-3.testdomain.local" domain_name: "testdomain.local" mgt_vip_address: "172.16.130.10" ext_vip_address: "10.120.120.240" keepalived_passwd: "8LJw251u" ironic_enable: "false"
Остальные параметры (размеры томов, настройки мониторинга) можно оставить по умолчанию или настроить согласно требованиям.
Примечание
В файле
lcm-config.yamlдоступны дополнительные параметры для настройки мониторинга и сервиса Ironic:Мониторинг: параметры для настройки Grafana, Prometheus и алертинга можно найти в секции мониторинга файла конфигурации. По умолчанию включён базовый мониторинг компонентов LCM.
Ironic: после первичной установки платформы сервис Ironic можно активировать, изменив параметр
ironic_enableна"true"и выполнив обновление конфигурации. Ironic необходим для управления Baremetal-узлами через IPMI/Redfish.
Сохраните и закройте файл.
Запустите установку:
$ ./installer.sh mutiple-node/lcm-config.yaml
Скрипт установит необходимые пакеты в систему и выполнит настройку ОС. На этом этапе применяются все необходимые настройки ядра и устанавливаются системные зависимости.
Примечание
Изменение настроек SELinux требует перезагрузки узлов после выполнения данного шага.
Этап установки order 1¶
На первом этапе устанавливается Kubernetes-кластер и система хранения данных Ceph.
Для первичной установки или переустановки этапа выполните:
$ cd mutiple-node/ $ ./offline-bundle/installer.sh --order 1
Проверка успешного завершения¶
Проверьте состояние узлов кластера. Должны отобразиться три узла в статусе
Ready:$ kubectl get nodes NAME STATUS ROLES AGE VERSION <имя>-lcm-01.vm.lab.itkey.com Ready control-plane 7m14s v1.31.5+k0s <имя>-lcm-02.vm.lab.itkey.com Ready control-plane 6m41s v1.31.5+k0s <имя>-lcm-03.vm.lab.itkey.com Ready control-plane 6m41s v1.31.5+k0s
Примечание
Скорость сборки Ceph-кластера зависит от скорости дисков. В среднем сборка занимает несколько минут. Дождитесь появления необходимого статуса, прежде чем переходить к следующему шагу.
Проверьте состояние OSD-дисков Ceph. Должны отобразиться три пода в статусе
Running:$ kubectl get pod -l app.kubernetes.io/name=ceph-osd -n ceph-cluster NAME READY STATUS RESTARTS AGE rook-ceph-osd-0-6cb69b89b6-2n5fc 2/2 Running 0 60s rook-ceph-osd-1-cf7476bcf-vnlj6 2/2 Running 0 60s rook-ceph-osd-2-54884b7c48-2s746 2/2 Running 0 59s
Проверьте состояние кластера Ceph. Должен отобразиться кластер в фазе
Readyсо статусом здоровьяHEALTH_WARN:$ kubectl get -n ceph-cluster cephclusters.ceph.rook.io NAME DATADIRHOSTPATH MONCOUNT AGE PHASE MESSAGE HEALTH ceph-cluster /var/lib/rook 3 8m43s Ready Cluster created successfully HEALTH_WARN
Подключение к Active Directory¶
Для интеграции ролевой модели KeyStack с централизованным каталогом организации выполните настройку подключения к Active Directory или LDAP-серверу. Подробные сведения о ролевой модели и принципах её работы описаны в разделе Ролевая модель KeyStack.
Требования к LDAP-серверу¶
Для корректной работы интеграции требуется:
LDAP-сервер с поддержкой TLS (LDAPS).
Доступ к серверу исключительно по DNS-имени (для корректной проверки TLS-сертификатов).
Корневой сертификат центра сертификации в формате PEM.
Учётная запись для привязки (bind) с правами чтения каталога.
Настройка параметров¶
Откройте файл конфигурации:
$ vi mutiple-node/lcm-config.yaml
Настройте блок Active Directory:
# Active Directory ldap_enable: "true" ldap_host: "dc-01.domain.loc" ldap_ca_cert_file: "ldap-root-cert.crt" ldap_bind_dn: "CN=test,CN=Users,DC=domain,DC=loc" ldap_user_search_basedn: "CN=Users,DC=domain,DC=loc" ldap_group_search_basedn: "CN=Users,DC=domain,DC=loc" ldap_reader_group_dn: "CN=KeyStack-Readers,CN=Users,DC=domain,DC=loc" ldap_auditor_group_dn: "CN=KeyStack-Auditors,CN=Users,DC=domain,DC=loc" ldap_admin_group_dn: "CN=KeyStack-Admins,CN=Users,DC=domain,DC=loc"
Где:
ldap_enable— включение интеграции с LDAP ("true"или"false").ldap_host— FQDN-имя сервера Active Directory. В SAN сертификата должно быть указано это имя.ldap_ca_cert_file— имя файла с корневым сертификатом ЦА в формате PEM.ldap_bind_dn— DN учётной записи для привязки к LDAP.ldap_user_search_basedn— базовый DN для поиска пользователей.ldap_group_search_basedn— базовый DN для поиска групп.ldap_reader_group_dn,ldap_auditor_group_dn,ldap_admin_group_dn— DN групп AD, соответствующих ролям KeyStack.
Создайте файл с корневым сертификатом CA:
$ cat > mutiple-node/ca-cert.pem << EOF -----BEGIN CERTIFICATE----- <содержимое сертификата> -----END CERTIFICATE----- EOF
Сохраните корневой сертификат центра сертификации в формате PEM в файл с именем, указанным в параметре
ldap_ca_cert_file:$ vi mutiple-node/ldap-root-cert.crt
Вставьте содержимое сертификата и сохраните файл.
Создание секретов для NetBox¶
Создайте Kubernetes-секрет с паролем для учётной записи привязки к LDAP:
$ export config_file='charts-config.yaml' $ export netbox_namespace=$(yq '.charts[] | select(.name == "netbox") | .namespace' "$config_file") $ kubectl create namespace "${netbox_namespace}" $ kubectl create -n "${netbox_namespace}" secret generic netbox-ldap \ --from-literal=email_password='' \ --from-literal=secret_key=$(python3 -c "import secrets; print(secrets.token_urlsafe(50))") \ --from-literal=ldap_bind_password='<пароль учётной записи ldap bind dn>'
Создание секретов для GitLab¶
Создайте Kubernetes-секрет с паролем для учётной записи привязки к LDAP:
$ export config_file='charts-config.yaml' $ export gitlab_namespace=$(yq '.charts[] | select(.name == "gitlab") | .namespace' "$config_file") $ kubectl create namespace "${gitlab_namespace}" $ kubectl create -n "${gitlab_namespace}" secret generic gitlab-ldap \ --from-literal=ldap_bind_password='<пароль учётной записи ldap bind dn>'
Подробная информация о ролях KeyStack и их привилегиях описана в разделах Настройка интеграции с LDAP/AD и Описание ролевой модели.
Этап установки order 2¶
На втором этапе устанавливаются сервисы LCM: GitLab, NetBox, Nexus, Vault, мониторинг и другие компоненты.
Перед запуском команды убедитесь, что все поды из предыдущего этапа подняты и нет ошибок:
$ kubectl get pod -A
Запустите установку:
$ ./offline-bundle/installer.sh --order 2
Проверка успешного завершения¶
Проверьте список установленных Helm-чартов:
$ helm list -A
Должны отобразиться все компоненты LCM в статусе
deployed:cert-managercnpg-operatorgitlabingress-docsingress-gitlabingress-netboxingress-nexusingress-vaultingress-vmkskeystack-documentationkyvernokyverno-policiesmariadb-operatormariadb-operator-crdsmetallbnetboxnexus3redis-ha(для GitLab и NetBox)rook-cephrook-ceph-clustervaultvault-unsealervlcvmks
Проверьте состояние всех подов:
$ kubectl get all -A
Все поды должны быть в статусе
RunningилиCompleted.
Наполнение LCM данными¶
После успешной установки всех компонентов выполните наполнение LCM начальными данными:
$ bash upload.sh mutiple-node/charts-config.yaml
На каждый запуск скрипта создаётся лог-файл в формате upload_<дата>_<время>.log.
Обновление LCM¶
Для обновления LCM на новую версию выполните следующие действия:
Перед обновлением создайте резервную копию конфигурации кластера:
$ k0sctl backup
Эта операция может занять продолжительное время. Для тестовых окружений этот шаг можно пропустить.
Скопируйте дистрибутив KeyStack на него любым удобным способом.
Распакуйте дистрибутив платформы:
$ tar -xf installer-k0s-ks2026.1-sberlinux-offline.tgz $ cd installer $ tar -xf mutiple-node-k0s-ks2026.1.tar.gz
Скопируйте значения переменных из текущей инсталляции в новый файл конфигурации:
$ vi charts-config.yaml
Убедитесь, что все параметры (
domain_name,mgt_vip_address,ext_vip_address, настройки LDAP и другие) соответствуют текущей установке.Перед запуском команды обновления убедитесь, что все поды подняты и нет ошибок:
$ kubectl get pod -A
Запустите процесс обновления:
$ ./offline-bundle/installer.sh --upgrade
Резервное копирование LCM¶
Для хранения резервных копий LCM используется система Velero, которая сохраняет копии в объектном хранилище S3. Предполагается, что S3-совместимое хранилище предоставляется заказчиком.
Ниже описан процесс настройки резервного копирования на примере тестового развёртывания с использованием Minio.
Настройка Minio для тестирования¶
Для тестирования работы Velero можно развернуть Minio в Docker на отдельном узле.
Создайте файл
minio.ymlдля Docker Compose:services: minio: image: quay.io/minio/minio container_name: minio ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: minio MINIO_ROOT_PASSWORD: passw0rd volumes: - "${PWD}/data:/data" command: server /data --console-address ":9001"
Создайте директорию для данных:
$ mkdir data
Запустите контейнер с Minio:
$ docker compose -f minio.yml up -d
Откройте веб-интерфейс Minio по адресу
http://<IP-адрес>:9001и создайте бакет с именемlcm.
Настройка Velero¶
Создайте конфигурационный файл авторизации для доступа к Minio:
$ cat << EOF > ./credentials-velero [default] aws_access_key_id=minio aws_secret_access_key=passw0rd EOF
Установите Velero в Kubernetes:
$ velero install \ --features=EnableCSI \ --provider aws \ --plugins docker.io/velero/velero-plugin-for-aws:v1.12.1 \ --bucket lcm \ --secret-file ./credentials-velero \ --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://<IP-адрес>:9000
Где:
--plugins— образ плагина для работы с AWS S3 (указан вcustom-images-list.txt).--bucket— имя бакета для хранения резервных копий.--backup-location-config— параметры подключения к S3:region— регион S3 (можно посмотреть в GUI Minio).s3Url— URL API Minio.
Удалите файл с учётными данными:
$ rm -f ./credentials-velero
Настройки доступа хранятся в Kubernetes-секрете.
Проверьте установку Velero. Должен отобразиться под в статусе
Running:$ kubectl get pod -n velero NAME READY STATUS RESTARTS AGE velero-75b867769d-gxh5s 1/1 Running 0 4h29m
Создание резервной копии¶
Velero поддерживает различные варианты создания резервных копий: по расписанию, с ротацией, с выбором компонентов для включения в копию.
Создайте резервную копию компонента LCM GitLab:
$ velero backup create gitlab --include-namespaces lcm-gitlab
В случае успешного завершения вы увидите:
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR gitlab Completed 0 0 2025-02-11 14:40:54 +0000 UTC 29d default <none>
Для получения подробной информации о резервной копии выполните:
$ velero backup describe gitlab --details
Восстановление из резервной копии¶
В качестве примера удалите namespace компонента LCM GitLab:
$ kubectl delete namespaces lcm-gitlab
Примечание
Удаление namespace занимает продолжительное время. Дождитесь завершения операции перед переходом к следующему шагу.
Восстановите namespace из резервной копии:
$ velero restore create --from-backup gitlab
Должно отобразиться состояние:
NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR gitlab-20250211151000 gitlab Completed 2025-02-11 15:10:00 +0000 UTC 2025-02-11 15:12:21 +0000 UTC 0 6 2025-02-11 15:10:00 +0000 UTC <none>
Если восстановление завершилось с ошибками, изучите логи пода Velero:
$ kubectl logs -n velero <имя пода velero>
Для получения имени пода выполните команду:
$ kubectl get pod -n velero
Восстановление отказавшего LCM-узла¶
В данном разделе описан порядок действий при отказе одного из трёх LCM-узлов кластера k0s. Кластер спроектирован так, чтобы сохранять работоспособность при потере одного узла, однако для полного восстановления требуется вмешательство администратора.
Примечание
Описанные ниже процедуры применимы только к сценарию отказа одного LCM-узла. При одновременном отказе двух или трёх узлов кворум etcd будет потерян, и кластер станет недоступен. В этом случае восстановите кластер из резервной копии Velero или k0sctl.
Автоматическое поведение кластера при отказе узла¶
При отказе одного из трёх LCM-узлов кластер автоматически выполняет следующие действия:
Keepalived — VIP-адрес управления (
mgt_vip_address) мигрирует на один из оставшихся узлов. Доступ к API Kubernetes сохраняется.Управляющий контур — etcd сохраняет кворум (2 из 3 членов). Управляющий контур продолжает обслуживать запросы.
Перепланирование подов — Kubernetes автоматически перемещает поды на оставшиеся узлы:
Поды с меткой
node.kubernetes.io/unreachableвытесняются через 30 секунд.Поды с меткой
node.kubernetes.io/not-readyвытесняются через 5 минут.
CronJob для StatefulSet — каждые 2 минуты выполняется автоматическая очистка подов Nexus3 и Gitaly, находящихся в состоянии
Terminating. Это необходимо для подов с томами типа ReadWriteOnce, которые не могут быть принудительно удалены стандартным механизмом Kubernetes.Базы данных (CNPG) — кластеры PostgreSQL для GitLab, NetBox и Grafana продолжают работу на оставшихся 2 из 3 реплик.
Vault (Raft) — сохраняет кворум (2 из 3 членов). Операции чтения и записи секретов продолжают работать.
Ceph — помечает OSD отказавшего узла как
down. Кластер продолжает работу в деградированном состоянии с 2 из 3 OSD. Данные остаются доступными.
Восстановление узла после перезагрузки¶
Если отказавший узел восстановился (например, после перезагрузки), выполните проверку его возвращения в кластер.
Убедитесь, что узел вернулся в кластер и находится в статусе
Ready:$ kubectl get nodes
Все три узла должны отображаться в статусе
Ready.Проверьте, что поды успешно распределились по узлам:
$ kubectl get pod -A -o wide
Убедитесь, что нет подов в статусе
Pending,ErrorилиCrashLoopBackOff.Проверьте состояние кластера Ceph:
$ kubectl get -n ceph-cluster cephclusters.ceph.rook.io
Дождитесь перехода кластера в состояние
HEALTH_OK. Процесс восстановления данных Ceph может занять продолжительное время в зависимости от объёма данных.Убедитесь, что все три OSD-диска Ceph запущены:
$ kubectl get pod -l app.kubernetes.io/name=ceph-osd -n ceph-cluster
Все три пода должны быть в статусе
Runningс индикатором2/2в столбцеREADY.Проверьте состав кластера etcd:
$ kubectl exec -n kube-system <etcd-pod> -- etcdctl member list
В списке должны отображаться все 3 члена кластера.
Проверьте состояние кластеров PostgreSQL (CNPG):
$ kubectl get clusters.postgresql.cnpg.io -A
Все кластеры должны отображать полное количество реплик (3/3) в столбце
READY.Проверьте состояние кластера Vault:
$ kubectl exec -n lcm-vault vault-0 -- vault status
Убедитесь, что значение
Sealedравноfalse. Повторите команду дляvault-1иvault-2. Если установлен vault-unsealer, разблокировка Vault происходит автоматически в течение 2 минут. В противном случае выполните действия, приведённые в разделе Восстановление Vault.Проверьте состояние Redis HA:
$ kubectl get pod -l app=redis-ha -A
Все поды Redis должны быть в статусе
Running. Если все поды находятся в ролиslave(ошибка Sentinelno-good-slave), выполните ручное повышение — см. Восстановление Redis HA.
Замена неисправного LCM-узла¶
Если отказавший узел не подлежит восстановлению и требуется его замена (переустановка ОС), выполните действия, приведённые ниже.
Для выполнения процедуры восстановления необходимы файлы инсталлятора и конфигурация кластера. Все перечисленные файлы размещаются на узле, с которого запускается инсталлятор (seed-узел).
Важно
Если отказавший узел являлся seed-узлом (узлом, с которого запускался инсталлятор), необходимо восстановить рабочую директорию инсталлятора на одном из оставшихся узлов.
Необходимые компоненты:
Дистрибутив инсталлятора — архив
mutiple-node-k0s-<версия>.tar.gz. Загрузите из репозитория артефактов и распакуйте на один из оставшихся узлов. Архив содержит шаблоны, бинарные файлы (k0sctl,k0s,helm,kubectl,yq), Helm-чарты и образы контейнеров (bundle_file.tar).Файл конфигурации
lcm-config.yaml— содержит параметры, специфичные для кластера (FQDN узлов, VIP, домен, пароли). Файл входит в дистрибутив со значениями по умолчанию, которые необходимо адаптировать под конкретный кластер перед запуском инсталлятора.Предупреждение
lcm-config.yamlявляется единственным источником конфигурации кластера. При замене seed-узла убедитесь, что используется файл с корректными значениями для данного кластера (FQDN, VIP, домен). Рекомендуется хранить отредактированный файл в системе контроля версий или создавать резервную копию.При утере файла его можно восстановить из данных работающего кластера. Выполните следующие команды с любого узла, имеющего доступ к
kubectl:FQDN узлов и
ssh_username:$ kubectl get nodes -o wide $ sudo cat /var/lib/k0s/pki/admin.conf
Если
kubectlнедоступен, скопируйте/var/lib/k0s/pki/admin.confкак~/.kube/config.VIP и
keepalived_passwd— из конфигурации k0s:$ sudo cat /etc/k0s/k0s.yaml | grep -A5 keepalived
domain_name— из любого Ingress:$ kubectl get ingress -A
loadbalancer_ip_rangeи IP-адреса сервисов — из MetalLB:$ kubectl get ipaddresspools.metallb.io -n metallb-system -o yaml
Размеры PV:
$ kubectl get pvc -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,SIZE:.spec.resources.requests.storage'
Флаги установки (vault, ironic, csi и др.) — по наличию namespace/release:
$ helm list -A
Параметры LDAP, Syslog, OpenSearch — из values установленных чартов:
$ helm get values gitlab -n lcm-gitlab $ helm get values vlc -n lcm-logging
SSH-ключ (
~/.ssh/id_rsa) — для беспарольного доступа ко всем узлам кластера. Должен присутствовать на seed-узле.Конфигурация kubectl (
~/.kube/config) — если утеряна, может быть восстановлена командойk0sctl kubeconfigс использованием файлаk0sctl.yaml, либо скопирована из файла/var/lib/k0s/pki/admin.confс любого работающего контроллера.
Файлы k0sctl.yaml и charts-config.yaml не нужно восстанавливать вручную — они автоматически генерируются инсталлятором из шаблонов и lcm-config.yaml.
Подготовка нового узла¶
Подготовьте новый узел в соответствии с требованиями, описанными в данном разделе ранее:
Установите ОС SberLinux.
Настройте непривилегированного пользователя с правами
sudo.Разместите SSH-ключ для беспарольного доступа с seed-узла.
Отключите фаервол и SELinux.
Настройте синхронизацию времени.
Очистите диски, предназначенные для Ceph. После переустановки ОС диск может содержать файловую систему (например, ephemeral), которую необходимо удалить:
$ sudo wipefs -a /dev/<диск_для_ceph> $ sudo sgdisk --zap-all /dev/<диск_для_ceph>
Обновите SSH-ключи хоста. После переустановки ОС-узел получает новые SSH-ключи, что приводит к ошибке верификации при подключении. Удалите старые ключи и добавьте новые на узле, с которого будет выполняться инсталлятор:
$ ssh-keygen -R <FQDN_нового_узла> $ ssh-keygen -R <IP_нового_узла> $ ssh-keyscan -H <FQDN_нового_узла> >> ~/.ssh/known_hosts $ ssh-keyscan -H <IP_нового_узла> >> ~/.ssh/known_hosts
Важно
Необходимо добавить ключи как по FQDN, так и по IP-адресу.
k0sctlможет подключаться по обоим адресам, и отсутствие любого из них приведёт к ошибкеhost key verification failed. Инсталлятор используетStrictHostKeyChecking=noдля своих SSH-соединений, но вызываемый имk0sctlпроверяетknown_hosts.Убедитесь, что SSH-подключение работает:
$ ssh <пользователь>@<FQDN_нового_узла> hostname
Обновите DNS-запись, чтобы имя отказавшего узла указывало на IP-адрес нового узла, либо измените параметр
fqdn_cpNв файлеlcm-config.yaml.
Удаление отказавшего узла¶
При наличии доступа к отказавшему узлу выполните:
$ ssh <отказавший узел> $ sudo k0s stop $ sudo k0s reset
Затем удалите узел из кластера Kubernetes и из etcd:
$ kubectl delete node <имя отказавшего узла> $ sudo k0s etcd leave --peer-address <IP_отказавшего_узла>
Важно
Команда
k0s etcd leaveобязательна. Без неёk0sctl applyзавершится с ошибкой: «controller is listed as an existing etcd member but k0s is not found installed on it».
Если доступа к отказавшему узлу нет (переустановка ОС, аппаратный сбой), выполните удаление из кластера Kubernetes и etcd с любого работающего контроллера.
Добавление нового узла¶
Для добавления нового узла рекомендуется использовать инсталлятор. Инсталлятор автоматически генерирует k0sctl.yaml из шаблона и lcm-config.yaml, устанавливает необходимые инструменты и выполняет k0sctl apply.
Из рабочей директории инсталлятора (mutiple-node/) выполните:
$ ./installer.sh --order 1
Инсталлятор выполнит следующие действия:
Установит инструменты (
k0sctl,kubectl,helm,yq,velero) в/usr/bin/.Проведёт предварительные проверки (SSH-доступ, firewall, resolv.conf).
Сгенерирует
k0sctl.yamlиз шаблонаtemplates/k0sctl.j2иlcm-config.yaml.Выполнит
k0sctl apply --config k0sctl.yaml --timeout 15m.Получит kubeconfig и настроит VIP.
Дождётся готовности всех узлов.
Переустановит Helm-чарты первого этапа (MetalLB, Rook-Ceph, CNPG, cert-manager и др.).
Если требуется только добавить узел без переустановки Helm-чартов, можно сгенерировать k0sctl.yaml и выполнить k0sctl apply вручную:
$ jinja -D bundle_images_file "bundle_file.tar" -d lcm-config.yaml templates/k0sctl.j2 > k0sctl.yaml
$ k0sctl apply --config k0sctl.yaml --timeout 15m
Предупреждение
k0sctl apply выполняет последовательную переустановку (reinstall) всех контроллеров кластера, а не только нового узла. Это приводит к кратковременному перезапуску сервиса k0s на существующих узлах. Процесс может занять 3–5 минут. В этот период kubelet на существующих узлах перезапускается, что вызывает кратковременную недоступность подов.
Дождитесь появления нового узла в кластере:
$ kubectl get nodes
Новый узел должен появиться в статусе Ready. Это может занять 2–3 минуты после завершения k0sctl apply.
Восстановление kubelet на существующих узлах¶
После переустановки контроллеров через k0sctl apply на существующих узлах kubelet может не запуститься из-за устаревших процессов и точек монтирования. Если kubelet не запускается в течение 5 минут (узел остаётся в статусе NotReady), выполните следующую процедуру на каждом проблемном узле:
Остановите k0s:
$ sudo k0s stop
Завершите устаревшие процессы контейнерной среды выполнения:
$ sudo pkill -9 containerd-shim
Отключите оставшиеся точки монтирования контейнеров, которые не были сняты после завершения процессов containerd-shim:
$ mount | grep '/run/k0s/containerd' | awk '{print $3}' | while read m; do sudo umount "$m"; done
Запустите k0s:
$ sudo k0s start
Дождитесь запуска kubelet. Процесс инициализации включает согласование конфигурации worker-узла и запуск Node Local Load Balancer (NLLB/EnvoyProxy). Kubelet начинает полноценную работу через 2–3 минуты после старта k0s:
$ sudo k0s status $ kubectl get nodes
Убедитесь, что все узлы находятся в статусе
Ready.
Восстановление Ceph¶
После замены узла старый OSD перейдёт в состояние CrashLoopBackOff, так как данные на диске были утеряны. Оператор Ceph для Kubernetes (Rook) не создаёт новый OSD автоматически — необходимо удалить старый OSD из кластера, очистить диск и перезапустить оператор.
Примечание
Если очистка диска (wipefs, sgdisk) была выполнена на этапе подготовки узла, после удаления старого OSD достаточно перезапустить оператор — Rook автоматически обнаружит чистый диск и создаст новый OSD.
Проверьте состояние OSD:
$ kubectl get pod -l app.kubernetes.io/name=ceph-osd -n ceph-cluster -o wide
Если старый OSD находится в статусе
CrashLoopBackOff, удалите его из кластера Ceph. Выполните команды из подаrook-ceph-tools:$ kubectl exec -n ceph-cluster deploy/rook-ceph-tools -- ceph osd out <ID_старого_OSD> $ kubectl exec -n ceph-cluster deploy/rook-ceph-tools -- ceph osd crush remove osd.<ID_старого_OSD> $ kubectl exec -n ceph-cluster deploy/rook-ceph-tools -- ceph auth del osd.<ID_старого_OSD> $ kubectl exec -n ceph-cluster deploy/rook-ceph-tools -- ceph osd rm <ID_старого_OSD>
Удалите Deployment старого OSD:
$ kubectl delete deploy rook-ceph-osd-<ID_старого_OSD> -n ceph-cluster
Если диск не был очищен на этапе подготовки узла, выполните очистку сейчас (на замещённом узле):
$ sudo wipefs -a /dev/<диск_для_ceph> $ sudo sgdisk --zap-all /dev/<диск_для_ceph>
Перезапустите оператор Rook для обнаружения чистого диска:
$ kubectl rollout restart deploy rook-ceph-operator -n rook-ceph
Дождитесь создания нового OSD и начала восстановления данных:
$ kubectl exec -n ceph-cluster deploy/rook-ceph-tools -- ceph status
Rook создаст новый OSD на подготовленном диске. Кластер перейдёт в состояние
HEALTH_WARNс сообщением о backfill/recovery. Дождитесь завершения восстановления данных и перехода вHEALTH_OK. Время восстановления зависит от объёма данных.
Восстановление Redis HA¶
Кластеры Redis HA (используемые в NetBox и других сервисах) в большинстве случаев восстанавливаются автоматически: Sentinel выполняет failover и назначает нового master из оставшихся подов. После добавления узла в кластер третий под Redis запускается и подключается как slave.
Примечание
Инсталлятор (installer.sh) при запуске с --no-reinstall-k0s также устанавливает Helm-чарты, которые проверяют и корректируют конфигурацию Redis HA.
Если автоматическое восстановление не произошло (все поды отображают role:slave, а master недоступен), выполните ручное повышение:
Проверьте роли Redis:
$ kubectl exec -n <namespace> <redis-ha-server-pod> -- redis-cli info replication
Выберите один из работающих Redis-подов и повысьте его до master:
$ kubectl exec -n <namespace> <redis-ha-server-pod> -- redis-cli SLAVEOF NO ONE
После повышения Sentinel автоматически обнаружит нового master и перенастроит оставшиеся поды.
Восстановление Vault¶
После перезапуска контроллеров поды Vault могут оказаться в заблокированном (sealed) состоянии.
Проверьте состояние каждого пода Vault:
$ kubectl exec -n lcm-vault vault-0 -- vault status $ kubectl exec -n lcm-vault vault-1 -- vault status $ kubectl exec -n lcm-vault vault-2 -- vault status
Если установлен vault-unsealer, дождитесь автоматической разблокировки (до 2 минут). Если vault-unsealer не установлен, выполните разблокировку вручную:
$ kubectl exec -n lcm-vault <vault-pod> -- vault operator unseal <unseal_key>
Повторите для каждого заблокированного пода.
Финальная проверка¶
Выполните полную проверку по шагам из раздела Восстановление узла после перезагрузки.