Русский
Русский
English
Статистика
Реклама

Практический пример подключения хранилища на базе Ceph в кластер Kubernetes

Container Storage Interface (CSI) это унифицированный интерфейс взаимодействия Kubernetes и систем хранения данных. Вкратце о нём мы уже рассказывали, а сегодня подробнее рассмотрим связку CSI и Ceph: покажем, как подключить хранилище Ceph к кластеру Kubernetes.
В статье приведены реальные, хотя и немного упрощённые для удобства восприятия примеры. Установку и настройку кластеров Ceph и Kubernetes не рассматриваем.


Вам интересно, как это работает?



Итак, у вас под рукой есть кластер Kubernetes, развернутый, к примеру, kubespray. Рядом работает кластер Ceph его можно также поставить, например, вот этим набором плейбуков. Надеюсь, не нужно упоминать, что для продакшена между ними должна быть сеть с пропускной способностью не менее 10 Гбит/с.


Если всё это у вас есть, поехали!


Сначала зайдем на одну из нод кластера Ceph и проверяем, что всё в порядке:


ceph healthceph -s

Далее тут же создадим пул для RBD дисков:


ceph osd pool create kube 32ceph osd pool application enable kube rbd

Переходим в кластер Kubernetes. Там первым делом установим Ceph CSI драйвер для RBD. Ставить будем, как и положено, через Helm.
Добавляем репозиторий с чартом, получаем набор переменных чарта ceph-csi-rbd:


helm repo add ceph-csi https://ceph.github.io/csi-chartshelm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml

Теперь нужно заполнить файл cephrbd.yml. Для этого узнаем ID кластера и IP-адреса мониторов в Ceph:


ceph fsid  # так мы узнаем clusterIDceph mon dump  # а так увидим IP-адреса мониторов

Полученные значения заносим в файл cephrbd.yml. Попутно включаем создание политик PSP (Pod Security Policies). Опции в разделах nodeplugin и provisioner уже есть в файле, их можно исправить так, как показано ниже:


csiConfig:  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"    monitors:      - "v2:172.18.8.5:3300/0,v1:172.18.8.5:6789/0"      - "v2:172.18.8.6:3300/0,v1:172.18.8.6:6789/0"      - "v2:172.18.8.7:3300/0,v1:172.18.8.7:6789/0"nodeplugin:  podSecurityPolicy:    enabled: trueprovisioner:  podSecurityPolicy:    enabled: true

Далее всё что нам остаётся установить чарт в кластер Kubernetes.


helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace

Отлично, RBD драйвер работает!
Создадим в Kubernetes новый StorageClass. Для этого снова потребуется немного поработать с Ceph.


Создаём нового пользователя в Ceph и выдаём ему права на запись в пул kube:


ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'

А теперь посмотрим ключ доступа всё там же:


ceph auth get-key client.rbdkube

Команда выдаст нечто подобное:


AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Занесём это значение в Secret в кластере Kubernetes туда, где нужен userKey:


---apiVersion: v1kind: Secretmetadata:  name: csi-rbd-secret  namespace: ceph-csi-rbdstringData:  # Значения ключей соответствуют имени пользователя и его ключу, как указано в  # кластере Ceph. ID юзера должен иметь доступ к пулу,  # указанному в storage class  userID: rbdkube  userKey: <user-key>

И создаём наш секрет:


kubectl apply -f secret.yaml

Далее нам нужен примерно такой манифест StorageClass:


---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:   name: csi-rbd-scprovisioner: rbd.csi.ceph.comparameters:   clusterID: <cluster-id>   pool: kube   imageFeatures: layering   # Эти секреты должны содержать данные для авторизации   # в ваш пул.   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret   csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret   csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret   csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd   csi.storage.k8s.io/fstype: ext4reclaimPolicy: DeleteallowVolumeExpansion: truemountOptions:  - discard

Нужно заполнить clusterID, который мы уже узнали командой ceph fsid, и применить этот манифест в кластере Kubernetes:


kubectl apply -f storageclass.yaml

Чтобы проверить работу кластеров в связке, создадим вот такой PVC (Persistent Volume Claim):


apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: rbd-pvcspec:  accessModes:  - ReadWriteOnce  resources:    requests:      storage: 1Gi  storageClassName: csi-rbd-sc

Сразу посмотрим, как Kubernetes создал в Ceph запрошенный том:


kubectl get pvckubectl get pv

Вроде бы всё отлично! А как это выглядит на стороне Ceph?
Получаем список томов в пуле и просматриваем информацию о нашем томе:


rbd ls -p kuberbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653  # тут, конечно же, будет другой ID тома, который выдала предыдущая команда

Теперь давайте посмотрим, как работает изменение размера тома RBD.
Изменяем размер тома в манифесте pvc.yaml до 2Gi и применяем его:


kubectl apply -f pvc.yaml

Подождём, пока изменения вступят в силу, и ещё раз посмотрим на размер тома.


rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653kubectl get pvkubectl get pvc

Видим, что размер у PVC не изменился. Чтобы узнать причину, можно запросить у Kubernetes описание PVC в формате YAML:


kubectl get pvc rbd-pvc -o yaml

А вот и проблема:


message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. type: FileSystemResizePending


То есть диск увеличился, а файловая система на нём нет.
Чтобы увеличить файловую систему, надо смонтировать том. У нас же созданный PVC/PV сейчас никак не используется.


Можем создать тестовый Pod, например вот так:


---apiVersion: v1kind: Podmetadata:  name: csi-rbd-demo-podspec:  containers:    - name: web-server      image: nginx:1.17.6      volumeMounts:        - name: mypvc          mountPath: /data  volumes:    - name: mypvc      persistentVolumeClaim:        claimName: rbd-pvc        readOnly: false

И теперь посмотрим на PVC:


kubectl get pvc

Размер изменился, всё в порядке.


В первой части мы работали с блочным устройством RBD (оно так и расшифровывается Rados Block Device), но так нельзя делать, если требуется одновременная работа с этим диском разных микросервисов. Для работы с файлами, а не с образом диска, намного лучше подходит CephFS.
На примере кластеров Ceph и Kubernetes настроим CSI и остальные необходимые сущности для работы с CephFS.


Получим значения из нужного нам нового Helm-чарта:


helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml

Снова нужно заполнить файл cephfs.yml. Как и ранее, помогут команды Ceph:


ceph fsidceph mon dump

Заполняем файл со значениями примерно так:


csiConfig:  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"    monitors:      - "172.18.8.5:6789"      - "172.18.8.6:6789"      - "172.18.8.7:6789"nodeplugin:  httpMetrics:    enabled: true    containerPort: 8091  podSecurityPolicy:    enabled: trueprovisioner:  replicaCount: 1  podSecurityPolicy:    enabled: true

Обратите внимание, что адреса мониторов указываются в простой форме address:port. Для монтирования cephfs на узле эти адреса передаются в модуль ядра, который ещё не умеет работать с протоколом мониторов v2.
Порт для httpMetrics (туда будет ходить Prometheus за метриками для мониторинга) мы меняем для того, чтобы он не конфликтовал с nginx-proxy, который устанавливается Kubesprayем. Вам это, возможно, не потребуется.


Устанавливаем Helm-чарт в кластер Kubernetes:


helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace

Переходим к хранилищу данных Ceph, чтобы создать там отдельного пользователя. В документации указано, что провизионеру CephFS необходимы права доступа администратора кластера. Но мы создадим отдельного пользователя fs с ограниченными правами:


ceph auth get-or-create client.fs mon 'allow r' mgr 'allow rw' mds 'allow rws' osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'

И сразу же посмотрим его ключ доступа, он нам пригодится далее:


ceph auth get-key client.fs

Создадим отдельные Secret и StorageClass.
Ничего нового, мы это уже видели на примере RBD:


---apiVersion: v1kind: Secretmetadata:  name: csi-cephfs-secret  namespace: ceph-csi-cephfsstringData:  # Необходимо для динамически создаваемых томов  adminID: fs  adminKey: <вывод предыдущей команды>

Применяем манифест:


kubectl apply -f secret.yaml

А теперь отдельный StorageClass:


---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: csi-cephfs-scprovisioner: cephfs.csi.ceph.comparameters:  clusterID: <cluster-id>  # Имя файловой системы CephFS, в которой будет создан том  fsName: cephfs  # (необязательно) Пул Ceph, в котором будут храниться данные тома  # pool: cephfs_data  # (необязательно) Разделенные запятыми опции монтирования для Ceph-fuse  # например:  # fuseMountOptions: debug  # (необязательно) Разделенные запятыми опции монтирования CephFS для ядра  # См. man mount.ceph чтобы узнать список этих опций. Например:  # kernelMountOptions: readdir_max_bytes=1048576,norbytes  # Секреты должны содержать доступы для админа и/или юзера Ceph.  csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret  csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs  csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret  csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs  csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret  csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs  # (необязательно) Драйвер может использовать либо ceph-fuse (fuse),   # либо ceph kernelclient (kernel).  # Если не указано, будет использоваться монтирование томов по умолчанию,  # это определяется поиском ceph-fuse и mount.ceph  # mounter: kernelreclaimPolicy: DeleteallowVolumeExpansion: truemountOptions:  - debug

Заполним тут clusterID и применим в Kubernetes:


kubectl apply -f storageclass.yaml

Проверка


Для проверки, как и в прошлом примере, создадим PVC:


---apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: csi-cephfs-pvcspec:  accessModes:    - ReadWriteMany  resources:    requests:      storage: 5Gi  storageClassName: csi-cephfs-sc

И проверим наличие PVC/PV:


kubectl get pvckubectl get pv

Если хочется посмотреть на файлы и каталоги в CephFS, можно примонтировать эту файловую систему куда-нибудь. Например, как показано ниже.


Сходим на одну из нод кластера Ceph и выполним такие действия:


# Точка монтированияmkdir -p /mnt/cephfs# Создаём файл с ключом администратораceph auth get-key client.admin >/etc/ceph/secret.key# Добавляем запись в /etc/fstab# !! Изменяем ip адрес на адрес нашего узлаecho "172.18.8.6:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev    0       2" >> /etc/fstabmount /mnt/cephfs

Конечно же, вот такое монтирование FS на ноде Ceph подходит исключительно для целей обучения, чем мы и занимаемся на наших курсах Слёрм. Не думаю, что кто-то станет это делать в продакшене, велик риск случайно затереть важные файлы.


Ну и напоследок давайте проверим, как в случае с CephFS обстоят дела с изменением размеров тома. Возвращаемся в Kubernetes и отредактируем наш манифест для PVC увеличим там размер, к примеру, до 7Gi.


Применим отредактированный файл:


kubectl apply -f pvc.yaml

Посмотрим на примонтированном каталоге, как изменилась квота:


getfattr -n ceph.quota.max_bytes <каталог-с-данными>

Для работы этой команды, возможно, вам потребуется установить в систему пакет attr.


Глаза боятся, а руки делают


С виду все эти заклинания и длинные манифесты YAML кажутся сложными, но на практике студенты Слёрма разбираются с ними довольно быстро.
В этой статье мы не углублялись в дебри для этого есть официальная документация. Если вас интересуют детали настройки хранилища Ceph совместно с кластером Kubernetes, помогут вот эти ссылки:


Общие принципы работы Kubernetes c томами
Документация по RBD
Интеграция RBD и Kubernetes с точки зрения Ceph
Интеграция RBD и Kubernetes с точки зрения CSI
Общая документация по CephFS
Интеграция CephFS и Kubernetes с точки зрения CSI


На курсе Слёрм Kubernetes База вы можете пойти ещё чуть дальше и развернуть в Kubernetes реальное приложение, которое будет использовать CephFS в качестве хранилища для файлов. Посредством GET/POST запросов вы сможете передавать файлы и получать их из Ceph.


А если вам больше интересно хранение данных, то записывайтесь на новый курс по Ceph. Пока идёт бета-тест, курс можно получить со скидкой и повлиять на его содержание.


Автор статьи: Александр Швалов, практикующий инженер Southbridge, Certified Kubernetes Administrator, автор и разработчик курсов Слёрм.

Источник: habr.com
К списку статей
Опубликовано: 18.09.2020 14:13:41
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании southbridge

Devops

Kubernetes

Хранение данных

Хранилища данных

Ceph

Rbd

Cephfs

Kubespray

Yaml

Tutorial

Обучение

Pvc/pv

Secret

Storageclass

Helm

Rados block device

Persistent volume claim

Pod security policies

Ceph csi драйвер

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru