Автор - Сергей Попов
Часть 1
Предистория
Наверняка, каждый смотрел фильмы про хакеров и задавался вопросом: откуда они знают, какие порты открыты в системе? Или как узнать, какие приложения запущены на сервере, не спрашивая об этом администратора? Вы можете сделать все это и даже больше вместе с небольшим инструментом под названием Nmap....
Как использовать Ceph в кластере Kubernetes — настраиваем deployment с несколькими репликами
Visitors have accessed this post 9027 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.
Вам также может понравится
Автор статьи - Сергей Попов
Предистория
Мало кто из инфраструктурщиков на просторах России не сталкивался с «Великим и Ужасным» ОДИН-ЭС. Многие после этой встречи безвозвратно уходят в мир *nix, чтобы никогда больше не пересекаться с ним, и не жалеют об этом, остальным приходится устанавливать, обслуживать и поддерживать этого монстра многие...
Автор - Максим Куприенко
Ищем корень зла
Как-то я столкнулся с интересной задачей. А именно - при работе с системой виртуализации VMware vSphere иногда возникала следующая проблема: для некоторых виртуальных машин выполнение штатных операций (старт/стоп/перезапуск) стало занимать гораздо больше времени, а также падала производительность самой...