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

Kubernetes 1.10: CSI в beta - подключаем Ceph RBD без патчей ядра

Обновляемся до Kubernetes 1.10: Container Storage Interface в beta позволяет подключать Ceph RBD через стандартный плагин без патчей ядра и out-of-tree драйверов.

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

Релиз Kubernetes 1.10 - Container Storage Interface (CSI) переходит в beta, улучшения RBAC и стабилизация Storage API

Kubernetes 1.10 вышел на прошлой неделе, и главное для нас в этом релизе - Container Storage Interface переходит в beta. Это не просто очередная галочка в changelog: CSI меняет то как Kubernetes работает с внешними системами хранения, и для кластеров с Ceph это имеет вполне конкретное практическое значение.

Что такое CSI и зачем он нужен

До CSI все плагины хранилища жили внутри бинарника Kubernetes - код для работы с AWS EBS, GCE PD, Ceph RBD, GlusterFS, iSCSI и ещё двумя десятками систем был встроен в kubelet и kube-controller-manager. Это создавало несколько проблем.

Во-первых, цикл выпуска: если в плагине Ceph RBD нашли баг или нужна новая функция - ждёшь следующего релиза Kubernetes. Во-вторых, для некоторых драйверов требовалась специфичная сборка ядра или дополнительные модули прямо на ноде. Для Ceph RBD это rbd и librados - надо было следить чтобы они были на каждой ноде, и при обновлении ядра иногда что-то разъезжалось.

CSI это стандартный интерфейс - спецификация gRPC, по которой Kubernetes разговаривает с плагином хранилища. Плагин живёт в обычном Pod-е, обновляется независимо от Kubernetes, не требует ничего в ядре кроме минимального набора системных вызовов для маунта. Идея не новая - Docker давно двинулся в ту же сторону с volume plugins - но в Kubernetes эта механика до сих пор была в alpha и на ней никто не строил серьёзного.

В 1.10 CSI становится beta. Это значит: API не будет ломаться без предупреждения, включено по умолчанию, можно начинать использовать в чём-то реальном.

Как это меняет работу с Ceph RBD

У нас несколько кластеров Kubernetes которые работают поверх инфраструктуры под управлением - часть из них использует Ceph как основную систему хранения через PersistentVolume. До 1.10 схема выглядела так: встроенный плагин rbd в kubelet, на каждой ноде нужны пакеты ceph-common с клиентскими инструментами и загруженный модуль ядра rbd.

Это работало, но с нюансами. При обновлении ОС на нодах надо было проверять что модуль ядра есть. При замене нод в кластере - снова ставить пакеты. На дистрибутивах без ceph в стандартных репозиториях - добавлять сторонние источники. Небольшая, но стабильно присутствующая операционная нагрузка.

С CSI-плагином для Ceph картина другая. Плагин запускается как DaemonSet в кластере, всё что ему нужно на ноде - стандартные системные вызовы для block device и монтирования. Подключение к Ceph-кластеру, авторизация через keyring, создание и маппинг RBD-образа - всё это делает процесс внутри контейнера, а не код в kubelet.

Обновить версию плагина - это kubectl set image daemonset/csi-rbdplugin, а не Rolling update всего кластера. Для операционной команды это принципиальная разница.

Что мы попробовали

На тестовом кластере мы поставили Kubernetes 1.10 и развернули CSI-плагин для Ceph RBD - ceph-csi от сообщества. Это не официальный плагин от самого Ceph-проекта, но наиболее активно поддерживаемый на данный момент.

Конфигурация требует создания нескольких объектов: StorageClass с параметрами CSI-драйвера, Secret с keyring и endpoint Ceph-кластера, само развёртывание плагина из трёх компонентов - provisioner, attacher и DaemonSet с node-плагином.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd-csi
provisioner: rbd.csi.ceph.com
parameters:
  monitors: 10.0.0.11:6789,10.0.0.12:6789,10.0.0.13:6789
  pool: kubernetes
  imageFormat: "2"
  imageFeatures: layering
  csiProvisionerSecretName: ceph-secret
  csiProvisionerSecretNamespace: kube-system
  csiNodePublishSecretName: ceph-secret
  csiNodePublishSecretNamespace: kube-system
reclaimPolicy: Delete

Создание PVC, монтирование в Pod, запись и чтение - работает. Latency и throughput на синтетических тестах - не хуже чем с встроенным плагином, что логично: транспорт тот же, меняется только кто инициирует подключение.

Что не так гладко

Несколько моментов которые нужно иметь в виду.

Beta - это не production-ready в общем смысле. Спецификация CSI стабилизировалась, но конкретные плагины от вендоров - нет. У ceph-csi есть известные ограничения: не все фичи RBD поддержаны, imageFeatures надо указывать аккуратно - exclusive-lock и object-map вызывали проблемы на ядрах до 4.14.

Отладка стала сложнее. Раньше при проблемах с маунтом смотришь в логи kubelet на ноде. Теперь - в логи CSI node-плагина, attacher, provisioner. Уровней стало больше. Нужны нормальные алерты и агрегация логов - без этого разбирать что пошло не так будет дольше.

RBAC в 1.10 подтянули. В этом же релизе улучшили аудит RBAC и добавили NodeRestriction admission controller. Если вы использовали широкие node-права как workaround для чего-то - стоит пройтись по сервисным аккаунтам. У нас пара аккаунтов требовала пересмотра после обновления.

Где мы сейчас

На тестовом кластере всё выглядит работающим. На production пока не переходим - хотим дать ceph-csi поработать несколько недель под нагрузкой и посмотреть на edge cases: рестарт ноды с примонтированными томами, поведение при временной недоступности Ceph, пересоздание Pod-а с тем же PVC.

Встроенный in-tree плагин Ceph RBD никуда не делся - он продолжает работать в 1.10 так же как в 1.9. Спешить некуда. Но вектор понятен: CSI это тот путь по которому будет двигаться интеграция с хранилищами, и начинать с ним разбираться на тестовых кластерах - сейчас правильный момент.

Если у вас Kubernetes + Ceph и вы хотите поговорить про CSI-миграцию - обращайтесь.

Контакт

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

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