Основные функции

Управление узлами осуществляется с помощью модуля node-manager, основные функции которого:

  1. Управление несколькими узлами как связанной группой (NodeGroup):
    • Возможность определить метаданные, которые наследуются всеми узлами группы.
    • Мониторинг группы узлов как единой сущности (группировка узлов на графиках по группам, группировка алертов о недоступности узлов, алерты о недоступности N узлов или N% узлов группы).
  2. Систематическое прерывание работы узлов — Chaos Monkey. Предназначено для верификации отказоустойчивости элементов кластера и запущенных приложений.
  3. Установка/обновление и настройка ПО узла (containerd, kubelet и др.), подключение узла в кластер:
    • Установка операционной системы (смотри список поддерживаемых ОС) вне зависимости от типа используемой инфраструктуры (в любом облаке или на любом железе).
    • Базовая настройка операционной системы (отключение автообновления, установка необходимых пакетов, настройка параметров журналирования и т. д.).
    • Настройка nginx (и системы автоматического обновления перечня upstream’ов) для балансировки запросов от узла (kubelet) по API-серверам.
    • Установка и настройка CRI containerd и Kubernetes, включение узла в кластер.
    • Управление обновлениями узлов и их простоем (disruptions):
      • Автоматическое определение допустимой минорной версии Kubernetes группы узлов на основании ее настроек (указанной для группы kubernetesVersion), версии по умолчанию для всего кластера и текущей действительной версии control plane (не допускается обновление узлов в опережение обновления control plane).
      • Из группы одновременно производится обновление только одного узла и только если все узлы группы доступны.
      • Два варианта обновлений узлов:
        • обычные — всегда происходят автоматически;
        • требующие disruption (например, обновление ядра, смена версии containerd, значительная смена версии kubelet и пр.) — можно выбрать ручной или автоматический режим. В случае, если разрешены автоматические disruptive-обновления, перед обновлением производится drain узла (можно отключить).
    • Мониторинг состояния и прогресса обновления.
  4. Масштабирование кластера.
    • Автоматическое масштабирование.

      Доступно при использовании поддерживаемых облачных провайдеров (подробнее) и недоступно для статических узлов. Облачный провайдер в автоматическом режиме может создавать или удалять виртуальные машины, подключать их к кластеру или отключать.

    • Поддержание желаемого количества узлов в группе.

      Доступно как для облачных провайдеров, так и для статических узлов (при использовании Cluster API Provider Static).

  5. Управление Linux-пользователями на узлах.

Управление узлами осуществляется через управление группой узлов (ресурс NodeGroup), где каждая такая группа выполняет определенные для нее задачи. Примеры групп узлов по выполняемым задачам:

  • группы master-узлов;
  • группа узлов маршрутизации HTTP(S)-трафика (front-узлы);
  • группа узлов мониторинга;
  • группа узлов приложений (worker-узлы) и т. п.

Узлы в группе имеют общие параметры и настраиваются автоматически в соответствии с параметрами группы. Deckhouse масштабирует группы, добавляя, исключая и обновляя ее узлы. Допускается иметь в одной группе как облачные, так и статические узлы (серверы bare metal, виртуальные машины). Это позволяет получать узлы на физических серверах, которые могут масштабироваться за счет облачных узлов (гибридные кластеры).

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

Работа со статическими узлами (например, серверами bare metal) выполняется с помощью в провайдера CAPS (Cluster API Provider Static).

Поддерживается работа со следующими сервисами Managed Kubernetes (может быть доступен не весь функционал сервиса):

  • Google Kubernetes Engine (GKE);
  • Elastic Kubernetes Service (EKS).

Типы узлов

Типы узлов, с которыми возможна работа в рамках группы узлов (ресурс NodeGroup):

  • CloudEphemeral — такие узлы автоматически заказываются, создаются и удаляются в настроенном облачном провайдере.
  • CloudPermanent — отличаются тем, что их конфигурация берется не из custom resource nodeGroup, а из специального ресурса <PROVIDER>ClusterConfiguration (например, AWSClusterConfiguration для AWS). Также важное отличие узлов в том, что для применения их конфигурации необходимо выполнить dhctl converge (запустив инсталлятор Deckhouse). Примером CloudPermanent-узла облачного кластера является master-узел кластера.
  • CloudStatic — узел, созданный вручную (статический узел), размещенный в том же облаке, с которым настроена интеграция у одного из облачных провайдеров. На таком узле работает CSI и такой узел управляется cloud-controller-manager'ом. Объект Node кластера обогащается информацией о зоне и регионе, в котором работает узел. Также при удалении узла из облака соответствующий ему Node-объект будет удален в кластере.
  • Static — статический узел, размещенный на сервере bare metal или виртуальной машине. В случае облака, такой узел не управляется cloud-controller-manager'ом, даже если включен один из облачных провайдеров. Подробнее про работу со статическими узлами…

Группировка узлов и управление группами

Группировка и управление узлами как связанной группой означает, что все узлы группы будут иметь одинаковые метаданные, взятые из custom resource’а NodeGroup.

Для групп узлов доступен мониторинг:

  • с группировкой параметров узлов на графиках группы;
  • с группировкой алертов о недоступности узлов;
  • с алертами о недоступности N узлов или N% узлов группы и т. п.

Автоматическое развертывание, настройка и обновление узлов Kubernetes

Автоматическое развертывание (в static/hybrid — частично), настройка и дальнейшее обновление ПО работают на любых кластерах, независимо от его размещения в облаке или на bare metal.

Развертывание узлов Kubernetes

Deckhouse автоматически разворачивает узлы кластера, выполняя следующие идемпотентные операции:

  • Настройку и оптимизацию операционной системы для работы с containerd и Kubernetes:
    • устанавливаются требуемые пакеты из репозиториев дистрибутива;
    • настраиваются параметры работы ядра, параметры журналирования, ротация журналов и другие параметры системы.
  • Установку требуемых версий containerd и kubelet, включение узла в кластер Kubernetes.
  • Настройку Nginx и обновление списка upstream для балансировки запросов от узла к Kubernetes API.

Поддержка актуального состояния узлов

Для поддержания узлов кластера в актуальном состоянии могут применяться два типа обновлений:

  • Обычные. Такие обновления всегда применяются автоматически, и не приводят к остановке или перезагрузке узла.
  • Требующие прерывания (disruption). Пример таких обновлений — обновление версии ядра или containerd, значительная смена версии kubelet и т. д. Для этого типа обновлений можно выбрать ручной или автоматический режим (секция параметров disruptions). В автоматическом режиме перед обновлением выполняется корректная приостановка работы узла (drain) и только после этого производится обновление.

В один момент времени производится обновление только одного узла из группы и только в том случае, когда все узлы группы доступны.

Модуль node-manager имеет набор встроенных метрик мониторинга, которые позволяют контролировать прогресс обновления, получать уведомления о возникающих во время обновления проблемах или о необходимости получения разрешения на обновление (ручное подтверждение обновления).

Работа с узлами в поддерживаемых облаках

У каждого поддерживаемого облачного провайдера существует возможность автоматического заказа узлов. Для этого необходимо указать требуемые параметры для каждого узла или группы узлов.

В зависимости от провайдера этими параметрами могут быть:

  • тип узлов или количество ядер процессора и объем оперативной памяти;
  • размер диска;
  • настройки безопасности;
  • подключаемые сети и др.

Создание, запуск и подключение виртуальных машин к кластеру выполняются автоматически.

Масштабирование узлов в облаке

Возможны два режима масштабирования узлов в группе:

  • Автоматическое масштабирование.

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

    Чтобы включить автоматическое масштабирование узлов, необходимо указать разные ненулевые значения минимального и максимального количества узлов в группе.

  • Фиксированное количество узлов.

    В этом случае Deckhouse будет поддерживать указанное количество узлов (например, заказывая новые в случае выхода из строя старых узлов).

    Чтобы указать фиксированное количество узлов в группе и отключить автоматическое масштабирование, необходимо указать одинаковые значения параметров minPerZone и maxPerZone.

Работа со статическими узлами

При работе со статическими узлами функции модуля node-manager выполняются со следующими ограничениями:

  • Отсутствует заказ узлов. Непосредственное выделение ресурсов (серверов bare metal, виртуальных машин, связанных ресурсов) выполняется вручную. Дальнейшая настройка ресурсов (подключение узла к кластеру, настройка мониторинга и т.п.) выполняются полностью автоматически (аналогично узлам в облаке) или частично.
  • Отсутствует автоматическое масштабирование узлов. Доступно поддержание в группе указанного количества узлов при использовании Cluster API Provider Static (параметр staticInstances.count). Т.е. Deckhouse будет пытаться поддерживать указанное количество узлов в группе, очищая лишние узлы и настраивая новые при необходимости (выбирая их из ресурсов StaticInstance, находящихся в состоянии Pending).

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

  • Вручную, с помощью подготовленных скриптов.

    Для настройки сервера (ВМ) и ввода узла в кластер нужно загрузить и выполнить специальный bootstrap-скрипт. Такой скрипт генерируется для каждой группы статических узлов (каждого ресурса NodeGroup). Он находится в секрете d8-cloud-instance-manager/manual-bootstrap-for-<ИМЯ-NODEGROUP>. Пример добавления статического узла в кластер можно найти в FAQ.

    Для отключения узла кластера и очистки сервера (виртуальной машины) нужно выполнить скрипт /var/lib/bashible/cleanup_static_node.sh, который уже находится на каждом статическом узле. Пример отключения узла кластера и очистки сервера можно найти в FAQ.

  • Автоматически, с помощью Cluster API Provider Static.

    Cluster API Provider Static (CAPS) подключается к серверу (ВМ) используя ресурсы StaticInstance и SSHCredentials, выполняет настройку, и вводит узел в кластер.

    При необходимости (например, если удален соответствующий серверу ресурс StaticInstance или уменьшено количество узлов группы), Cluster API Provider Static подключается к узлу кластера, очищает его и отключает от кластера.

  • Вручную с последующей передачей узла под автоматическое управление Cluster API Provider Static.

    Функциональность доступна начиная с версии Deckhouse 1.63.

    Для передачи существующего узла кластера под управление CAPS необходимо подготовить для этого узла ресурсы StaticInstance и SSHCredentials, как при автоматическом управлении в пункте выше, однако ресурс StaticInstance должен дополнительно быть помечен аннотацией static.node.deckhouse.io/skip-bootstrap-phase: "".

Cluster API Provider Static

Cluster API Provider Static (CAPS), это реализация провайдера декларативного управления статическими узлами (серверами bare metal или виртуальными машинами) для проекта Cluster API Kubernetes. По сути, CAPS это дополнительный слой абстракции к уже существующему функционалу Deckhouse по автоматической настройке и очистке статических узлов с помощью скриптов, генерируемых для каждой группы узлов (см. раздел Работа со статическими узлами).

CAPS выполняет следующие функции:

  • настройка сервера bare metal (или виртуальной машины) для подключения к кластеру Kubernetes;
  • подключение узла в кластер Kubernetes;
  • отключение узла от кластера Kubernetes;
  • очистка сервера bare metal (или виртуальной машины) после отключения узла из кластера Kubernetes.

CAPS использует следующие ресурсы (CustomResource) при работе:

  • StaticInstance. Каждый ресурс StaticInstance описывает конкретный хост (сервер, ВМ), который управляется с помощью CAPS.
  • SSHCredentials. Содержит данные SSH, необходимые для подключения к хосту (SSHCredentials указывается в параметре credentialsRef ресурса StaticInstance).
  • NodeGroup. Секция параметров staticInstances определяет необходимое количество узлов в группе и фильтр множества ресурсов StaticInstance которые могут использоваться в группе.

CAPS включается автоматически, если в NodeGroup заполнена секция параметров staticInstances. Если в NodeGroup секция параметров staticInstances не заполнена, то настройка и очистка узлов для работы в этой группе выполняется вручную (см. примеры добавления статического узла в кластер и очистки узла), а не с помощью CAPS.

Схема работы со статичными узлами при использовании Cluster API Provider Static (CAPS) (практический пример добавления узла):

  1. Подготовка ресурсов.

    Перед тем, как отдать сервер bare metal или виртуальную машину под управление CAPS, может быть необходима предварительная подготовка, например:

    • Подготовка системы хранения, добавление точек монтирования и т. п.;
    • Установка специфических пакетов ОС. Например, установка пакета ceph-common, если на сервере используется тома CEPH;
    • Настройка необходимой сетевой связанности. Например, между сервером и узлами кластера;
    • Настройка доступа по SSH на сервер, создание пользователя для управления с root-доступом через sudo. Хорошей практикой является создание отдельного пользователя и уникальных ключей для каждого сервера.
  2. Создание ресурса SSHCredentials.

    В ресурсе SSHCredentials указываются параметры, необходимые CAPS для подключения к серверу по SSH. Один ресурс SSHCredentials может использоваться для подключения к нескольким серверам, но хорошей практикой является создание уникальных пользователей и ключей доступа для подключения к каждому серверу. В этом случае ресурс SSHCredentials также будет отдельный на каждый сервер.

  3. Создание ресурса StaticInstance.

    На каждый сервер (ВМ) в кластере создается отдельный ресурс StaticInstance. В нем указан IP-адрес для подключения и ссылка на ресурс SSHCredentials, данные которого нужно использовать при подключении.

    Возможные состояния StaticInstances и связанных с ним серверов (ВМ) и узлов кластера:

    • Pending. Сервер не настроен, и в кластере нет соответствующего узла.
    • Bootstraping. Выполняется процедура настройки сервера (ВМ) и подключения узла в кластер.
    • Running. Сервер настроен, и в кластер добавлен соответствующий узел.
    • Cleaning. Выполняется процедура очистки сервера и отключение узла из кластера.

    Можно отдать существующий узел кластера, заранее введенный в кластер вручную, под управление CAPS, пометив его StaticInstance аннотацией static.node.deckhouse.io/skip-bootstrap-phase: "".

  4. Создание ресурса NodeGroup.

    В контексте CAPS в ресурсе NodeGroup нужно обратить внимание на параметр nodeType (должен быть Static) и секцию параметров staticInstances.

    Секция параметров staticInstances.labelSelector определяет фильтр, по которому CAPS выбирает ресурсы StaticInstance, которые нужно использовать в группе. Фильтр позволяет использовать для разных групп узлов только определенные StaticInstance, а также позволяет использовать один StaticInstance в разных группах узлов. Фильтр можно не определять, чтобы использовать в группе узлов любой доступный StaticInstance.

    Параметр staticInstances.count определяет желаемое количество узлов в группе. При изменении параметра, CAPS начинает добавлять или удалять необходимое количество узлов, запуская этот процесс параллельно.

В соответствии с данными секции параметров staticInstances, CAPS будет пытаться поддерживать указанное (параметр count) количество узлов в группе. При необходимости добавить узел в группу, CAPS выбирает соответствующий фильтру ресурс StaticInstance находящийся в статусе Pending, настраивает сервер (ВМ) и добавляет узел в кластер. При необходимости удалить узел из группы, CAPS выбирает StaticInstance находящийся в статусе Running, очищает сервер (ВМ) и удаляет узел из кластера (после чего, соответствующий StaticInstance переходит в состояние Pending и снова может быть использован).

Пользовательские настройки на узлах

Для автоматизации действий на узлах группы предусмотрен ресурс NodeGroupConfiguration. Ресурс позволяет выполнять на узлах bash-скрипты, в которых можно пользоваться набором команд bashbooster, а также позволяет использовать шаблонизатор Go Template. Это удобно для автоматизации таких операций, как:

Ресурс NodeGroupConfiguration позволяет указывать приоритет выполняемым скриптам, ограничивать их выполнение определенными группами узлов и типами ОС.

Код скрипта указывается в параметре content ресурса. При создании скрипта на узле содержимое параметра content проходит через шаблонизатор Go Template, который позволят встроить дополнительный уровень логики при генерации скрипта. При прохождении через шаблонизатор становится доступным контекст с набором динамических переменных.

Переменные, которые доступны для использования в шаблонизаторе:

  • .cloudProvider (для групп узлов с nodeType CloudEphemeral или CloudPermanent) — массив данных облачного провайдера.

    Пример данных...

    cloudProvider:
      instanceClassKind: OpenStackInstanceClass
      machineClassKind: OpenStackMachineClass
      openstack:
        connection:
          authURL: https://cloud.provider.com/v3/
          domainName: Default
          password: p@ssw0rd
          region: region2
          tenantName: mytenantname
          username: mytenantusername
        externalNetworkNames:
        - public
        instances:
          imageName: ubuntu-22-04-cloud-amd64
          mainNetwork: kube
          securityGroups:
          - kube
          sshKeyPairName: kube
        internalNetworkNames:
        - kube
        podNetworkMode: DirectRoutingWithPortSecurityEnabled
      region: region2
      type: openstack
      zones:
      - nova
    
  • .cri — используемый CRI (с версии Deckhouse 1.49 используется только Containerd).
  • .kubernetesVersion — используемая версия Kubernetes.
  • .nodeUsers — массив данных о пользователях узла, добавленных через ресурс NodeUser.

    Пример данных...

    nodeUsers:
    - name: user1
      spec:
        isSudoer: true
        nodeGroups:
        - '*'
        passwordHash: PASSWORD_HASH
        sshPublicKey: SSH_PUBLIC_KEY
        uid: 1050
    
  • .nodeGroup — массив данных группы узлов.

    Пример данных...

    nodeGroup:
      cri:
        type: Containerd
      disruptions:
        approvalMode: Automatic
      kubelet:
        containerLogMaxFiles: 4
        containerLogMaxSize: 50Mi
        resourceReservation:
          mode: "Off"
      kubernetesVersion: "1.27"
      manualRolloutID: ""
      name: master
      nodeTemplate:
        labels:
          node-role.kubernetes.io/control-plane: ""
          node-role.kubernetes.io/master: ""
        taints:
        - effect: NoSchedule
          key: node-role.kubernetes.io/master
      nodeType: CloudPermanent
      updateEpoch: "1699879470"
    

Пример использования переменных в шаблонизаторе:

{{- range .nodeUsers }}
echo 'Tuning environment for user {{ .name }}'
# Some code for tuning user environment
{{- end }}

Пример использования команд bashbooster:

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
}

Ход выполнения скриптов можно увидеть на узле в журнале сервиса bashible c помощью команды:

journalctl -u bashible.service

Сами скрипты находятся на узле в директории /var/lib/bashible/bundle_steps/.

Сервис принимает решение о повторном запуске скриптов путем сравнения единой контрольной суммы всех файлов, расположенной по пути /var/lib/bashible/configuration_checksum с контрольной суммой размещенной в кластере kubernetes в секрете configuration-checksums namespace d8-cloud-instance-manager. Проверить контрольную сумму можно следующей командой:

kubectl -n d8-cloud-instance-manager get secret configuration-checksums -o yaml

Сравнение контрольных суммы сервис совершает каждую минуту.

Контрольная сумма в кластере изменяется раз в 4 часа, тем самым повторно запуская скрипты на всех узлах.
Принудительный вызов исполнения bashible на узле можно произвести путем удаления файла с контрольной суммой скриптов с помощью следующей команды:

rm /var/lib/bashible/configuration_checksum

Особенности написания скриптов

При написании скриптов важно учитывать следующие особенности их использования в Deckhouse:

  1. Скрипты в deckhouse выполняются раз в 4 часа или на основании внешних триггеров. Поэтому важно писать скрипты таким образом, чтобы они производили проверку необходимости своих изменений в системе перед выполнением действий, а не производили изменения каждый раз при запуске.
  2. Существуют предзаготовленные скрипты которые производят различные действия в т.ч. установку и настройку сервисов. Важно учитывать это при выборе приоритета пользовательских скриптов. Например, если в скрипте планируется произвести перезапуск сервиса, то данный скрипт должен вызываться после скрипта установки сервиса. В противном случае он не сможет выполниться при развертывании нового узла.

Полезные особенности некоторых скриптов:

  • 032_configure_containerd.sh - производит объединение всех конфигурационных файлов сервиса containerd расположенных по пути /etc/containerd/conf.d/*.toml, а также перезапуск сервиса. Следует учитывать что директория /etc/containerd/conf.d/ не создается автоматически, а также что создание файлов в этой директории следует производить в скриптах с приоритетом менее 32

Chaos Monkey

Инструмент (включается у каждой из NodeGroup отдельно), позволяющий систематически вызывать случайные прерывания работы узлов. Предназначен для проверки элементов кластера, приложений и инфраструктурных компонентов на реальную работу отказоустойчивости.

Мониторинг

Для групп узлов (ресурс NodeGroup) DKP экспортирует метрики доступности группы.

Какую информацию собирает Prometheus?

Все метрики групп узлов имеют префикс d8_node_group_ в названии, и метку с именем группы node_group_name.

Следующие метрики собираются для каждой группы узлов:

  • d8_node_group_ready — количество узлов группы, находящихся в статусе Ready;
  • d8_node_group_nodes — количество узлов в группе (в любом статусе);
  • d8_node_group_instances — количество инстансов в группе (в любом статусе);
  • d8_node_group_desired — желаемое (целевое) количество объектов Machines в группе;
  • d8_node_group_min — минимальное количество инстансов в группе;
  • d8_node_group_max — максимальное количество инстансов в группе;
  • d8_node_group_up_to_date — количество узлов в группе в состоянии up-to-date;
  • d8_node_group_standby — количество резервных узлов (см. параметр standby) в группе;
  • d8_node_group_has_errors — единица, если в группе узлов есть какие-либо ошибки.