Container Storage Interface (CSI) – це уніфікований інтерфейс взаємодії Kubernetes та систем зберігання даних. Коротко про нього ми вже
У статті наведено реальні, хоч і трохи спрощені для зручності сприйняття приклади. Встановлення та налаштування кластерів Ceph та Kubernetes не розглядаємо.
Вам цікаво як це працює?
Отже, у вас під рукою є кластер Kubernetes, розгорнутий, наприклад,
Якщо все це у вас є, поїхали!
Спочатку зайдемо на одну з нід кластера Ceph і перевіряємо, що все гаразд:
ceph health
ceph -s
Далі тут же створимо пул для дисків RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbd
Переходимо до кластера Kubernetes. Там насамперед встановимо Ceph CSI драйвер для RBD. Ставитимемо, як і належить, через Helm.
Додаємо репозиторій із чартом, отримуємо набір змінних чарту ceph-csi-rbd:
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml
Тепер необхідно заповнити файл cephrbd.yml. Для цього дізнаємося ID кластера та IP-адреси моніторів у Ceph:
ceph fsid # так мы узнаем clusterID
ceph mon dump # а так увидим IP-адреса мониторов
Отримані значення заносимо у файл cephrbd.yml. Принагідно включаємо створення політик PSP (Pod Security Policies). Опції у розділах nodeplugin и провізор вже є у файлі, їх можна виправити так, як показано нижче:
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: true
provisioner:
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 та видаємо йому права на запис у пул Кубе:
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: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Значения ключей соответствуют имени пользователя и его ключу, как указано в
# кластере Ceph. ID юзера должен иметь доступ к пулу,
# указанному в storage class
userID: rbdkube
userKey: <user-key>
І створюємо наш секрет:
kubectl apply -f secret.yaml
Далі нам потрібний приблизно такий маніфест StorageClass:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
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: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard
Потрібно заповнити clusterID, який ми вже дізналися командою ceph fsid, і застосувати цей маніфест у кластері Kubernetes:
kubectl apply -f storageclass.yaml
Щоб перевірити роботу кластерів у зв'язці, створимо такий PVC (Persistent Volume Claim):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc
Відразу подивимося, як Kubernetes створив у Ceph запитаний том:
kubectl get pvc
kubectl get pv
Начебто все чудово! А як це виглядає на боці Ceph?
Отримуємо список томів у пулі та переглядаємо інформацію про наш том:
rbd ls -p kube
rbd -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-6235e7640653
kubectl get pv
kubectl get pvc
Бачимо, що розмір PVC не змінився. Щоб дізнатися про причину, можна запитати у Kubernetes опис PVC у форматі YAML:
kubectl get pvc rbd-pvc -o yaml
А ось і проблема:
message: Використовуйте для використання (re-)start a під кінець файлу системи, щоб переглянути обсяг на node. type: FileSystemResizePending
Тобто диск збільшився, а файлова система на ньому немає.
Щоб збільшити файлову систему, необхідно змонтувати том. У нас створений PVC/PV зараз ніяк не використовується.
Можемо створити тестовий Pod, наприклад:
---
apiVersion: v1
kind: Pod
metadata:
name: csi-rbd-demo-pod
spec:
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 fsid
ceph 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: true
provisioner:
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: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Необходимо для динамически создаваемых томов
adminID: fs
adminKey: <вывод предыдущей команды>
Застосовуємо маніфест:
kubectl apply -f secret.yaml
А тепер – окремий StorageClass:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
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: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debug
Заповнимо тут clusterID і застосуємо в Kubernetes:
kubectl apply -f storageclass.yaml
Перевірка
Для перевірки, як і в попередньому прикладі, створимо PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-sc
І перевіримо наявність PVC/PV:
kubectl get pvc
kubectl 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/fstab
mount /mnt/cephfs
Звичайно ж, ось таке монтування FS на ноді Ceph підходить виключно для цілей навчання, ніж ми і займаємось на наших
Ну і наостанок давайте перевіримо, як у випадку з CephFS справи зі зміною розмірів тому. Повертаємось у Kubernetes і відредагуємо наш маніфест для PVC – збільшимо там розмір, наприклад, до 7Gi.
Застосуємо відредагований файл:
kubectl apply -f pvc.yaml
Подивимося на примонтованому каталозі, як змінилася квота:
getfattr -n ceph.quota.max_bytes <каталог-с-данными>
Для роботи цієї команди, можливо, вам знадобиться встановити в систему пакет атр.
Очі бояться, а руки роблять
На вигляд усі ці заклинання та довгі маніфести YAML здаються складними, але на практиці студенти Слерма розбираються з ними досить швидко.
У цій статті ми не заглиблювались у нетрі — для цього є офіційна документація. Якщо вас цікавлять деталі налаштування сховища Ceph спільно з кластером Kubernetes, допоможуть ці посилання:
На курсі Слерм
А якщо вам цікавіше зберігання даних, то записуйтесь на
Автор статті: Олександр Швалов, практикуючий інженер
Джерело: habr.com