Skip to main content

Как работает CSI драйвер?

Объекты: CSIDriver, volumeattachment, pvc, pv

losted in ~ λ kubectl api-resources | grep stora                                                                                                                            CHG:98% 00:20:11
csidrivers                                       storage.k8s.io/v1                 false        CSIDriver
csinodes                                         storage.k8s.io/v1                 false        CSINode
csistoragecapacities                             storage.k8s.io/v1                 true         CSIStorageCapacity
storageclasses                      sc           storage.k8s.io/v1                 false        StorageClass
volumeattachments                                storage.k8s.io/v1                 false        VolumeAttachment


Статья написана на основе собственного опыта и документации. Никакие нейронки не использовались. Посмотрим, хорошо это или плохо.

Все мы когда-то сталкивались с дилеммой - как сохранить данные. На помощь обычно приходит csi драйвер, но как он работает? Эта статья должна помочь разработчикам и разъяснить некоторые моменты пользователям.

CSI (Container Storage Interface) это довольно гибкий интерфейс для предоставления хранилища. В официальной документации подробно расписаны все возможности и архитектура работы, а на гитхабе есть компоненты и много проектов от CSI-SIG. Зачастую интерес пользователя останавливается на нескольких свойствах драйверов - хранилище блочное или файловое, RWX (ReadWriteMany - когда можно подключать один том к нескольким подам) или RWO (ReadWriteOnce - один том на один под), но на самом деле CSI предоставляет больше возможностей.

Из чего состоит CSI драйвер?

Зачастую CSI драйвер состоит из sidecar контейнеров и вашего кода, которые общаются через Unix сокет по Grpc протоколу [ref]. Это сделано чтобы облегчить жизнь разработчикам - сосредоточиться на написании своей логики, а не взаимодействия с kubernetes. 

 

изображение.png

 

С чего все начинается

Вот вы поставили свой любимый CSI драйвер, например https://github.com/kubernetes-csi/csi-driver-nfs , он поставился и вы побежали создавать PVC. А что произошло под капотом?

Все начинается с объекта CSIDriver (apiversion буду пропускать - он везде "storage.k8s.io/v1"). Без него приложение в поде не сможет зарегистрироваться в кубернетисе. Какие интересные поля в нем есть? Выведем только spec, так как в блоке metadata интересных полей нет.

~ kubectl explain csidrivers.spec --recursive
GROUP:      storage.k8s.io
KIND:       CSIDriver
VERSION:    v1

FIELD: spec <CSIDriverSpec>


DESCRIPTION:
    spec represents the specification of the CSI Driver.
    CSIDriverSpec is the specification of a CSIDriver.
    
FIELDS:
  attachRequired        <boolean>
  fsGroupPolicy <string>
  podInfoOnMount        <boolean>
  requiresRepublish     <boolean>
  seLinuxMount  <boolean>
  storageCapacity       <boolean>
  tokenRequests <[]TokenRequest>
    audience    <string> -required-
    expirationSeconds   <integer>
  volumeLifecycleModes  <[]string>

С первого поля начинается погружение в логику CSI. Поле attachRequired говорит, нужно ли посылать запрос на монтирование к воркеру диска.

Здесь наверное надо обратиться к типовому устройству CSI драйвера. Что это вообще такое? Зачастую это приложение из 2х компонентов: controller, который взаимодействует с внешней апишкой, например апи облака, чтобы выполнять действия которые , и node - daemonset запущенный на каждом воркере, зачастую он занимается форматированием и монтированием диска к нужному пути (к пути внутри пода)

Оба эти приложения - GRPC службы, которые отвечают на запросы kubelet через unix-сокет по пути /var/lib/kubelet/plugins/"CSIDriver.metadata.name"/controller/csi/csi.sock.

Так что же делает attachRequired? Он говорит кубернетису, что вызывать функции контроллера для монтирования/отмонтирования диска не требуется. Это может быть полезно если у вас NFS и обращаться перед монтироваием банально некуда - том можно сразу же монтировать на ноде.

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

Параметр fsGroupPolicy