Объект NCI (NodeConfigItem)
Обзор
NodeConfigItem (NCI) — кластерный кастомный ресурс Kubernetes, который описывает переиспользуемый шаблон конфигурации Linux-узлов. В NCI администратор задаёт, что нужно настроить на узлах, на какие узлы распространить конфигурацию и с каким приоритетом объединять её с другими NCI.
NCI используется для декларативного управления настройками ОС и компонентов Kubernetes на узлах: NTP, containerd, sysctl, пакетами, репозиториями, файлами, пользователями, systemd-юнитами, kubelet, kube-apiserver и другими разделами. Настройка NCI в графическом интерфейсе, поля форм и расширенные примеры манифестов описаны на странице Конфигурация узлов (NCI).
NCI не применяется к узлу напрямую. Модуль shturval-node-config выбирает подходящие объекты NCI по селекторам, записывает их имена в NodeConfig (NC) конкретных узлов, а демон std (shturvald) на узле объединяет конфигурацию, применяет её и отражает результат в статусе NodeConfig.
Когда использовать NCI
Используйте NCI, когда нужно:
- единообразно настроить группу узлов по лейблам, например все Worker-узлы или только узлы с GPU;
- подключить репозитории пакетов или приватные registry для containerd;
- установить, удалить или заблокировать пакеты ОС;
- создать файлы, директории, локальных пользователей и SSH-ключи;
- настроить sysctl, systemd-юниты, NTP, сертификаты, параметры ядра, SELinux, swap или iptables;
- управлять параметрами kubelet и kube-apiserver на выбранных узлах;
- разделить базовую конфигурацию и специализированные overrides через
priority.
Для просмотра статуса применения конкретного NCI на узле используйте страницу узла или статус соответствующего NodeConfig.
Идентификация ресурса
| Параметр | Значение |
|---|---|
| API group | node.shturval.tech |
| API version | v1beta2 |
| Kind | NodeConfigItem |
| Plural | nodeconfigitems |
| Short name | nci |
| Scope | Cluster |
| Finalizer | node.shturval.tech/finalizer |
| Webhook | Mutating webhook /mutate-node-shturval-tech-nodeconfig для create/update |
Общий обзор API-групп и кастомных ресурсов платформы см. в разделе Кастомные ресурсы в платформе.
Жизненный цикл
- Администратор создаёт или изменяет
NodeConfigItem. - Mutating webhook добавляет служебные аннотации
usernameиupdatedDateдля внешнего пользователя. Сервисный аккаунт оператора пропускается без мутации. NodeConfigItemReconcilerвыбираетNodeConfig, labels которых соответствуютspec.nodeconfigselector.- Имя NCI добавляется в
NodeConfig.spec.nodeconfigitemsкаждого выбранного узла. - Демон
stdна узле читает локальный init NCI и кеш NCI из кластера, сохраняет кеш в/etc/std/caches/<name>.json, объединяет конфигурации в/etc/std/merged.jsonи применяет результат. - Результат применения записывается в
NodeConfig.status.ncistate. NodeConfigItem.statusпоказывает агрегированную картину: какиеNodeConfigвыбраны, какие уже обновлены и готов ли NCI в целом.
Связь NCI, NodeConfig, дрейна и перезагрузки подробно описана в жизненном цикле модуля shturval-node-config.
Структура
Минимальный пример:
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
name: nodeconfigitem-sample
spec:
nodeconfigselector:
kubernetes.io/os: linux
priority: 100
files:
- path: /etc/shturval/test
type: directory
mode: "0600"
metadata.name — имя NCI. После создания имя объекта не изменяется. Чтобы заменить NCI с другим именем, создайте новый объект и удалите старый, учитывая ограничения удаления и rollback.
Поля spec
| JSON-поле | Тип | Обязательное | Назначение |
|---|---|---|---|
nodeconfigselector |
map[string]string |
Да | Выбирает NodeConfig по labels. |
priority |
uint |
Нет | Приоритет merge. Чем больше значение, тем выше приоритет. |
kubeversion |
string |
Нет | Целевая версия Kubernetes для upgrade. |
repositories |
[]Repo |
Нет | Подключение или удаление репозиториев пакетов ОС. |
packages |
[]Package |
Нет | Установка, удаление и блокировка пакетов ОС. |
files |
[]File |
Нет | Создание и изменение файлов и директорий. |
ntp |
*NTP |
Нет | NTP-серверы и часовой пояс. |
certificates |
[]Certificate |
Нет | Доверенные сертификаты ОС. |
runtimecfg |
*ContainerRuntimeConfig |
Нет | Конфигурация containerd: registry, hosts.toml, config.toml. |
kernelarguments |
[]KernelArgument |
Нет | Параметры загрузчика ядра. |
kernelmodules |
[]KernelModule |
Нет | Автозагрузка и blacklist модулей ядра. |
sysctl |
*Sysctl |
Нет | Параметры sysctl в формате ключ-значение. |
systemdunits |
[]SystemdUnitConfig |
Нет | Запуск, остановка и автозагрузка systemd-юнитов. |
users |
[]User |
Нет | Локальные Linux-пользователи, группы и SSH-ключи. |
swap |
*Swap |
Нет | Включение или отключение swap. |
iptables |
*Iptables |
Нет | Flush iptables. |
selinux |
*Selinux |
Нет | Режим SELinux. |
kubecerts |
*KubeCerts |
Нет | Период ротации системных сертификатов Kubernetes. |
kubelet |
*Kubelet |
Нет | Подмножество параметров kubelet. |
kubeapi |
*KubeAPI |
Нет | Параметры kube-apiserver на Control Plane узлах. |
Полный перечень полей форм и примеров для разделов spec см. на странице Конфигурация узлов (NCI).
Селектор узлов
spec.nodeconfigselector — обязательная карта key: value. Контроллер выбирает те NodeConfig, у которых есть все labels, указанные в селекторе NCI, с теми же значениями. Формат близок к nodeSelector Kubernetes.
Пример выбора всех Linux Worker-узлов:
spec:
nodeconfigselector:
kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""
Если селектор соответствует нескольким узлам, один NCI будет добавлен в NodeConfig.spec.nodeconfigitems каждого подходящего узла. Для выбора узлов используйте стандартные labels Kubernetes или пользовательские labels. Примеры настройки labels есть на странице Конфигурация узлов (NCI).
Приоритет и merge
На одном узле может быть несколько NCI. Перед применением демон объединяет их в итоговую конфигурацию /etc/std/merged.json.
Алгоритм merge:
- NCI сортируются по возрастанию
spec.priority. - При равном
priorityраньше идёт NCI с более раннимCreationTimestamp. - Если timestamp совпадает, порядок определяется именем.
- Merge выполняется от меньшего приоритета к большему, поэтому NCI с большим
priorityперезаписывает конфликтующие значения.
Практический вывод: базовые NCI задавайте с меньшим приоритетом, а специализированные overrides — с большим. При одинаковом priority позже созданный NCI может переопределить конфликтующие значения ранее созданного NCI; если время создания совпало, последним станет NCI с лексикографически большим именем.
nodeconfigselector и priority не попадают в итоговую конфигурацию узла. Они используются только для выбора узлов и порядка объединения.
Статус NodeConfigItem
NodeConfigItem.status управляется оператором и показывает агрегированный результат распределения NCI по выбранным узлам.
| JSON-поле | Тип | Описание |
|---|---|---|
selectednodeconfigs |
[]string |
Имена NodeConfig, выбранных по nodeconfigselector. |
updatednodeconfigs |
[]string |
Имена NodeConfig, где соответствующий NCI имеет состояние applied. |
ready |
bool |
true, если все выбранные NodeConfig обновлены и список выбранных не пуст. |
applied |
string |
Строка вида <updated>/<selected>, например 3/3. |
NodeConfigItem.status.ready означает, что NCI доведён до состояния applied в NodeConfig.status.ncistate. Это не самостоятельный rollback-механизм и не отдельная проверка каждого файла, пакета или параметра вне логики агента. Для диагностики конкретного узла смотрите NodeConfig.status.ncistate; его поля описаны в справочнике NodeConfig (NC).
Порядок применения на узле
После merge демон применяет разделы конфигурации в фиксированном порядке:
swapselinuxiptablesusersfileskubeapisysctlkernelargumentskubecertscertificatesrepositoriespackagesruntimekernelmodulessystemdunitsntpkubelet
kubeversion применяется отдельной логикой Kubernetes upgrade: сначала NCI добавляется только на bootstrap/init node, после его обновления — на остальные выбранные узлы.
Основные разделы конфигурации
Репозитории и пакеты
repositories управляет сетевыми репозиториями пакетов ОС. Репозиторий идентифицируется по address; state: present подключает репозиторий, state: absent удаляет его из конфигурации пакетного менеджера.
packages устанавливает, удаляет и блокирует пакеты. Пакет идентифицируется по name; для удаления используйте state: absent, для запрета автообновления — setlock: true.
spec:
repositories:
- name: internal
state: present
address: https://repo.example.com/os
keyurl: https://repo.example.com/RPM-GPG-KEY
checkgpg: true
checkssl: true
packages:
- name: nginx
state: present
setlock: true
- name: old-agent
state: absent
ignorelock: true
Файлы, сертификаты и пользователи
files создаёт или изменяет файлы и директории. Идентификатор merge — пара path и type. Удаление файлов и директорий через NCI не предусмотрено.
certificates добавляет доверенные сертификаты ОС. Для удаления сертификата используйте exist: false.
users создаёт или изменяет Linux-пользователей, группы и SSH-ключи. SSH-ключи объединяются и дедуплицируются. Поля для удаления пользователя или группы через NCI нет.
spec:
files:
- path: /etc/shturval/config.env
type: file
mode: "0640"
owner: root
group: root
content: |
ENABLED=true
certificates:
- name: corp-ca
url: https://ca.example.com:443
exist: true
users:
- username: admin
homedir: /home/admin
shell: /bin/bash
group: admin
sshkeys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAExample admin@example
Container Runtime
runtimecfg управляет containerd: registry hosts, config.toml, sandbox image, cgroup driver и произвольными секциями. Для настройки приватных registry используйте runtimecfg.registries[].license; это YAML-поле записывается как Authorization header в hosts.toml. Подробный сценарий подключения приватного registry см. в разделе Настройка приватного реестра.
spec:
runtimecfg:
registries:
- name: registry.example.com
host: https://registry.example.com
capabilities: [pull, resolve]
license: "Basic dXNlcjpwYXNzd29yZA=="
insecure: false
Для HTTP registry обязательно указывайте insecure: true:
spec:
runtimecfg:
registries:
- name: registry.local
host: http://registry.local:5000
capabilities: [pull, resolve]
insecure: true
Для настройки config.toml используйте runtimecfg.configSections, а не deprecated-поля pauseimage и cgroupdriver:
spec:
runtimecfg:
configSections:
- path: 'plugins."io.containerd.grpc.v1.cri"'
params:
- key: sandbox_image
value: registry.k8s.io/pause:3.10
- path: 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options'
params:
- key: SystemdCgroup
value: true
Секции и параметры configSections можно удалять через exist: false, но root section с path: "" удалить нельзя. Для удаления лишних registry-директорий, отсутствующих в spec, используйте runtimecfg.removeunused: true.
Sysctl, systemd и настройки ОС
sysctl задаёт параметры ядра в формате строковых значений. Они сохраняются в /etc/sysctl.d/9999-shturval-items.conf.
systemdunits запускает, останавливает, включает или отключает автозапуск systemd-юнитов. Если active или enabled не заданы, значение трактуется как true.
kernelarguments управляет параметрами загрузчика ядра; для удаления параметра используйте exist: false. kernelmodules включает автозагрузку модулей или помещает их в blacklist. При одновременном autoload: true и blacklist: true blacklist имеет приоритет.
spec:
sysctl:
param:
net.ipv4.ip_forward: "1"
vm.max_map_count: "262144"
systemdunits:
- name: chronyd.service
active: true
enabled: true
kernelmodules:
- name: br_netfilter
autoload: true
- name: nouveau
autoload: false
blacklist: true
ntp задаёт NTP-серверы и timezone. Для применения NTP-настроек на узле должен быть установлен и включён сервис ntpd или chronyd; пример установки сервиса через packages и systemdunits приведён на странице Конфигурация узлов (NCI).
Kubernetes-компоненты
kubecerts задаёт период ротации системных сертификатов Kubernetes. Значение rotationperiod должно быть от 7 до 365 дней, значение по умолчанию — 30.
kubeapi управляет отдельными параметрами kube-apiserver: Admission Plugins, Feature Gates, OIDC, Audit Policy, requests/limits, priority и шифрованием Secrets. Применяйте этот раздел к Control Plane узлам.
spec:
nodeconfigselector:
node-role.kubernetes.io/control-plane: ""
kubeapi:
admissionplugins:
AlwaysPullImages: true
PodSecurityPolicy: false
kubelet содержит подмножество параметров KubeletConfiguration: CPU и memory policies, reservedSystemCPUs, systemReserved, maxPods, featureGates, TLS, частоты синхронизации, registry pull limits и другие поля. Для сценариев CPU Pinning см. Резервирование CPU для etcd.
spec:
kubelet:
cpuManagerPolicy: static
memoryManagerPolicy: Static
topologyManagerPolicy: single-numa-node
reservedSystemCPUs: "0-1"
maxPods: 100
Ограничения и важное поведение
Удаление NCI не откатывает изменения
NCI не является rollback-механизмом. Если NCI удалён или перестал подходить по selector, оператор убирает его имя из NodeConfig, но уже применённые изменения ОС остаются на узле: созданные пользователи, файлы, репозитории, пакеты, runtime-настройки и другие элементы не откатываются автоматически.
Чтобы изменить состояние, создайте новый NCI или измените существующий NCI с нужными параметрами. При конфликте используйте более высокий priority. Если изменение требует перезагрузки, её координирует shturval-node-config; ручное управление описано в разделе Защитить узлы от автоматического перезапуска.
Удаление доступно только через явные команды
Подтверждённые способы описать целевое состояние «объекта не должно быть»:
packages[].state: absent;runtimecfg.removeunused: trueдля лишних registry-директорий.
Не найдено подтверждённой команды удаления для Linux-пользователя или группы через users, файла или директории через files, systemd unit-файла через systemdunits и произвольной registry-записи без removeunused.
Пустые строки часто не очищают значения
В merge для repositories, packages, files, users, kernelmodules и runtime registries многие строковые поля обновляются только если новое значение непустое. Поэтому пустой строкой обычно нельзя очистить ранее заданное значение через более приоритетный NCI.
Валидация не покрывает все ошибки
Основная валидация задана OpenAPI-схемой CRD. Отдельные бизнес-ограничения могут проявиться только при применении на узле, например:
- некорректный
runtimecfg.configSections.path; - попытка удалить root section containerd;
- HTTP registry без
insecure: true; - конфликт kubelet-полей, например
maxParallelImagePullsвместе сserializeImagePulls: true.
Просмотр и диагностика
# Список всех NCI в кластере
kubectl get nodeconfigitem
kubectl get nci
# Краткий вывод с приоритетом, applied/ready и selector
kubectl get nodeconfigitem -o wide
# Полный манифест NCI
kubectl get nodeconfigitem <nci-name> -o yaml
# Список NodeConfig, где видно применение на уровне узлов
kubectl get nodeconfig
# Статус конкретного узла
kubectl get nodeconfig <node-name> -o yaml
Для общей диагностики оператора и демона используйте раздел Диагностика модуля shturval-node-config. В интерфейсе список NCI и отношение применённых узлов к выбранным отображаются на странице Конфигурация узлов (NCI), а состояние применения NCI на конкретном узле — на странице узла.
Быстрая памятка
- Используйте
apiVersion: node.shturval.tech/v1beta2. - Всегда задавайте
spec.nodeconfigselector: это обязательное поле выбора узлов. - Разделяйте базовую и специализированную конфигурацию по
priority. - Для containerd предпочитайте
runtimecfg.configSections, а не deprecatedpauseimageиcgroupdriver. - Для private registry используйте YAML-поле
license, а неauthorization. - Для HTTP registry указывайте
insecure: true. - Не рассчитывайте, что удаление NCI откатит изменения на узле.
- Для удаления используйте только явные команды
state: absent,exist: falseилиremoveunused: true, если они поддержаны соответствующим разделом. - Для диагностики конкретного узла смотрите
NodeConfig.status.ncistate, а не толькоkubectl get nci.