Thank you for reading this post, don't forget to subscribe!
у нас есть на руках кластер Ceph и кластер Kubernetes и стоит задача поднять deployment c несколькими репликами (несколько реплик — в нашем случае ключевое требование). Deployment будет содержать в себе nginx сервер в 2 репликах. Если curl -ом отправить в его сторону файл — он сохранит его на диск Ceph. Вот такое простое приложение.
Если посмотреть на эту задачу с точки зрения реализации – нам нужно выделить в ceph необходимые дисковые ресурсы и прокинуть их в кластер Kubernetes. Этот ресурс должен быть в режиме ReadWriteMany или коллективного доступа, так как иначе наш Deployment поднимет только одну реплику, остальные же в ожидании свободного диска работать не будут. А это не наша история.
Общая схема того, что мы будем делать, — со всеми частями и их взаимосвязями.
Создаем Pool с именем kube.
Теперь нам необходимы Client key и Admin key, которые позволят нам авторизоваться в Ceph со стороны кластера Kubernetes.
1 2 3 4 5 |
ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube' ceph auth get-key client.kube AQDMgvRet0DFKRAAq2FrkDDyC79RHvf96V0+ew== ceph auth get client.admin 2>&1 |grep "key = " |awk '{print $3'} AQD9zu2ePGYqFhAAUF7aHgdETMxJv6ncrLsFow== |
Этап подготовительных работ в ceph мы завершили.
Дальше переходим к Kubernetes и попробуем сделать в нем следующее:
- установить CSI driver;
- создать secret;
- создать Storageclass;
- создать PVC;
- создать точку монтирования;
- создать Deployment;
- создать Configmap.
Устанавливаем CSI driver
CSI (Container Storage Interface) позволяет Kubernetes подключать разные хранилища, например, ceph, Amazon S3 итд. Но из коробки его нет и поэтому его необходимо доставить в кластер.
Доставлять будем через helm чарт. Потому что стильно, модно, молодежно — и удобно, конечно. Добавляем репо и скачиваем себе cephfs.yml для настройки.
helm repo add ceph-csi — https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-cephfs >cephfs.yml
Файл cephfs.yaml позволяет сконфигурировать драйвер под ваш ceph. Смотрим cepf sid и IP мониторов. Эту информацию мы в дальнейшем внесем в cephfs.yaml
1 2 3 4 5 6 |
ceph sid bcd0d202-fba8-4352-b25d-75c89258d5ab ceph mon dump 192.168.0.4:6789 192.168.0.5:6789 192.168.0.6:6789 |
Ниже приведен пример откорректированного cephfs.yaml с учетом моего кластера. Ceph sid и IP мониторов (ясное дело, тут у каждого будет свой вариант).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 |
Остальные секции файла у меня остались без изменений — это уже тонкая настройка. В секции nodeplugin изменен containerPort (по дефолту — 8080), так как его часто используют другие компоненты Kubernetes и с этим могут быть проблемы.
После внесения изменений в cephfs.yaml устанавливаем чарт.
Тут есть один нюанс – нужно создать отдельный namespace ceph-csi-cephfs, (его мы будем использовать в дальнейшем при создании Secret).
Создаем secret
Теперь нам нужно авторизовать общение Kubernetes и ceph. Для этого мы и создавали в ceph admin key и client key. Используем в нашем secret admin key и созданный чуть выше отдельный namespace.
Посмотреть admin key можно:
1 2 |
ceph auth get-key client.admin AQD9zu9ePGYqLhAAUV7aHgdETMxJv6ncrLsFow== |
Манифест secret.yaml
1 2 3 4 5 6 7 8 9 10 |
--- apiVersion: v1 kind: Secret metadata: name: csi-cephfs-secret namespace: ceph-csi-cephfs stringData: # Required for dynamically provisioned volumes adminID: admin adminKey: AQD9zu9ePGYqLhAAUV7aHgdETMxJv6ncrLsFow== |
Далее создаем secret.
Создаем Storageclass
Теперь самое интересное. Эта абстракция позволяет соединить через CSI файловую систему (в нашем случае ceph) c кластером Kubernetes. В Kubernetes может быть создано несколько storageclass, и каждый будет предоставлять дисковые ресурсы для кластера. В этом манифесте мы указываем свои clusterID и secret созданный нами ранее.
Манифест storageclass.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
--- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: csi-cephfs-sc provisioner: cephfs.csi.ceph.com parameters: clusterID: 8a72cf06-87f6-432c-b057-35073bae8d5f # CephFS filesystem name into which the volume shall be created fsName: cephfs # (optional) Ceph pool into which volume data shall be stored # pool: cephfs_data # (optional) Comma separated string of Ceph-fuse mount options. # For eg: # fuseMountOptions: debug # (optional) Comma separated string of Cephfs kernel mount options. # Check man mount.ceph for mount options. For eg: # kernelMountOptions: readdir_max_bytes=1048576,norbytes # The secrets have to contain user and/or Ceph admin credentials. 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 # (optional) The driver can use either ceph-fuse (fuse) or # ceph kernelclient (kernel). # If omitted, default volume mounter will be used - this is # determined by probing for ceph-fuse and mount.ceph # mounter: kernel reclaimPolicy: Delete allowVolumeExpansion: true mountOptions: - debug |
Создаем storageclass
Создаем PVC
Далее у нас по плану создание PVC (PersistentVolumeClaim). PVC — это, по сути, запрос на дисковые ресурсы в кластере Kubernetes. Если ресурсы имеются, то автоматически создается PV (PersistentVolume) и его мы уже используем как том в нашем Deployment.
Из интересного тут:
- accessModes: ReadWriteMany (Многопользовательский доступ)
- storage: 5Gi (Запрашиваемый дисковый ресурс)
- storageClassName: csi-cephfs-sc (Ссылка на наш StorageClass)
Манифест pvc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 |
--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: csi-cephfs-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: csi-cephfs-sc |
Создаем PVC.
Создаем точку монтирования в кластере Kubernetes
Идем на одну из Worker node в кластере и создаем там точку монтирования.
Создаем файл с ключом администратора.
Редактируем fstab.
Монтируем.
Готово! Настройку файловой системы мы закончили. Теперь, используя PVC + PV, мы можем подключить дисковый ресурс в наш deployment.
Наш deployment достаточно прост и поднимает nginx сервер в двух репликах, настройки nginx находятся в configmap. Также монтируется каталог /data, который и есть ceph файловый ресурс, доступный всем подам в deployment.
Чтобы проверить наше приложение, отправьте на ip нашего сервиса файл, используя curl. Если у нас все получилось, файл упадет в каталог /data. А каталог /data, как вы помните, – это ресурсы ceph.