Интерфейсът за съхранение на контейнери (CSI) е унифициран интерфейс между Kubernetes и системите за съхранение. Вече говорихме за това накратко , а днес ще разгледаме по-отблизо комбинацията от CSI и Ceph: ще покажем как към клъстера Kubernetes.
Статията предоставя реални, макар и леко опростени примери за по-лесно възприемане. Ние не обмисляме инсталиране и конфигуриране на Ceph и Kubernetes клъстери.
Чудите ли се как работи?

И така, имате Kubernetes клъстер на една ръка разстояние, разгърнат, например, . Наблизо работи клъстер Ceph - можете също да го инсталирате, например, с това . Надявам се няма нужда да споменавам, че за производство между тях трябва да има мрежа с честотна лента поне 10 Gbit/s.
Ако имате всичко това, да вървим!
Първо, нека отидем до един от клъстерните възли на 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 работи!
Нека създадем нов StorageClass в Kubernetes. Това отново изисква малко работа с 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 YAML описание на PVC:
kubectl get pvc rbd-pvc -o yamlЕто го проблема:
съобщение: Изчакване потребителят да (ре)стартира под, за да завърши преоразмеряването на тома на файловата система на възела. тип: FileSystemResizePending
Тоест дискът е нараснал, но файловата система на него не.
За да увеличите файловата система, трябва да монтирате тома. У нас създаденото PVC/PV в момента не се използва по никакъв начин.
Можем да създадем тестов под, например по този начин:
---
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Моля, обърнете внимание, че адресите на монитора са посочени в простата форма адрес:порт. За да монтирате 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 манифести изглеждат сложни на пръв поглед, но на практика учениците на Slurm ги овладяват доста бързо.
В тази статия не навлязохме дълбоко в джунглата - има официална документация за това. Ако се интересувате от подробности за настройката на Ceph хранилище с Kubernetes клъстер, тези връзки ще ви помогнат:
На курса Slurm можете да отидете малко по-далеч и да разположите истинско приложение в Kubernetes, което ще използва CephFS като хранилище на файлове. Чрез заявки GET/POST ще можете да прехвърляте файлове към и да ги получавате от Ceph.
И ако се интересувате повече от съхранение на данни, тогава се регистрирайте за . Докато тече бета тестът, курсът може да бъде получен с отстъпка и можете да повлияете на съдържанието му.
Автор на статията: Александър Швалов, практикуващ инженер , сертифициран Kubernetes администратор, автор и разработчик на курсове по Slurm.
Източник: www.habr.com
