ADG Оставить заявку
Блог DevOps 4 мин чтения

Kubernetes 1.31 beta: проверяем CSI-совместимость в Deckhouse на отечественных серверах

Kubernetes 1.31 beta окончательно убрал in-tree volume-драйверы. Смотрим, что это значит для Deckhouse-кластеров на отечественном железе и как проверить CSI до обновления.

Контекст момента

Kubernetes 1.31 beta - нативный AppArmor и финальное удаление in-tree volume plugin-ов, завершающее миграцию на CSI

Kubernetes 1.31 вышел в beta, и среди прочего там два события, которые нас задели напрямую. Первое - AppArmor наконец стал first-class гражданином API: поле appArmorProfile в podSpec вместо аннотаций. Второе - и это важнее - финальное удаление in-tree volume plugin-ов завершено. Не «deprecated», не «планируется», а именно удалено. Для кластеров на managed Kubernetes с отечественным железом это конкретный повод проверить стек хранилища до того, как обновление прилетит само.

Что именно ушло

In-tree volume plugin-ы - это встроенные в ядро Kubernetes драйверы для работы с различными системами хранения. AWS EBS, Azure Disk, GCE PD, Cinder, vSphere - всё это когда-то жило прямо в коде Kubernetes. CSI (Container Storage Interface) появился как абстракция, позволяющая вынести эти драйверы в отдельные плагины, независимые от цикла релизов Kubernetes. Миграция шла несколько лет, в 1.31 она завершена.

На практике это означает: если у вас в кластере PersistentVolume с типом, который раньше обслуживал in-tree драйвер, а внешнего CSI-плагина нет или он не настроен правильно - вы получите проблему с монтированием томов после обновления.

Для кластеров на публичных облаках это обычно не вопрос - провайдеры давно переехали на CSI. Интереснее ситуация у тех, кто разворачивает кластеры на собственном железе с кастомными решениями хранения.

Как это выглядит в Deckhouse на отечественных серверах

Мы работаем с несколькими кластерами на Deckhouse, развёрнутыми на серверах российского производства - часть из стека по итогам пересмотра серверной дорожной карты после санкционных новостей июля. Типичная конфигурация хранилища в таких кластерах: Ceph через rook-ceph с CSI-драйвером, локальные диски через local-path-provisioner, иногда NFS через nfs-subdir-external-provisioner.

На первый взгляд всё выглядит нормально - ни один из этих вариантов не зависит от in-tree плагинов, которые убрали в 1.31. Но дьявол в деталях: мы обнаружили несколько PV, созданных ещё на старых версиях кластера, где в поле spec.storageClassName стояло что-то вроде kubernetes.io/rbd или kubernetes.io/glusterfs - наследие от инсталляций, которые мигрировали через несколько мажорных версий. Эти тома монтировались, потому что in-tree плагин был жив. После 1.31 - не будут.

Что мы проверяем перед обновлением

Минимальный чеклист для кластера, который готовится получить 1.31:

  • Инвентаризация PV по типам. kubectl get pv -o json | jq '.items[].spec | {name: .storageClassName, source: keys}' - смотрим на всё, где source содержит что-то отличное от csi. Любой awsElasticBlockStore, azureDisk, gcePersistentDisk, cinder, rbd, glusterfs, flocker, quobyte, storageos, portworxVolume, scaleIO - это потенциальные проблемные зоны.

  • Проверка StorageClass-ов. kubectl get sc -o yaml - смотрим на provisioner. Если там что-то без csi в названии и не kubernetes.io/no-provisioner (это local) - разбираемся откуда оно взялось.

  • CSI-драйверы в кластере. kubectl get csidrivers - всё ли необходимое установлено и находится ли в состоянии Ready.

  • Rook-ceph специфично. Проверяем версию rook-ceph и совместимость с версией Kubernetes. Rook 1.14+ поддерживает Kubernetes до 1.30; поддержка 1.31 появится в следующем релизе rook-ceph, но старые версии имеют ограничения уже сейчас.

У нас нашлось несколько rbd-томов в статусе Released с retain-политикой - живые данные там уже не хранились, но PV существовали. Почистили руками. Ещё один кластер показал NFS-тома через старый плагин kubernetes.io/nfs - заменили на nfs-subdir-external-provisioner с нормальным CSI.

AppArmor: приятная мелочь

Нативный AppArmor в 1.31 - это скорее радость для тех, кто строит безопасность кластера правильно. До 1.31 AppArmor-профили задавались через аннотации вида container.apparmor.security.beta.kubernetes.io/<container_name>: profile. Работало, но выглядело как временный костыль.

В 1.31 появился securityContext.appArmorProfile с двумя вариантами: RuntimeDefault (использовать дефолтный профиль рантайма) и Localhost (профиль с указанием имени, загруженный на ноде). На Astra Linux, которая у ряда наших клиентов из КИИ стоит на хостах, AppArmor присутствует и этот механизм имеет смысл использовать. Аннотации в 1.31 ещё работают для обратной совместимости, но закладываться на них не стоит.

Итог

Основная работа перед обновлением кластера на 1.31 - это аудит хранилища, а не AppArmor. Три часа с kubectl и jq дали нам полную картину по всем кластерам: где CSI-стек чистый, где есть исторический мусор, где нужна миграция. Лучше потратить это время сейчас, чем разбираться с unmountable-томами после автообновления.

Deckhouse в своём цикле релизов обычно идёт за апстримом с небольшим лагом - 1.31 GA ожидается в августе, Deckhouse подтянется примерно к осени. Времени на подготовку достаточно, но начинать инвентаризацию стоит уже сейчас, особенно в кластерах с историей в несколько мажорных версий.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.