Здравствуйте, уважаемые читатели Хабра!
В прошлой публикации я рассказал, как развернуть отказоустойчивый кластер Kubernetes. Но дело в том, что в Kubernetes удобно деплоить stateless приложения, которым не требуется сохранять свое состояние или работать с данными. Но в большинстве случаев нам требуются сохранять данные и не терять их при рестартах подов.
Для этих целей в Kubernetes используются тома (volume). Когда мы работаем с облачными решениями Kubernetes, то проблем особо нет. Нам лишь нужно у Google, Amazon или иного облачного провайдера заказать требуемый объем и, руководствуясь документаций , подключить полученные тома к подам.
Когда же мы имеем дело с bare metal, тут дела обстоят немного сложнее. Сегодня я хочу рассказать об одном из решений основанном на использовании ceph.
В данной публикации я расскажу:
Введение
Для начала я хотел бы объяснить для кого будет полезна эта статья. Во первых, для читателей, которые разворачивали кластер по моей первой публикации, чтобы продолжать выстраивать микросервисную архитектуру. Во вторых, для людей, которые хотят попробовать самостоятельно развернуть кластер ceph и оценить его работу.
В данной публикации я не буду затрагивать тему планирования кластера под какие либо нужды, я лишь расскажу общие принципы и понятия. Не буду углублятся в «тюнинг» и глубокую настройку, на эту тему есть много публикаций, в том числе и на хабре. Статья будет носить более ознакомительный характер, но при этом позволит получить рабочее решение, которое Вы в дальнейшем сможете адаптировать под Ваши нужды.
- Cписок хостов, ресурсы хостов, версии ОС и ПО
- Структура кластра ceph
- Настройка нод кластера перед установкой
- Установка ceph-deploy
- Создание кластера ceph
- Настройка сети
- Установка пакетов ceph
- Установка и инициализация мониторов
- Добавление OSD
- Подключение ceph к kubernetes
- Создание пула данных
- Создание доступа и ключей
- Создание client secret
- Деплой ceph rbd provisioner
- Создание storage class
- Тест работы связки kubernetes + ceph
- Список материалов используемых при подготовке статьи
Список хостов и системные требования
Name | IP адрес | Comment |
---|---|---|
ceph01-test | 10.73.88.52 | ceph-node01 |
ceph02-test | 10.73.88.53 | ceph-node02 |
ceph03-test | 10.73.88.54 | ceph-node03 |
При написании статьи я использую виртуальные машины вот такой конфигурации
На каждой установлена ОС Debian 9.5. Это тестовые машины, в каждой два диска, первый под ОС, второй для OSD цефа.
Разворачивать кластер я буду через утилиту ceph-deploy. Можно разворачивать кластер ceph и в ручном режиме, все шаги описаны в документации, но целью данной статьи является рассказать, как быстро можно развернуть ceph и начать использовать его в kubernetes.
Ceph довольно прожорлив к ресурсам особенно к оперативной памяти. Для хорошей скорости желательно использовать ssd диски.
Более подробно про требования можно почитать в официальной документации ceph
Структура кластра ceph
MON
Монитор — это демон, выполняющий роль координатора, с которого начинается кластер. Как только у нас появляется хотя бы один рабочий монитор, у нас появляется Ceph-кластер. Монитор хранит информацию о здоровье и состоянии кластера, обмениваясь различными картами с другими мониторами. Клиенты обращаются к мониторам, чтобы узнать, на какие OSD писать/читать данные. При разворачивании нового хранилища, первым делом создается монитор (или несколько). Кластер может прожить на одном мониторе, но рекомендуется делать 3 или 5 мониторов, во избежание падения всей системы по причине падения единственного монитора. Главное, чтобы количество оных было нечетным, дабы избежать ситуаций раздвоения сознания (split-brain). Мониторы работают в кворуме, поэтому если упадет больше половины мониторов, кластер заблокируется для предотвращения рассогласованности данных.
MGR
Менеджер Ceph демон работает вместе с демоном монитора, чтобы обеспечить дополнительный контроль.
С версии 12.x демон ceph-mgr стал необходим для нормальной работы.
Если демон mgr не запущен, вы увидите предупреждение об этом.
OSD (Object Storage Device)
OSD — это юнит хранилища, который хранит сами данные и обрабатывает запросы клиентов, обмениваясь данными с другими OSD. Обычно это диск. И обычно за каждый OSD отвечает отдельный OSD-демон, который может запускаться на любой машине, на которой установлен этот диск.
На каждой машине нашего кластера будут работать все три демона. Соответственно, демоны монитора и менеджера как служебные, и демон OSD для одного диска нашей виртуальной машины.
Настройка нод кластера перед установкой
В документации ceph указана следующая схема работы:
Я буду работать с первой ноды кластера ceph01-test она же и будет Admin Node, на ней же будут конфигурационные файлы для утилиты ceph-deploy. Для корректной работы утилиты ceph-deploy все узлы кластера должны быть доступны по ssh c Admin node. Я для удобства пропишу в hosts короткие имена для кластера
10.73.88.52 ceph01-test 10.73.88.53 ceph02-test 10.73.88.54 ceph03-tset
И скопирую ключи на остальные хосты. Все команды я буду выполнять из под root.
ssh-copy-id ceph02-test ssh-copy-id ceph03-test
Установка ceph-deploy
Первым шагом установим ceph-deploy на машине ceph01-test
wget -q -O- 'https://download.ceph.com/keys/release.asc' | apt-key add -
Далее нужно выбрать релиз, который Вы хотите ставить. Но тут возникают сложности, в настоящее время ceph для ОС Debian поддерживают только пакеты luminous.
Если вы хотите поставить более свежий релиз то придется воспользоваться зеркалом, например
https://mirror.croit.io/debian-mimic/dists/
Добавляем репозиторий с mimic на всех трех нодах
apt install curl apt-transport-https -y curl https://mirror.croit.io/keys/release.gpg > /usr/share/keyrings/croit-signing-key.gpg echo 'deb [signed-by=/usr/share/keyrings/croit-signing-key.gpg] https://mirror.croit.io/debian-mimic/ stretch main' > /etc/apt/sources.list.d/croit-ceph.list apt update apt install ceph-deploy
Если Вам достаточно luminous то можно воспользоваться официальными репозиториями
echo deb https://download.ceph.com/debian-luminous/ $(lsb_release -sc) main | tee /etc/apt/sources.list.d/ceph.list apt-transport-https apt update apt install ceph-deploy
Так же установим NTP на всех трех нодах.
We recommend installing NTP on Ceph nodes (especially on Ceph Monitor nodes) to prevent issues arising from clock drift.
apt install ntp
Создание кластера ceph
Создадим каталог для конфиг файлов и файлов ceph-deploy
mkdir my-cluster cd my-cluster
Создадим конфиг нового кластер, при создании укажем что в нашем кластере будет три монитора
ceph-deploy new ceph01-test ceph02-test ceph03-test
Настройка сети
Теперь важный момент, настало время поговорить о сети для ceph. Ceph для работы использует две сети public network и cluster network
Как видно из схемы public network это уровень пользователя и приложений, а cluster network это сеть по которой происходит репликация данных.
Очень желательно отделять эти две сети друг от друга. Также скорость сети cluster network желательна не меньше 10 Gb.
Конечно, можно все держать в одной сети. Но это черевато тем, что как только возрастет объем репликаций между OSD, например, при падении или добавлении новых OSD (дисков), то нагрузка на сеть ОЧЕНЬ сильно возрастет. Так что скорость и стабильность вашей инфраструктуры, будет сильно зависеть от сети используемой ceph.
На моем кластере виртуализации к сожалению нет отдельной сети, и я буду использовать общий сегмент сети.
Настройка сети для кластера производится через конфиг файл, который мы сгенерировали предыдущей командой.
/my-cluster# cat ceph.conf [global] fsid = 2e0d92b0-e803-475e-9060-0871b63b6e7f mon_initial_members = ceph01-test, ceph02-test, ceph03-test mon_host = 10.73.88.52,10.73.88.53,10.73.88.54 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx
Как мы видим цеф деплой не создал нам настройки сети по умолчанию, по этому я добавлю в конфиг в раздел global параметр public network = {public-network/netmask}. Моя сеть 10.73.0.0/16 по этому после добавления мой конфиг будет выглядеть следующим образом
[global] fsid = 2e0d92b0-e803-475e-9060-0871b63b6e7f mon_initial_members = ceph01-test, ceph02-test, ceph03-test mon_host = 10.73.88.52,10.73.88.53,10.73.88.54 public network = 10.73.0.0/16 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx
Если Вы хотите отделить сеть cluster от public, то добавьте параметр cluster network = {cluster-network/netmask}
Более подробно про сети можно почитать в документации
Установка пакетов ceph
C помощью ceph-deploy установим все нужные нам пакеты ceph на наши три ноды.
Для этого на ceph01-test выполним
Если версия mimic то
ceph-deploy install --release mimic ceph01-test ceph02-test ceph03-test
Если версия luminous то
ceph-deploy install --release luminous ceph01-test ceph02-test ceph03-test
И подождем пока все установится.
Установка и инициализация мониторов
После того как все пакеты установлены, мы созданим и инициируем мониторы нашего кластера.
C ceph01-test выполняем следующее
ceph-deploy mon create-initial
В процессе будут созданы мониторы, запущены демоны, также ceph-deploy проверит quorum.
Теперь раскидаем конфиги по нодам кластера.
ceph-deploy admin ceph01-test ceph02-test ceph03-test
И проверим статус нашего кластера, если Вы все сделали правильно то статус должен быть
HEALTH_OK
~/my-cluster# ceph status cluster: id: 2e0d92b0-e803-475e-9060-0871b63b6e7f health: HEALTH_OK services: mon: 3 daemons, quorum ceph01-test,ceph02-test,ceph03-test mgr: no daemons active osd: 0 osds: 0 up, 0 in data: pools: 0 pools, 0 pgs objects: 0 objects, 0 B usage: 0 B used, 0 B / 0 B avail pgs:
Создадим mgr
ceph-deploy mgr create ceph01-test ceph02-test ceph03-test
И еще раз проверим статус
ceph -s
Должна появится строчка
mgr: ceph01-test(active), standbys: ceph02-test, ceph03-test
Запишем конфиг на все хосты кластера
ceph-deploy admin ceph01-test ceph02-test ceph03-test
Добавление OSD
В данный момент мы имеем работающий кластер, но в нем еще нет дисков (osd в терминологии ceph) для хранения информации.
OSD можно добавить следующей командой (общий вид)
ceph-deploy osd create --data {device} {ceph-node}
В моем тестовом стенду под osd выделен disk /dev/sdb, по этому в моем случае команды будут следующие
ceph-deploy osd create --data /dev/sdb ceph01-test ceph-deploy osd create --data /dev/sdb ceph02-test ceph-deploy osd create --data /dev/sdb ceph03-test
Проверим что все OSD работают
ceph -s
Вывод
cluster: id: 2e0d92b0-e803-475e-9060-0871b63b6e7f health: HEALTH_OK services: mon: 3 daemons, quorum ceph01-test,ceph02-test,ceph03-test mgr: ceph01-test(active) osd: 3 osds: 3 up, 3 in
Так же можете попробовать полезные команды для OSD
ceph osd df ID CLASS WEIGHT REWEIGHT SIZE USE AVAIL %USE VAR PGS 0 hdd 0.00490 1.00000 5.0 GiB 1.0 GiB 4.0 GiB 20.05 1.00 0 1 hdd 0.00490 1.00000 5.0 GiB 1.0 GiB 4.0 GiB 20.05 1.00 0 2 hdd 0.00490 1.00000 5.0 GiB 1.0 GiB 4.0 GiB 20.05 1.00 0 TOTAL 15 GiB 3.0 GiB 12 GiB 20.05
и
ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.01469 root default -3 0.00490 host ceph01-test 0 hdd 0.00490 osd.0 up 1.00000 1.00000 -5 0.00490 host ceph02-test 1 hdd 0.00490 osd.1 up 1.00000 1.00000 -7 0.00490 host ceph03-test 2 hdd 0.00490 osd.2 up 1.00000 1.00000
Если все ОК, то мы имеем работоспособный кластер ceph. В следующей части я расскажу как использовать ceph с kubernetes
Подключение ceph к kubernetes
К сожалению, я не смогу в рамках данной статьи подробно рассказать про работу томов Kubernetes, поэтому попробую уложиться в один абзац.
Для работы с томами данных данных Kubernetes использует storage classes, для каждого storage class есть свой provisioner, можно рассматривать его как некий «драйвер» для работы с различными томами хранения данных. Полный список который поддерживает kubernetes можно посмотреть в официальной документации.
В самом Kubernetes так же есть поддержка работы с rbd, но в официальном образе kube-controller-manager нет установленного клиента rbd, поэтому нужно использовать другой образ.
Я не пробовал использовать второй способ.
Для того что бы наш кластер смог работать с томами на ceph, нам нужно:
в кластере Сeph:
- создать pool данных в кластере ceph
- создать клиента и ключ доступа до пула данных
- получить сeph admin secret
в кластере Kubernetes:
- создать сeph admin secret
- создать secret c ключом клиента ceph
- установить ceph rbd provisioner или изменить образ kube-controller-manager на образ который поддерживает rbd
- создать storage class
- установить ceph-common на воркер нодах kubernetes
Создание пула данных
В кластере ceph создадим pool для томов kubernetes
ceph osd pool create kube 8 8
Тут я сделаю небольшое пояснение, цифры 8 8 в конце это количество pg и pgs. Эти значения зависят от размера Вашего кластера ceph. Есть специальные калькуляторы которые рассчитывают количество pg и pgs, например официальный от ceph
Для начала я рекомендую оставить по умолчанию, если что в будущем это количество можно увеличить (уменьшить можно только с версии Nautilus).
Создание клиента для пула данных
Создадим клиента для нового пула
ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube'
Получим ключ для клиента, в дальнейшем он понадобится нам для создания secret kubernetes
ceph auth get-key client.kube AQDd5aldka5KJRAAkpWTQYUMQi+5dfGDqSyxkg==
Получение ключа админа
И получим админский ключ
ceph auth get client.admin 2>&1 |grep "key = " |awk '{print $3'} AQAv+Itdx4DwKBAAKVhWRS3+eEPqV3Xrnlg9KA==
На кластере ceph все работы завершены и теперь нам нужно перейти на машину которая имеет доступ до кластера kubernetes
Я буду работать с master01-test (10.73.71.25) кластера развернутого мной в первой публикации.
Создание client secret
Создадим файл с клиентским токеном который мы получили (не забудьте заменить на свой токен)
echo AQDd5aldka5KJRAAkpWTQYUMQi+5dfGDqSyxkg== > /tmp/key.client
И создадим secret, который будем использовать в дальнейшем
kubectl create secret generic ceph-secret --from-file=/tmp/key.client --namespace=kube-system --type=kubernetes.io/rbd
Создание admin secret
Создадим файл с админским токеном (не забудьте заменить на свой токен)
echo AQAv+Itdx4DwKBAAKVhWRS3+eEPqV3Xrnlg9KA== > /tmp/key.admin
После этого создадим admin secret
kubectl create secret generic ceph-admin-secret --from-file=/tmp/key.admin --namespace=kube-system --type=kubernetes.io/rbd
Проверим, что секреты создались
kubectl get secret -n kube-system | grep ceph ceph-admin-secret kubernetes.io/rbd 1 8m31s ceph-secret kubernetes.io/rbd 1 7m32s
Способ первый деплой ceph rbd provisioner
Клонируем с github репозиторий kubernetes-incubator/external-storage, в нем есть все необходимое для того чтобы ‘подружить’ кластер kubernetes c хранилищем ceph.
git clone https://github.com/kubernetes-incubator/external-storage.git cd external-storage/ceph/rbd/deploy/ NAMESPACE=kube-system sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/clusterrolebinding.yaml ./rbac/rolebinding.yaml
kubectl -n $NAMESPACE apply -f ./rbac
Вывод
clusterrole.rbac.authorization.k8s.io/rbd-provisioner created clusterrolebinding.rbac.authorization.k8s.io/rbd-provisioner created deployment.extensions/rbd-provisioner created role.rbac.authorization.k8s.io/rbd-provisioner created rolebinding.rbac.authorization.k8s.io/rbd-provisioner created serviceaccount/rbd-provisioner created
Способ второй: Замена образа kube-controller-manager
Данная часть будет заполнена в ближайшие дни.
Создание storage class
Создадим yaml файл с описанием нашего storage class. Также все файлы используемые ниже можно скачать в моем репозитории в каталоге ceph
cat <<EOF >./storage-class.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: ceph-rbd provisioner: ceph.com/rbd parameters: monitors: 10.73.88.52:6789, 10.73.88.53:6789, 10.73.88.54:6789 pool: kube adminId: admin adminSecretNamespace: kube-system adminSecretName: ceph-admin-secret userId: kube userSecretNamespace: kube-system userSecretName: ceph-secret imageFormat: "2" imageFeatures: layering EOF
И задеплоим его в наш кластер
kubectl apply -f storage-class.yaml
Проверим что все ОК
kubectl get sc NAME PROVISIONER AGE ceph-rbd ceph.com/rbd 7s
Тест работы связки kubernetes + ceph
Перед тем как тестировать работу ceph + kubernetes, на КАЖДОЙ воркноде кластера нужно установить пакет ceph-common.
apt install curl apt-transport-https -y curl https://mirror.croit.io/keys/release.gpg > /usr/share/keyrings/croit-signing-key.gpg echo 'deb [signed-by=/usr/share/keyrings/croit-signing-key.gpg] https://mirror.croit.io/debian-mimic/ stretch main' > /etc/apt/sources.list.d/croit-ceph.list apt update apt install ceph-common
Создадим yaml файл PersistentVolumeClaim
cat <<EOF >./claim.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: claim1 spec: accessModes: - ReadWriteOnce storageClassName: ceph-rbd resources: requests: storage: 1Gi EOF
Задеплоим его
kubectl apply -f claim.yaml
Проверим что PersistentVolumeClaim создался.
bectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE claim1 Bound pvc-d1e47825-289c-4201-acb8-033e62a3fe81 1Gi RWO ceph-rbd 44m
А также автоматически создался PersistentVolume.
kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d1e47825-289c-4201-acb8-033e62a3fe81 1Gi RWO Delete Bound default/claim1 ceph-rbd 37m
Создадим один тестовый pod, в котором мы подключим созданный pvc в каталог /mnt. Пускай данный файл /mnt/test.txt c текстом «Hello World!»
cat <<EOF >./greate-file-pod.yaml kind: Pod apiVersion: v1 metadata: name: greate-file-pod spec: containers: - name: test-pod image: gcr.io/google_containers/busybox:1.24 command: - "/bin/sh" args: - "-c" - "echo Helo world! > /mnt/test.txt && exit 0 || exit 1" volumeMounts: - name: pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: pvc persistentVolumeClaim: claimName: claim1 EOF
Задеплоим его и проверим, что он выполнил свою задачу
kubectl apply -f greate-file-pod.yaml kubectl get pods -w
Дождемся статуса
greate-file-pod 0/1 Completed 0 16s
Создадим другой под, подключим к нему наш том но уже в /mnt/test, а после этого убедимся, что созданный первым томом файл на месте
cat <<EOF >./test-pod.yaml kind: Pod apiVersion: v1 metadata: name: test-pod spec: containers: - name: test-pod image: gcr.io/google_containers/busybox:1.24 command: - "/bin/sh" args: - "-c" - "sleep 600" volumeMounts: - name: pvc mountPath: "/mnt/test" restartPolicy: "Never" volumes: - name: pvc persistentVolumeClaim: claimName: claim1 EOF
Выполним kubectl get po -w и дождемся пока pod будет в статусе running
После этого зайдем в него и проверим что том подключился и наш файл в каталоге /mnt/test
kubectl exec test-pod -ti sh cat /mnt/test/test.txt Helo world!
Спасибо за то что прочитали до конца. Извиняюсь за задержку публикации.
На все вопросы я готов ответить в личных сообщениях или в соцсетях, которые указаны у меня в профиле.
В следующей небольшой публикации я расскажу, как на базе созданного ceph кластера развернуть хранилище S3, и далее по плану из первой публикации.
Материалы используемые для публикации
ссылка на оригинал статьи https://habr.com/ru/post/465399/
Добавить комментарий