Хабр, привет! 

На связи команда разработки контейнерной платформы «Штурвал». Недавно мы выпустили новую версию 2.13 — под катом делимся самым интересным в релизе, а оценить изменения самостоятельно можно в доступной каждому CE-версии.

TL;DR: теперь пользователям доступны установка через YAML и флаги командной строки, профили кластеров по шаблонам, containerd 2.x с шифрованием образов, сводные отчеты по безопасности. Подробные release notes читайте в доке

Shtil. Установка без UI

Shtil остается основным способом установки. В 2.13 мы вернули возможность установки без графического интерфейса, как было в stc.

При помощи YAML-манифестов 

Теперь можно описать всю конфигурацию кластера управления в YAML-файле и запустить установку из консоли. Это полезно при развертывании платформы в нескольких ЦОДах.

Пример YAML-манифеста
---
# Шаблон YAML-манифеста инсталляции платформы с провайдером oVirt
# Конфигурация провайдера
type: CapovProviderConfig

#name: cluster-management-provider # [НЕОБЯЗАТЕЛЬНО] Имя экземпляра провайдера. По умолчанию - cluster-management-provider

credentials:                                                 # [ОБЯЗАТЕЛЬНО] Учетные данные для подключения к API Engine oVirt
  oVirt:
    url: <https://ovirt-engine.example.com/ovirt-engine/api> # [ОБЯЗАТЕЛЬНО] URL для подключения к API Engine oVirt. Требуется указать полный адрес Engine провайдера, добавив на конце /ovirt-engine/api
    username: <admin@internal>                               # [ОБЯЗАТЕЛЬНО] Имя пользователя для аутентификации в API oVirt
    password: <password>                                     # [ОБЯЗАТЕЛЬНО] Пароль для аутентификации в API oVirt

#connection:         # [НЕОБЯЗАТЕЛЬНО] Настройки TLS подключения к API oVirt
  #tlsInsecure: true # [НЕОБЯЗАТЕЛЬНО] Отключить проверку TLS сертификата. По умолчанию - true. Установите false для продакшена с валидными сертификатами
  #tlsCertPath: ''   # [НЕОБЯЗАТЕЛЬНО] Путь к файлу CA сертификата для проверки TLS. Используется при tlsInsecure: false. Пример: /path/to/ca-bundle.crt

providerConfig:                      # [ОБЯЗАТЕЛЬНО] Конфигурация провайдера oVirt
  #subtype: zvirt                    # [НЕОБЯЗАТЕЛЬНО] Подтип ovirt-подобного провайдера. Может быть задано одно из значений: zvirt, hostvm, redvirt, rosavirt
  datacenter: <Default>              # [ОБЯЗАТЕЛЬНО] Имя датацентра oVirt, где будут создаваться ВМ
  datacenterCluster: <Default>       # [ОБЯЗАТЕЛЬНО] Имя кластера oVirt внутри датацентра
  vnicProfile: <ovirtmgmt/ovirtmgmt> # [ОБЯЗАТЕЛЬНО] Имя VNIC профиля oVirt для сетевых интерфейсов ВМ
  template: <rocky9-template>        # [ОБЯЗАТЕЛЬНО] Имя шаблона ВМ в выбранном датацентре (базовый образ для узлов кластера)
  #csiStorage: ''                    # [НЕОБЯЗАТЕЛЬНО] Имя домена хранения для динамических постоянных томов через CSI драйвер. Оставьте пустым для отключения CSI
  #vmType: server                    # [НЕОБЯЗАТЕЛЬНО] Тип ВМ для создаваемых виртуальных машин. По умолчанию - server. Не переопределяйте без специальных требований
  #templateNetInterface: eth0        # [НЕОБЯЗАТЕЛЬНО] Имя сетевого интерфейса в шаблоне. По умолчанию - eth0. Не переопределяйте, если шаблон не использует другой интерфейс

ingressCerts:                         # Сертификат кластера. По умолчанию кластер будет инсталлирован с самоподписным сертификатом. Только один из подтипов сертификата может быть выбран
  ca:
    crtPath:                          # [НЕОБЯЗАТЕЛЬНО] Путь до цепочки сертификатов (ваш промежуточный сертификат -> сертификат корпоративного центра сертификации) в формате "pem" файла. Должен быть задан в паре с `ca.keyPath`
    keyPath:                          # [НЕОБЯЗАТЕЛЬНО] Путь до закрытого ключа промежуточного сертификата CA. Должен быть задан в паре с `ca.crtPath`
  tls:
    crtPath:                          # [НЕОБЯЗАТЕЛЬНО] Путь до корпоративного сертификата("pem" файла), который был выпущен CA (в этом случае в файле будет цепочка сертификатов) или самоподписан для доменного имени Ingress. Должен быть задан в паре с `tls.keyPath`
    keyPath:                          # [НЕОБЯЗАТЕЛЬНО] Путь до закрытого ключа корпоративного сертификата Ingress. Должен быть задан в паре с `tls.crtPath`
  acme:
    rootPath: </some/path>            # [НЕОБЯЗАТЕЛЬНО] Путь до файла корневого сертификата CA для ACME. Должен быть задан в паре с `acme.url`
    url: example.com                  # [НЕОБЯЗАТЕЛЬНО] Адрес ACME сервера с портом и путем к ресурсу, например: https://acme.corp.lan:8443/directory. Должен быть задан в паре с `acme.rootPath`
    email: user@domain.com            # [НЕОБЯЗАТЕЛЬНО] Email, который должен быть связан с учетной записью Let's Encrypt

---
type: CapovClusterConfig           # Конфигурация кластера управления
cluster:                            # [ОБЯЗАТЕЛЬНО] Конфигурация кластера управления
  apiEndpoint: <192.168.1.100>      # [ОБЯЗАТЕЛЬНО] Адрес API-сервера кластера (IP или FQDN)
  #clusterName: cluster-management  # [НЕОБЯЗАТЕЛЬНО] Имя создаваемого кластера управления. По умолчанию - cluster-management
  #enabledServices: []              # [НЕОБЯЗАТЕЛЬНО] Список включенных сервисов, перечисленных через запятую. По умолчанию (если не задано) в кластере будут установлены критически важные для работы платформы сервисы, а также сервисы мониторинга и логирования. Если установлено minimal: true, значения этого параметра будут проигнорированы
  #externalingresslb: false         # [НЕОБЯЗАТЕЛЬНО] Использовать внешний балансировщик для Ingress. По умолчанию - false
  #ingress: ''                      # [ОБЯЗАТЕЛЬНО, если не задан ingressvip] Wildcard DNS-запись для ingress (например, <cluster_name>.<base_domain>)
  #controlPlaneNodesCount: 1        # [НЕОБЯЗАТЕЛЬНО] Количество Control Plane узлов. Должно быть не менее 1. По умолчанию - 1
  ingressvip: <192.168.1.101>       # [НЕОБЯЗАТЕЛЬНО] VIP-адрес для Ingress контроллера. Чтобы задать VIP-адрес для ingress, должен быть указан externalingresslb: false
  #podSubnet: 172.16.0.0/16         # [НЕОБЯЗАТЕЛЬНО] CIDR подсети подов. По умолчанию - 172.16.0.0/16
  #secure: false                    # [НЕОБЯЗАТЕЛЬНО] Включить расширенные параметры безопасности. По умолчанию - false
  #serviceSubnet: 10.96.0.0/12      # [НЕОБЯЗАТЕЛЬНО] CIDR подсети сервисов. По умолчанию - 10.96.0.0/12
  #shturvalVersion: 2.13.0          # [НЕОБЯЗАТЕЛЬНО] Версия платформы. Должна соответствовать версии утилиты shtil
  #minimal: false                   # [НЕОБЯЗАТЕЛЬНО] Определяет инсталляцию кластера управления с минимальным набором сервисов. Если задать true, будут установлены только критически важные для работы платформы сервисы. При этом сервисы в enabledServices будут проигнорированы

#provider:                                             # [НЕОБЯЗАТЕЛЬНО] Конфигурации узлов. По умолчанию конфигурация групп Control Plane и Worker-узлов предзаполнена. Создание дополнительных Worker групп недоступно
  #name: cluster-management-provider                   # [НЕОБЯЗАТЕЛЬНО] Должно совпадать с именем экземпляра провайдера. По умолчанию - cluster-management-provider

  #  # Конфигурация Control Plane узлов
  #controlPlaneNodeConfig:                             # [НЕОБЯЗАТЕЛЬНО] Конфигурация Control Plane узлов
  #  nodeConfig:
  #    groupName: control-plane                        # [Не переопределять] Имя группы Control Plane узлов
  #    roles:
  #      - name: node-role.kubernetes.io/control-plane # [Не переопределять] Роль группы Control Plane узлов, должна быть строго control-plane
  #  capovNodeConfig:
  #    cpu:
  #      cores: 4                                      # [НЕОБЯЗАТЕЛЬНО] Количество ядер CPU на Control Plane узел. По умолчанию - 4
  #      sockets: 1                                    # [НЕОБЯЗАТЕЛЬНО] Количество CPU сокетов на Control Plane узел. По умолчанию - 1
  #      threads: 1                                    # [НЕОБЯЗАТЕЛЬНО] Количество потоков CPU на сокет. По умолчанию - 1
  #    memory:
  #      sizeMB: 16000                                 # [НЕОБЯЗАТЕЛЬНО] Размер памяти в МБ на Control Plane узел. По умолчанию - 16000
  #      guaranteedMB: 16000                           # [НЕОБЯЗАТЕЛЬНО] Гарантированная память в МБ. Должна совпадать с sizeMB. По умолчанию - 16000
  #    osDiskSizeGB: 100                               # [НЕОБЯЗАТЕЛЬНО] Размер диска ОС в ГБ на Control Plane узел. По умолчанию - 100

  #  # Конфигурация Worker-узлов
  #workerNodeConfigs:                                  # [НЕОБЯЗАТЕЛЬНО] Конфигурация Worker-узлов
  #  - nodeConfig:                                     # [НЕОБЯЗАТЕЛЬНО] Создание дефолтной (default) группы Worker-узлов
  #      groupName: default                            # [Не переопределять] Имя дефолтной группы Worker-узлов
  #      roles:
  #        - name: node-role.kubernetes.io/workers     # [НЕОБЯЗАТЕЛЬНО] Роль группы Worker-узлов
  #    workersCount: 3                                 # [НЕОБЯЗАТЕЛЬНО] Количество узлов в дефолтной Worker группе. По умолчанию - 3
  #    capovNodeConfig:
  #      cpu:
  #        cores: 8                                    # [НЕОБЯЗАТЕЛЬНО] Количество ядер CPU на Worker-узел. По умолчанию - 8
  #        sockets: 1                                  # [НЕОБЯЗАТЕЛЬНО] Количество CPU сокетов на Worker-узел. По умолчанию - 1
  #        threads: 1                                  # [НЕОБЯЗАТЕЛЬНО] Количество потоков CPU на сокет. По умолчанию - 1
  #      memory:
  #        sizeMB: 32000                               # [НЕОБЯЗАТЕЛЬНО] Размер памяти в МБ на Worker-узел. По умолчанию - 32000
  #        guaranteedMB: 32000                         # [НЕОБЯЗАТЕЛЬНО] Гарантированная память в МБ. Должна совпадать с sizeMB. По умолчанию - 32000

Все шаблоны YAML-манифестов доступны здесь.

При помощи флагов командной строки

Для тех, кто предпочитает скрипты — можно передать все параметры через флаги.

shtil install ovirt \ 
--api-endpoint=10.131.145.101 \
--ingress-default-fqdn= "*.some.address.com" \ 
--use-external-ingress-lb=true \ 
--url-provider="https://ovirt.example.com/ovirt-engine/api" \ 
--user-provider="user@internal" \ 
--password-provider="mypa\$\$word" \ 
--datacenter-provider=Datacenter1 \ 
--datacenter-cluster-provider=some_dc_cluster_name \ 
--vnic-profile-provider=ovirtmgmt \ 
--template=LinuxVM_001 \ 
--bootstrap-license=/path/to/license.yaml

Процесс установки с помощью shtil подробно описан тут.

Containerd 2.x

Был реализован переход на containerd 2.x в качестве среды выполнения контейнеров. Обновление происходит автоматически. 

Что это дало: 

  • cgroup v2 — более точный контроль ресурсов и лучшая изоляция контейнеров; 

  • шифрование образов — дополнительный уровень безопасности для чувствительных workloads; 

  • ускоренная загрузка образов (screaming) — контейнеры стартуют быстрее, не дожидаясь полной загрузки образа; 

  • монтирование образов контейнеров как файловых систем — подходит для работы с ML-моделями и датасетами. 

Профили конфигурации кластеров

Мы расширили возможности управлениям профилями конфигурации клиентских кластеров. 

Профиль — это шаблон с преднастроенными параметрами для похожих кластеров. Он позволяет стандартизировать конфигурации (узлы с GPU, NVIDIA Device Plugin, Vault, Argo CD и другие), сократить количество ручных операций и ошибок. В версии 2.14 для профилей будет реализован графический интерфейс.

Логи

Логи теперь сгруппированы по стримам, чтобы было легче ориентироваться в потоке сообщений. А еще добавлен поиск по параметрам логов — namespace, pod, container, уровню важности и подобному.

Переработанный интерфейс NCI

Интерфейс конфигурации узлов (Node Configuration Interface, NCI) переведен на модальные окна. 

Добавлены: 

  • Параметры Kube API Server. Можно настраивать параметры API-сервера прямо в графическом интерфейсе NCI. Не нужно править YAML или использовать kubectl. Feature gates, Admission Controllers, параметры аудита доступны через UI.

  • Модальные окна для всех разделов. Конфигурация всех разделов NCI вынесена в модальные окна, чтобы было легче сосредоточиться на конкретной секции настроек.

  • Видимость состояний NodeConfig. Добавлено отображение состояний конфигураций узлов (NodeConfigs) кластера. Теперь видно, применилась ли конфигурация на узлах, в каком статусе находится каждый NodeConfig.

Конфигурация NCI в модальном окне
Конфигурация NCI в модальном окне
Статусы NodeConfig в кластере
Статусы NodeConfig в кластере

Сервисы и безопасность

Трехпозиционный переключатель сервисов 

Режим работы сервисов управляется через состояния:

  • Absent (он недоступен для критически важных сервисов)

  • Manual 

  • Auto

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

Сводные отчеты по безопасности

В интерфейс добавлены агрегированные отчеты по всем кластерам: 

  • Kyverno — политики безопасности и соответствия в едином представлении.  

Теперь доступно полное представление по всей платформе, а не только по отдельным кластерам.

  • Trivy — результаты сканирования образов контейнеров на уязвимости. 

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

Сохранение пользовательских настроек

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

А что еще?

  • Доступна поддержка указания DNS-записи Ingress при использовании внутреннего LB в кластерах без Cloud Controller Manager. Это упрощает настройку сетевого доступа в классических инфраструктурах (vSphere, Shturval v2, oVirt).

  • В клиентских кластерах дефолтная конфигурация ресурсов приведена в соответствие с минимальными требованиями для установки. Теперь меньше шансов, что кластер не раскатится из-за нехватки памяти или CPU.

  • Обновлены ключевые компоненты: Kubernetes 1.34.3, Cilium 1.19, Cluster API 1.11.0, containerd 2.x.

И напоследок — полезные ссылки: