Visitors have accessed this post 9027 times.

Как использовать Ceph в кластере Kubernetes — настраиваем deployment с несколькими репликами

3
0
9027
14 августа 2020 15:07
Автор: Rebrain Me
Kubernetes

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.

Комментарии (3)
Введено символов из возможных
Не отвечать

Вам также может понравится

NMap
array(1) { [0]=> object(WP_Term)#11559 (16) { ["term_id"]=> int(6) ["name"]=> string(5) "Linux" ["slug"]=> string(5) "linux" ["term_group"]=> int(0) ["term_taxonomy_id"]=> int(6) ["taxonomy"]=> string(8) "category" ["description"]=> string(0) "" ["parent"]=> int(0) ["count"]=> int(28) ["filter"]=> string(3) "raw" ["cat_ID"]=> int(6) ["category_count"]=> int(28) ["category_description"]=> string(0) "" ["cat_name"]=> string(5) "Linux" ["category_nicename"]=> string(5) "linux" ["category_parent"]=> int(0) } } Linux

Автор - Сергей Попов
Часть 1
Предистория
Наверняка, каждый смотрел фильмы про хакеров и задавался вопросом: откуда они знают, какие порты открыты в системе? Или как узнать, какие приложения запущены на сервере, не спрашивая об этом администратора? Вы можете сделать все это и даже больше вместе с небольшим инструментом под названием Nmap....

36
0
4 сентября 2020
Linux like One-c
array(1) { [0]=> object(WP_Term)#976 (16) { ["term_id"]=> int(6) ["name"]=> string(5) "Linux" ["slug"]=> string(5) "linux" ["term_group"]=> int(0) ["term_taxonomy_id"]=> int(6) ["taxonomy"]=> string(8) "category" ["description"]=> string(0) "" ["parent"]=> int(0) ["count"]=> int(28) ["filter"]=> string(3) "raw" ["cat_ID"]=> int(6) ["category_count"]=> int(28) ["category_description"]=> string(0) "" ["cat_name"]=> string(5) "Linux" ["category_nicename"]=> string(5) "linux" ["category_parent"]=> int(0) } } Linux

Автор статьи - Сергей Попов
Предистория
Мало кто из инфраструктурщиков на просторах России не сталкивался с «Великим и Ужасным» ОДИН-ЭС. Многие после этой встречи безвозвратно уходят в мир *nix, чтобы никогда больше не пересекаться с ним, и не жалеют об этом, остальным приходится устанавливать, обслуживать и поддерживать этого монстра многие...

0
8
3 августа 2020
Как и для чего я автоматизировал проверку количества shapshot’ов
array(1) { [0]=> object(WP_Term)#11559 (16) { ["term_id"]=> int(7) ["name"]=> string(6) "DevOps" ["slug"]=> string(6) "devops" ["term_group"]=> int(0) ["term_taxonomy_id"]=> int(7) ["taxonomy"]=> string(8) "category" ["description"]=> string(0) "" ["parent"]=> int(0) ["count"]=> int(19) ["filter"]=> string(3) "raw" ["cat_ID"]=> int(7) ["category_count"]=> int(19) ["category_description"]=> string(0) "" ["cat_name"]=> string(6) "DevOps" ["category_nicename"]=> string(6) "devops" ["category_parent"]=> int(0) } } DevOps

Автор - Максим Куприенко
Ищем корень зла
Как-то я столкнулся с интересной задачей. А именно - при работе с системой виртуализации VMware vSphere иногда возникала следующая проблема: для некоторых виртуальных машин выполнение штатных операций (старт/стоп/перезапуск) стало занимать гораздо больше времени, а также падала производительность самой...

4
0
28 августа 2020