Понимаем Container Storage Interface (в Kubernetes и не только)

от автора

Прим. перев.: о так называемых плагинах хранилищ «вне дерева» Kubernetes (Out-of-Tree CSI Volume Plugins) мы впервые рассказывали в своём обзоре релиза K8s 1.9, где эта фича появилась в статусе альфа-версии. Автор нового материала — Anoop Vijayan Maniankara (ведущий DevOps-инженер финской компании Tuxera) — собрал ключевые сведения об идеях и устройстве CSI, что помогает быстро познакомиться с новой концепцией, которая, как утверждают некоторые наши сотрудники, «будет the next big thing». Для более подробного и технического изучения CSI в конце статьи приведены полезные ссылки, среди которых я особенно выделю презентацию одного из авторов этой спецификации (Jie Yu). Но начать всё равно стоит с «общей картины»…

Container Storage Interface (CSI) — инициатива, призванная унифицировать интерфейс хранилищ, таких как Ceph, Portworx, NetApp и т.п., в системах оркестровки контейнеров: Kubernetes, Mesos, Docker Swarm, Cloud Foundry и других. Идея в том, чтобы реализация одного CSI производителем хранилища гарантированно работала со всеми этими системами.


Источник изображения: доклад про CSI от Jie Yu на CloudNativeCon EU 2018

Обратите внимание: в этой статье будет рассказано только о динамическом provisioning’е. Предварительно настроенные тома и flex-тома выходят за её рамки. Если хотите лучше разобраться, о чём пойдёт речь, стоит предварительно прочитать документацию Kubernetes. Кроме того, в статье не будет глубокого погружения в детали реализации CSI. Я представлю высокоуровневый обзор CSI и заложу основу для создания CSI-тома. И последнее: для примеров и ссылок на подробности используется информация для Kubernetes.

До того, как погрузиться в тему, важно также знать, что такое sidecar-контейнеры в Kubernetes. Они расширяют возможности основного контейнера (main), существуя в том же поде, разделяя хранилище и сеть.

На момент написания статьи (13 августа 2018 г.) компоненты CSI имели следующие версии:

До появления CSI

Первый релиз CSI — v0.1 — состоялся в декабре 2017 года. Конечно, сделать provisioning для внешнего хранилища в системах оркестровки можно было и до его появления. В случае Kubernetes за потребности в хранилищах отвечали плагины томов — volume plugins:

Как видно из картинки выше, такие плагины являются частью ядра системы оркестровки. Из-за этого возникали следующие проблемы, упомянутые в документе с архитектурой CSI:

  • разработка плагина тома плотно связана с релизами Kubernetes и зависима от них;
  • разработчики/сообщество Kubernetes ответственны за тестирование и поддержку всех плагинов вместо того, чтобы просто тестировать и поддерживать стабильный API для плагинов;
  • баги в плагинах томов могут уронить не только сам плагин, но и критичные компоненты Kubernetes;
  • плагины получают полные привилегии компонентов Kubernetes (kubelet и kube-controller-manager);
  • разработчики плагинов вынуждены публиковать исходный код плагина и не могут выбрать путь бинарников.

Понимаем CSI

Представляя CSI, команда Kubernetes выпустила внешние компоненты, не являющиеся частью ядра и предназначенные для взаимодействия с другими внешними компонентами, реализуемыми производителями. Между собой они общаются через сокеты домена с помощью gRPC.

Внешние компоненты Kubernetes

Они полностью реализуются и поддерживаются командой Kubernetes и расширяют действия Kubernetes вне Kubernetes. Производителям можно совсем не волноваться об особенностях их реализации. Состоят из трёх частей:

  • Driver registrar  — sidecar-контейнер, регистрирующий CSI-драйвер в kubelet и добавляющий NodeId драйвера в лейбл объекта узла в Kubernetes API. Для этого взаимодействует с сервисом CSI-драйвера Identity (подробнее о нём см. ниже — прим. перев.) и вызывает GetNodeId у CSI;
  • External provisioner  — sidecar-контейнер, наблюдающий за объектами PersistentVolumeClaim в Kubernetes API и вызывающий команды CreateVolume и DeleteVolume для endpoint’а драйвера;
  • External attacher  — sidecar-контейнер, наблюдающий за объектами VolumeAttachment в Kubernetes API и вызывающий команды ControllerPublish и ControllerUnpublish для endpoint’а драйвера.

Внешний компонент от производителя хранилища/третьей стороны

Специфичная для вендора реализация. Каждый производитель реализует необходимые API в рамках функций gRPC-сервиса. Например, реализация GCE PD или Ceph и т.п. Они тоже состоят из трёх компонентов:

  • CSI Identity  — преимущественно для идентификации плагина: убедиться в том, что он функционирует, вернуть базовую информацию о плагине;
    service Identity {   // вернуть версию и название плагина   rpc GetPluginInfo(GetPluginInfoRequest)     returns (GetPluginInfoResponse) {}   // сообщить, в состоянии ли плагин обслуживать интерфейс Controller   rpc GetPluginCapabilities(GetPluginCapabilitiesRequest)     returns (GetPluginCapabilitiesResponse) {}   // вызывается системой оркестровки, чтобы проверить, запущен ли плагин   rpc Probe (ProbeRequest)     returns (ProbeResponse) {} }

    (kubernetes-csi-identity.proto)

  • CSI Controller  отвечает за контролирование томов и управление ими: создание, удаление, присоединение/отсоединение, снапшоты и т.п.;
    service Controller {   // выполнить provisioning тома   rpc CreateVolume (CreateVolumeRequest)     returns (CreateVolumeResponse) {}        // удалить выделенный ранее том   rpc DeleteVolume (DeleteVolumeRequest)     returns (DeleteVolumeResponse) {}        // сделать том доступным на требуемом узле   rpc ControllerPublishVolume (ControllerPublishVolumeRequest)     returns (ControllerPublishVolumeResponse) {}        // сделать том недоступным на требуемом узле   rpc ControllerUnpublishVolume (ControllerUnpublishVolumeRequest)     returns (ControllerUnpublishVolumeResponse) {}    // например, может использоваться для одновременного чтения/записи с нескольких узлов   rpc ValidateVolumeCapabilities (ValidateVolumeCapabilitiesRequest)     returns (ValidateVolumeCapabilitiesResponse) {}    // вернуть все доступные тома   rpc ListVolumes (ListVolumesRequest)     returns (ListVolumesResponse) {}    // полная емкость доступного пространства в пуле   rpc GetCapacity (GetCapacityRequest)     returns (GetCapacityResponse) {}    // например, плагины могут не иметь реализации GetCapacity и Snapshotting   rpc ControllerGetCapabilities (ControllerGetCapabilitiesRequest)     returns (ControllerGetCapabilitiesResponse) {}    // сделать снапшот   rpc CreateSnapshot (CreateSnapshotRequest)     returns (CreateSnapshotResponse) {}    // удалить снапшот   rpc DeleteSnapshot (DeleteSnapshotRequest)     returns (DeleteSnapshotResponse) {}    // вывести список снапшотов   rpc ListSnapshots (ListSnapshotsRequest)     returns (ListSnapshotsResponse) {} }

    (kubernetes-csi-controller.proto)

  • CSI Node  отвечает за контролирование действий тома на узле Kubernetes.
    service Node {   // временно примонтировать том к staging-пути   rpc NodeStageVolume (NodeStageVolumeRequest)     returns (NodeStageVolumeResponse) {}    // отмонтировать том от staging-пути   rpc NodeUnstageVolume (NodeUnstageVolumeRequest)     returns (NodeUnstageVolumeResponse) {}    // примонтировать том из staging к целевому пути   rpc NodePublishVolume (NodePublishVolumeRequest)     returns (NodePublishVolumeResponse) {}    // отмонтировать том от целевого пути   rpc NodeUnpublishVolume (NodeUnpublishVolumeRequest)     returns (NodeUnpublishVolumeResponse) {}    // статистика по тому   rpc NodeGetVolumeStats (NodeGetVolumeStatsRequest)     returns (NodeGetVolumeStatsResponse) {}    // вернуть уникальный ID узла   rpc NodeGetId (NodeGetIdRequest)     returns (NodeGetIdResponse) {     option deprecated = true;   }    // вернуть возможности (capabilities) узла   rpc NodeGetCapabilities (NodeGetCapabilitiesRequest)     returns (NodeGetCapabilitiesResponse) {}    // схоже с NodeGetId   rpc NodeGetInfo (NodeGetInfoRequest)     returns (NodeGetInfoResponse) {} }

    (kubernetes-csi-node.proto)

Заключение

Появление CSI принесло очевидный плюс системам оркестровки и производителям хранилищ. К тому же, хорошо определённые интерфейсы помогают простой реализации и тестированию CSI как разработчикам, так и будущим системам оркестровки. Если вы решите начать реализацию своего CSI после прочтения этого материала, хорошей стартовой точкой станет статья «How to write a Container Storage Interface (CSI) plugin» от Fatih Arslan.

Ссылки на литературу

  1. Спецификация CSI;
  2. Sidecar-контейнеры в Kubernetes;
  3. Доклад про CSI от Jie Yu на KubeCon EU: CloudNativeCon EU 2018 вот здесь доступно видео с этого выступления — прим. перев.);
  4. Документ по архитектуре CSI;
  5. Актуальная документация по CSI от Kubernetes;
  6. Устаревшая документация по CSI от Kubernetes.

P.S. от переводчика

Читайте также в нашем блоге:


ссылка на оригинал статьи https://habr.com/post/424211/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *