Как использовать Ceph в кластере Kubernetes — настраиваем deployment с несколькими репликами
3
7579
14 августа 2020 15:07
14/08/2020
Visitors have accessed this post 7579 times.
Автор статьи — Андрей Трошин
День добрый, в этой статье хочу рассказать один из вариантов использования распределенной файловой системы Ceph в кластере Kubernetes.
Собственно, для чего это может пригодиться? Один из важных принципов в кластере Kubernetes — это постоянное распределение подов c репликами вашего приложения по нодам кластера. Проще говоря, поды прыгают с одной ноды на другую. Если приложение требует сохранения своего состояния (Stateful Service), то ему необходимо удовлетворить некоторые требования к хранилищу данных. Распределенная файловая система Ceph как раз и позволяет это сделать. А именно, обращение нескольких подов к одному тому, удобное масштабирование и отказоустойчивость.
Вроде бы в сети много мануалов на эту тему, но, как правило, они содержат лишь обрывки информации. А мне хотелось найти консолидированный материал — увы, такого мне не встретилось.
Поэтому я решил поделиться личным опытом. Поехали!
Наши вводные
Итак, у нас есть на руках кластер Ceph и кластер Kubernetes и стоит задача поднять deployment c несколькими репликами (несколько реплик — в нашем случае ключевое требование). Deployment будет содержать в себе nginx сервер в 2 репликах. Если curl -ом отправить в его сторону файл — он сохранит его на диск Ceph. Вот такое простое приложение.
Если посмотреть на эту задачу с точки зрения реализации – нам нужно выделить в ceph необходимые дисковые ресурсы и прокинуть их в кластер Kubernetes. Этот ресурс должен быть в режиме ReadWriteMany или коллективного доступа, так как иначе наш Deployment поднимет только одну реплику, остальные же в ожидании свободного диска работать не будут. А это не наша история.
Переходим к реализации
Ну что, теперь самое интересное! Общая схема того, что мы будем делать, — со всеми частями и их взаимосвязями.
Создаем Pool с именем kube.
ceph osd pool create kube 8 8
Теперь нам необходимы Client key и Admin key, которые позволят нам авторизоваться в Ceph со стороны кластера Kubernetes.
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
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 мониторов (ясное дело, тут у каждого будет свой вариант).
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 устанавливаем чарт.
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace
Тут есть один нюанс – нужно создать отдельный namespace ceph-csi-cephfs, (его мы будем использовать в дальнейшем при создании Secret).
Создаем secret
Теперь нам нужно авторизовать общение Kubernetes и ceph. Для этого мы и создавали в ceph admin key и client key. Используем в нашем secret admin key и созданный чуть выше отдельный namespace.
Посмотреть admin key можно:
ceph auth get-key client.admin
AQD9zu9ePGYqLhAAUV7aHgdETMxJv6ncrLsFow==
Манифест secret.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Required for dynamically provisioned volumes
adminID: admin
adminKey: AQD9zu9ePGYqLhAAUV7aHgdETMxJv6ncrLsFow==
Далее создаем secret.
kubectl create –f secret.yaml
Создаем Storageclass
Теперь самое интересное. Эта абстракция позволяет соединить через CSI файловую систему (в нашем случае ceph) c кластером Kubernetes. В Kubernetes может быть создано несколько storageclass, и каждый будет предоставлять дисковые ресурсы для кластера. В этом манифесте мы указываем свои clusterID и secret созданный нами ранее.
Манифест storageclass.yaml
---
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
Kubectl create –f storageclass.yaml
Создаем PVC
Далее у нас по плану создание PVC (PersistentVolumeClaim). PVC — это, по сути, запрос на дисковые ресурсы в кластере Kubernetes. Если ресурсы имеются, то автоматически создается PV (PersistentVolume) и его мы уже используем как том в нашем Deployment.
Из интересного тут:
- accessModes: ReadWriteMany (Многопользовательский доступ)
- storage: 5Gi (Запрашиваемый дисковый ресурс)
- storageClassName: csi-cephfs-sc (Ссылка на наш StorageClass)
Манифест pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-sc
Создаем PVC.
Kubectl create –f pvc.yaml
Создаем точку монтирования в кластере Kubernetes
Идем на одну из Worker node в кластере и создаем там точку монтирования.
mkdir -p /mnt/cephfs
Создаем файл с ключом администратора.
ceph auth get-key client.admin >/etc/ceph/secret.key
Редактируем fstab.
echo "IP Worker node:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev 0 2">>/etc/fstab
Монтируем.
mount /mnt/cephfs
Готово! Настройку файловой системы мы закончили. Теперь, используя PVC + PV, мы можем подключить дисковый ресурс в наш deployment.
Наш deployment достаточно прост и поднимает nginx сервер в двух репликах, настройки nginx находятся в configmap. Также монтируется каталог /data, который и есть ceph файловый ресурс, доступный всем подам в deployment.
Чтобы проверить наше приложение, отправьте на ip нашего сервиса файл, используя curl. Если у нас все получилось, файл упадет в каталог /data. А каталог /data, как вы помните, – это ресурсы ceph.
curl -i ip address/files/ -T test.txt
А что в итоге?
У нас получилось подружить кластер ceph и кластер Kubernetes. Теперь мы можем использовать дисковый ресурс в режиме RWO и запустить наше приложение в нескольких репликах с помощью deployment.
Пробуйте, пользуйтесь. А вопросы можно задать в комментариях.
От редакции
Если вам интересно посещать бесплатные онлайн-мероприятия по DevOps, Kubernetes, Docker, GitlabCI и др. и задавать вопросы в режиме реального времени, подключайтесь к каналу DevOps by REBRAIN.
*Анонсы мероприятий каждую неделю
Практикумы для специалистов по инфраструктуре и разработчиков — https://rebrainme.com.
Наш Youtube-канал — https://www.youtube.com/channel/UC6uIx64IFKMVmj12gKtSgBQ.
Агентство Fevlake, проектируем и поддерживаем IT-инфраструктуры с 2012 года — https://fevlake.com.