====== Строим свое облачное и расширяемое хранилище на базе Ceph ====== Облачный и расширяемый open-source сервис хранения данных Поскольку заниматься **Ceph** я начал недавно, возможны недочеты или же некоторые действия могут показаться лишними или неправильными.\\ Я действую из той информации, которая доступна и понятна мне. Список материалов будет представлен в конце статьи. В качестве тестового стенда я взял **ESXi** сервер, на котором развернул виртуальные машины с необходимым мне количество виртуальных дисков, которые будут имитировать работу физических серверов. === Коротко о демонах === **OSD** (//object storage daemon//) — в каждой ноде кластера может быть несколько дисков и на каждый диск нужен отдельный демон **OSD**. Демоны **Ceph OSD** сохраняют данные в виде объектов в плоском пространстве имён, то есть без иерархии в виде каталогов. Объекты обладают идентификаторами, бинарными данными и метаданными в виде ключ-значение, которые использует **MDS** сохраняя владельца файла, время создания, время модификации и так далее. Идентификатор объекта уникален в пределах кластера. Демон **OSD** в составе кластера постоянно сообщает о своём статусе - //up// или //down//. Если по ряду причин **OSD** демон не сообщает о своём состоянии, демон монитора периодически сам проверяет статус **OSD** демонов и уполномочен обновлять кластерную карту и уведомлять других демонов мониторов о состоянии **OSD** демонов. **Metadata server (MDS)** — вспомогательный демон для обеспечения синхронного состояния файлов в точках монтирования **CephFS**. В один момент времени работает только один **MDS** в пределах кластера, а другие находятся в режиме ожидания и кто-то станет активным, если текущий **MDS** упадёт. Мониторы **Ceph** (//Ceph Monitors//) поддерживают главную копию (//master copy//) кластерной карты (//cluster map//), по которой клиенты **Ceph** могут определить расположение всех мониторов, **OSD** демонов и серверов **Metadata (MDS)**. До того как клиенты начнут что-либо писать или читать у **OSD** или **MDS**, они должны впервую очередь связаться с монитором **Ceph**. С текущей кластерной картой и алгоритмом **CRUSH**, клиенты могут вычислить расположение любого объекта. Эта способность позволяет клиентам напрямую общаться с **OSD**, что является важным аспектом в архитектуре **Ceph** и его способности к высокой доступности и производительности. Главная задача мониторов - поддерживать главную копию кластерной карты. Помимо этого мониторы занимаются аутентификацией и журналированием. Кластерная карта - это комплексная карта. Она состоит из карты мониторов (//monitor map//), карты **OSD** (//OSD map//), карты плейсмент-группы (//placement group map//) и карты **MDS** (//metadata server map//). Приступим.\\ Выполняем установку ОС на сервера и базовую настройку сети, также отключаем **IPv6** и **SElinux**. Установку системы производим на один диск, загрузчик ставим туда же, никаких **RAID** не собираем (тоже самое касается аппаратного **RAID** - только **RAID 0** (**JBOD**)). * Ceph-node-admin [192.168.2.67] * Ceph-node-mon [192.168.2.68] * Ceph-node-00 [192.168.2.69] * Ceph-node-01 [192.168.2.70] * Ceph-node-02 [192.168.2.71] Для удобства будем работать по каноническим именам, если нет своего личного **DNS**-сервера, то не забываем внести соответствующие настройки в файл ''/etc/hosts'' на каждом сервере. | 192.168.2.67 Ceph-node-admin 192.168.2.68 Ceph-node-mon 192.168.2.69 ceph-node-00 192.168.2.70 ceph-node-01 192.168.2.71 ceph-node-02 | ==== Настройка NTP ==== Выполняем настройку **NTP** сервера на каждой ноде. Это очень важный шаг, поскольку большинство проблем может возникнуть именно из-за некорректной настройки времени. === Установим NTP === | sudo yum install ntp ntpdate sudo ntpdate ntp2.stratum2.ru sudo systemctl enable ntpd.service sudo systemctl start ntpd.service | Вносим изменения в конфигурационный файл ''/etc/ntp.conf''. | server ntp2.stratum2.ru server ntp3.stratum2.ru server ntp4.stratum2.ru server ntp5.stratum2.ru disable monitor restrict default kod nomodify notrap nopeer noquery restrict -6 default kod nomodify notrap nopeer noquery restrict 127.0.0.1 restrict -6 ::1 | Выполним настройку временной зоны, если это не было сделано при установке системы. ==== Создаем нового пользователя ==== Поскольку данный пункт я выполнил на стадии установки, то я сразу перейду к следующему шагу. Изменим файл ''/etc/sudoers'' на каждом сервере и добавим в него следующую строчку, что позволит выполнять ''sudo'' команды без запроса пароля. Либо создадим в папке ''/etc/sudoers.d/'' файл с именем пользователя, в который добавим тоже самое. | echo "{USERNAME} ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/ceph && sudo chmod 0440 /etc/sudoers.d/ceph | Мы создали пользователя ''ceph'' на каждой ноде, теперь создадим ключ авторизации, без указания кодовой фразы, для беспарольного доступа между серверами. | ssh-keygen | Теперь скопируем его на все используемые сервера. | ssh-copy-id {ceph user}@{hostname} | Например: | ssh-copy-id ceph@ceph-node-admin ssh-copy-id ceph@ceph-node-mon ssh-copy-id ceph@ceph-node-00 ssh-copy-id ceph@ceph-node-01 ssh-copy-id ceph@ceph-node-02 | ==== Настройка ядра системы ==== При наличии большого количества **OSD**, возможно создание огромного количества тредов (//threads//), особенно в процессе восстановления или же при повторной балансировке. Изменим в **Linux** значение по умолчанию на необходимое нам. ''kernel.pid_max'' служит для поддержки большего значения тредов (//threads//). В теории, максимум это ''- 4,194,303''. Внесем изменения в файл ''/etc/sysctl.conf'', добавив строчку: | kernel.pid_max = 4194303 | Применяем параметры “на лету”: | sudo sysctl -p | ==== Настроим правила на файрволле ==== Для **Firewalld** | sudo firewall-cmd --zone=public --add-port=6789/tcp --permanent sudo firewall-cmd --zone=public --add-service=ceph-mon --permanent sudo firewall-cmd --zone=public --add-service=ceph --permanent sudo firewall-cmd --reload | Для **Iptables** | sudo iptables -A INPUT -i {iface} -p tcp -s {ip-address}/{netmask} --dport 6789 -j ACCEPT | Также установим пакет ''yum-plugin-priorities'', чтобы менеджер пакетов устанавливал предпочтительные пакеты. | sudo yum install yum-plugin-priorities | ==== Установка Ceph Storage Cluster с помощью ceph-deploy ==== Начнем пожалуй с простого. Сделаем кластер с двумя **OSD** демонами и одним монитором. После достижения статуса ''active+clean'' добавим третий **OSD** демон в уже работающий кластер, а также резервный **MDS** и несколько мониторов. === Выполним установку ceph-deploy === Установим необходимые пакеты и репозитории: | sudo yum install -y yum-utils && sudo yum-config-manager --add-repo https://dl.fedoraproject.org/pub/epel/7/x86_64/ && sudo yum install --nogpgcheck -y epel-release && sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 && sudo rm /etc/yum.repos.d/dl.fedoraproject.org* | Подключим репозиторий Ceph ''/etc/yum.repos.d/ceph.repo'': | [ceph-noarch] name=Ceph noarch packages baseurl=http://download.ceph.com/rpm-{ceph-release}/{distro}/noarch enabled=1 gpgcheck=1 type=rpm-md gpgkey=https://download.ceph.com/keys/release.asc | Заменим ''{distro}'' на наш дистрибутив, в данном случае ''el7''. Заменим ''{ceph-release}'' на стабильную версию [[http://docs.ceph.com/docs/master/releases/|Ceph]]. На момент написания статьи это ''infernalis''. После всех этих действий установим пакет ''ceph-deploy'': | sudo yum update && sudo yum install ceph-deploy | Создадим рабочую директорию на административной ноде для генерации конфигурационных файлов и ключей, дальнейшие действия необходимо выполнять находясь в ней. | mkdir ceph-admin cd ceph-admin | **Очень важно!** Не выполняйте команду ''ceph-deploy'' с ''sudo'' или же от ''root'', если авторизованы под другим пользователем. На некоторых дистрибутивах, в частности **CentOS**, при выполнении команды ''ceph-deploy'' возможны ошибки, для этого измените параметр ''Defaults requiretty'' с помощью ''sudo visudo'' в ''/etc/sudoers.d/ceph'' на ''Defaults:ceph !requiretty'' для того, чтобы ''ceph-deploy'' мог подключаться с помощью пользователя ''ceph'' и выполнять команды с ''sudo''. Далее при установке, если на каком-то из пунктов получили неисправимую ошибку, то можно затереть данные и откатиться, используя следующие команды: | ceph-deploy purgedata {ceph-node} [{ceph-node}] ceph-deploy forgetkeys | Для удаления пакетов: | ceph-deploy purge {ceph-node} [{ceph-node}] | Если выполнялась команда ''purge'', то необходимо переустановить пакеты Ceph. ==== Создаем кластер Ceph Storage Cluster ==== С админской ноды из директории, которую мы создали для хранения конфигурационных файлов, выполняем команду для создания кластера: | ceph-deploy new {initial-monitor-node(s)} | Например: | ceph-deploy new ceph-node-mon | После этого в папке появится конфигурационный файл и ключ монитора. Убедитесь в этом. По умолчанию имя кластера будет ceph. Если вы хотите на одном и том же оборудовании использовать несколько кластеров, то для каждого из них нужно задавать имя, используя ceph-deploy –cluster {cluster-name} new … Изменим значение по умолчанию для количества реплик в **Ceph**. По умолчанию значение равно ''3'', изменим его на ''2'', чтобы **Ceph** мог достичь статуса ''Active+Clean'' с помощью двух **OSD**. Добавим следующую строку в директиву ''[global]'' файла ''ceph.conf''. | osd_pool_default_size = 3 osd_pool_default_min_size = 2 | Зададим значения для плейсмент групп (//Placement Groups//) и плейсмент групп для размещения (//Placement Groups for Placement//) в директиве ''[global]''. Для небольших кластеров (//менее 5 OSDs//) рекомендуется **128** плейсмент группы. | osd_pool_default_pg_num = osd_pool_default_pgp_num = | * менее **5 OSD** - значение ''pg_num'' и ''pgp_num'' ставим **128**; * от **5** до **10 OSD** - значение ''pg_num'' и ''pgp_num'' ставим **512**; * от **10** до **50 OSD** - значение ''pg_num'' и ''pgp_num'' ставим **4096**; * от **50 OSD** и выше параметры ''pg_num'' и ''pgp_num'' рассчитываем по следующей формуле: | (OSDs * 100) Total PGs = ------------ pool size | ''osd_pool_default_size'' значение, которое мы устанавливали на предыдущем шаге. Установим максимальное количество плейсмент груп на **OSD**. По умолчанию это значение равно **300**. Несколько пулов могут использовать один и тот же набор правил **CRUSH**. Когда **OSD** имеют слишком много плейсмент групп это может сказаться на производительности. | mon_pg_warn_max_per_osd | Установка типа **CRUSH** для отказоустойчивости. По умолчанию это значение равно **1**. Если мы хотим сделать как минимум для 3-х объектов реплики, то необходимо изменить параметр на **3**. | osd_crush_chooseleaf_type = 3 | * Тип **0** - osd * Тип **1** - host * Тип **2** - chassis * Тип **3** - rack * Тип **4** - row * Тип **5** - pdu * Тип **6** - pod * Тип **7** - room * Тип **8** - datacenter * Тип **9** - region * Тип **10** - root Установим ''max_open_files'' для того чтобы задать максимальное значение открытых дескрипторов файлов на уровне ОС: max_open_files = 131072 **XATTR** параметры используются с файловой системой ''ext4'' для улучшения производительности. filestore_xattr_use_omap = true Как уже и говорилось в начале статьи, рекомендуется правильная настройка времени на сервере. mon_clock_drift_allowed = .15 mon_clock_drift_warn_backoff = 30 mon_osd_down_out_interval = 300 mon_osd_report_timeout = 300 Установим ''full_ratio'' и ''near_full_ratio'' на приемлемые значения. Полную мощность на 95% и почти заполненную на 85%. | mon_osd_full_ratio = .75 mon_osd_nearfull_ratio = .65 osd_backfill_full_ratio = .65 | Пример ceph.conf | [global] fsid = {cluster-id} mon initial members = {hostname}[, {hostname}] mon host = {ip-address}[, {ip-address}] #All clusters have a front-side public network. #If you have two NICs, you can configure a back side cluster #network for OSD object replication, heart beats, backfilling, #recovery, etc. public network = {network}[, {network}] #cluster network = {network}[, {network}] #Clusters require authentication by default. auth cluster required = cephx auth service required = cephx auth client required = cephx #Choose reasonable numbers for your journals, number of replicas #and placement groups. osd journal size = {n} osd pool default size = {n} # Write an object n times. osd pool default min size = {n} # Allow writing n copy in a degraded state. osd pool default pg num = {n} osd pool default pgp num = {n} #Choose a reasonable crush leaf type. #0 for a 1-node cluster. #1 for a multi node cluster in a single rack #2 for a multi node, multi chassis cluster with multiple hosts in a chassis #3 for a multi node cluster with hosts across racks, etc. osd crush chooseleaf type = {n} | Если на сервере имеется и используется больше одного сетевого интерфейса, то добавим ''public_network'' в секцию ''[global]'' конфигурационного файла **Ceph**. ( [[http://docs.ceph.com/docs/master/rados/configuration/network-config-ref/|Подробнее о сетевой конфигурации]] ) Установим **Ceph**: | ceph-deploy install {ceph-node}[{ceph-node} ...] | Например: | ceph-deploy install ceph-node-admin ceph-node-mon ceph-node-00 ceph-node-01 | В процессе установки может появиться следующая ошибка: | [ceph-node-admin][WARNIN] warning: /etc/yum.repos.d/ceph.repo created as /etc/yum.repos.d/ceph.repo.rpmnew [ceph-node-admin][WARNIN] ensuring that /etc/yum.repos.d/ceph.repo contains a high priority [ceph_deploy][ERROR ] RuntimeError: NoSectionError: No section: 'ceph' | Устраняем проблему командой: | sudo mv /etc/yum.repos.d/ceph.repo /etc/yum.repos.d/ceph-deploy.repo | == Настройка CRUSH карты с SSD кэшированием == В файле конфигурации **ceph** запрещаем обновлять карту автоматически: | osd_crush_update_on_start = false | Сохраним текущую карту и переведем её в текстовый формат: | ceph osd getcrushmap -o map.running crushtool -d map.running -o map.decompile | | # begin crush map tunable choose_local_tries 0 tunable choose_local_fallback_tries 0 tunable choose_total_tries 50 tunable chooseleaf_descend_once 1 tunable chooseleaf_vary_r 1 tunable straw_calc_version 1 # devices device 0 osd.0 device 1 osd.1 device 2 osd.2 device 3 osd.3 device 4 osd.4 device 5 osd.5 device 6 osd.6 device 7 osd.7 device 8 osd.8 device 9 osd.9 device 10 osd.10 device 11 osd.11 device 12 osd.12 # types type 0 osd type 1 host type 2 chassis type 3 rack type 4 row type 5 pdu type 6 pod type 7 room type 8 datacenter type 9 region type 10 root # buckets host ceph-node-00-ssd-cache { id -2 # do not change unnecessarily # weight 5.659 alg straw hash 0 # rjenkins1 item osd.0 weight 1.000 } host ceph-node-01-ssd-cache { id -3 # do not change unnecessarily # weight 16.550 alg straw hash 0 # rjenkins1 item osd.1 weight 1.000 } host ceph-node-02-ssd-cache { id -4 # do not change unnecessarily # weight 5.659 alg straw hash 0 # rjenkins1 item osd.2 weight 1.000 } host ceph-node-00-hdd { id -102 # do not change unnecessarily # weight 5.659 alg straw hash 0 # rjenkins1 item osd.11 weight 1.000 item osd.12 weight 1.000 } host ceph-node-01-hdd { id -103 # do not change unnecessarily # weight 16.550 alg straw hash 0 # rjenkins1 item osd.3 weight 1.000 item osd.4 weight 1.000 item osd.5 weight 1.000 item osd.6 weight 1.000 item osd.7 weight 1.000 item osd.8 weight 1.000 } host ceph-node-02-hdd { id -104 # do not change unnecessarily # weight 5.659 alg straw hash 0 # rjenkins1 item osd.9 weight 1.000 item osd.10 weight 1.000 } root ssd-cache { id -1 # do not change unnecessarily # weight 27.868 alg straw hash 0 # rjenkins1 item ceph-node-00-ssd-cache weight 5.659 item ceph-node-01-ssd-cache weight 16.550 item ceph-node-02-ssd-cache weight 5.659 } root hdd { id -100 # do not change unnecessarily # weight 27.868 alg straw hash 0 # rjenkins1 item ceph-node-00-hdd weight 5.659 item ceph-node-01-hdd weight 16.550 item ceph-node-02-hdd weight 5.659 } # rules rule ssd-cache { ruleset 0 type replicated min_size 1 max_size 10 step take ssd-cache step chooseleaf firstn 0 type host step emit } rule hdd { ruleset 1 type replicated min_size 1 max_size 10 step take hdd step chooseleaf firstn 0 type host step emit } # end crush map | Обратите внимание на то, что я создал два root для SSD и HDD, а также два правила ruleset. Скомпилируем обратно и запустим CRUSH-карту | crushtool -c map.decompile -o map.new ceph osd setcrushmap -i map.new | == Добавим первоначальные мониторы и соберем ключи == Для обеспечения высокой доступности необходимо запустить **Ceph** как минимум с 3-мя мониторами. **Ceph** использует алгоритм, который требует консенсуса среди большинства мониторов в кворуме. Подсчет мониторов осуществляется приблизительно следующим образом: ''1:1'', ''2:3'', ''3:4'', ''3:5'', ''4:6'', etc. Необязательно, но желательно, чтобы количество мониторов в кластере было нечётным числом для улучшения работы алгоритма Paxos при сохранении кворума. В идеале, разработчики **Ceph** советуют ноды-мониторы не совмещать с нодами **OSD**, так как мониторы активно используют ''fsync()'' и это пагубно влияет на производительность **OSD**. | ceph-deploy mon create-initial | После выполнения данного процесса в локальной директории ''ceph-admin'' проверим наличие всех ключей: | {cluster-name}.client.admin.keyring {cluster-name}.bootstrap-osd.keyring {cluster-name}.bootstrap-mds.keyring {cluster-name}.bootstrap-rgw.keyring | Например: | [ceph@ceph-node-admin ceph-admin]$ ls -lah total 228K drwxrwxr-x. 2 ceph ceph 4.0K Feb 29 13:30 . drwx------. 4 ceph ceph 4.0K Feb 29 12:46 .. -rw------- 1 ceph ceph 71 Feb 29 13:30 ceph.bootstrap-mds.keyring -rw------- 1 ceph ceph 71 Feb 29 13:30 ceph.bootstrap-osd.keyring -rw------- 1 ceph ceph 71 Feb 29 13:30 ceph.bootstrap-rgw.keyring -rw------- 1 ceph ceph 63 Feb 29 13:30 ceph.client.admin.keyring -rw-rw-r-- 1 ceph ceph 260 Feb 29 13:12 ceph.conf -rw-rw-r--. 1 ceph ceph 180K Feb 29 13:30 ceph.log -rw------- 1 ceph ceph 73 Feb 29 13:11 ceph.mon.keyring | ==== Добавление OSD ==== Первоначальный вариант предусматривает **OSD** в виде директорий на диске, я же буду использовать диски полностью. Добавление и удаление **OSD** демонов в кластер может занимать несколько шагов, особенно если используется запись на диск и в журнал. Для листинга дисков ноды используем следующую команду: | ceph-deploy disk list {node-name [node-name]...} | Например: [ceph@ceph-node-admin ceph-admin]$ ceph-deploy disk list ceph-node-00 [ceph_deploy.conf][DEBUG ] found configuration file at: /home/ceph/.cephdeploy.conf [ceph_deploy.cli][INFO ] Invoked (1.5.31): /usr/bin/ceph-deploy disk list ceph-node-00 [ceph_deploy.cli][INFO ] ceph-deploy options: [ceph_deploy.cli][INFO ] username : None [ceph_deploy.cli][INFO ] verbose : False [ceph_deploy.cli][INFO ] overwrite_conf : False [ceph_deploy.cli][INFO ] subcommand : list [ceph_deploy.cli][INFO ] quiet : False [ceph_deploy.cli][INFO ] cd_conf : [ceph_deploy.cli][INFO ] cluster : ceph [ceph_deploy.cli][INFO ] func : [ceph_deploy.cli][INFO ] ceph_conf : None [ceph_deploy.cli][INFO ] default_release : False [ceph_deploy.cli][INFO ] disk : [('ceph-node-00', None, None)] [ceph-node-00][DEBUG ] connection detected need for sudo [ceph-node-00][DEBUG ] connected to host: ceph-node-00 [ceph-node-00][DEBUG ] detect platform information from remote host [ceph-node-00][DEBUG ] detect machine type [ceph-node-00][DEBUG ] find the location of an executable [ceph_deploy.osd][INFO ] Distro info: CentOS Linux 7.2.1511 Core [ceph_deploy.osd][DEBUG ] Listing disks on ceph-node-00... [ceph-node-00][DEBUG ] find the location of an executable [ceph-node-00][INFO ] Running command: sudo /usr/sbin/ceph-disk list [ceph-node-00][DEBUG ] /dev/dm-0 other, xfs, mounted on / [ceph-node-00][DEBUG ] /dev/dm-1 swap, swap [ceph-node-00][DEBUG ] /dev/sda : [ceph-node-00][DEBUG ] /dev/sda2 other, LVM2_member [ceph-node-00][DEBUG ] /dev/sda1 other, xfs, mounted on /boot [ceph-node-00][DEBUG ] /dev/sdb other, unknown [ceph-node-00][DEBUG ] /dev/sdc other, unknown [ceph-node-00][DEBUG ] /dev/sr0 other, unknown | Затираем диски Определившись с дисками затираем все данные на них (в т.ч. таблицу разделов) и подготовим для использования **Ceph**. ceph-deploy disk zap {osd-server-name}:{disk-name} Например: | ceph-deploy disk zap ceph-node-00:sdb ceph-node-00:sdc ceph-node-01:sdb ceph-node-01:sdc | ==== Подготовим диски ==== Разработчики **Ceph** рекомендуют использовать файловую систему **XFS**. ( [[http://docs.ceph.com/docs/master/rados/configuration/filesystem-recommendations/|см. Ceph Docs]] ), поэтому позаботьтесь о том, чтобы пакет ''xfsprogs'' был установлен на всех нодах кластера. При подготовке дисков ''ceph-deploy'' автоматически форматирует диски в **XFS**. Если установка производится на разделы, то отформатировать его можно командой ''sudo mkfs.xfs -i size=512 /dev/sdX''. | ceph-deploy osd prepare {node-name}:{data-disk}[:{journal-disk}] ceph-deploy osd prepare osdserver1:sdb:/dev/ssd ceph-deploy osd prepare osdserver1:sdc:/dev/ssd | | ceph-deploy osd prepare ceph-node-00:sdb ceph-node-00:sdc ceph-node-01:sdb ceph-node-01:sdc | После создания кластера и установки **Ceph** пакетов, а также создания ключей, можем выполнить подготовку **OSD** и развернуть их на **OSD** нодах. Команда ''prepare'' только подготовит **OSD**! ==== Активация OSD ==== После успешной подготовки дисков активируем **OSD**. (Обратите внимание, что необходимо указать разделы диска.) | ceph-deploy osd activate {node-name}:{data-disk-partition}[:{journal-disk-partition}] ceph-deploy osd activate osdserver1:sdb1:/dev/ssd1 ceph-deploy osd activate osdserver1:sdc1:/dev/ssd2 | Например: | ceph-deploy osd activate ceph-node-00:sdb1:/dev/sdb2 ceph-node-00:sdc1:/dev/sdc2 ceph-node-01:sdb1:/dev/sdb2 ceph-node-01:sdc1:/dev/sdc2 | Для того чтобы подготовить, развернуть и активировать **OSD** можно воспользоваться одной командой ''create'': | ceph-deploy osd create ceph-node-00:sdb1:/dev/sdb2 ceph-node-00:sdc1:/dev/sdc2 ceph-node-01:sdb1:/dev/sdb2 ceph-node-01:sdc1:/dev/sdc2 | Скопируем ключи и конфигурационный файл на ноды: | ceph-deploy admin {admin-node} {ceph-node} | Например: | ceph-deploy admin ceph-node-admin ceph-node-mon ceph-node-00 ceph-node-01 | Убедимся в корректных привилегиях ''ceph.client.admin.keyring'': | sudo chmod +r /etc/ceph/ceph.client.admin.keyring | Проверяем состояние: | ceph status | Получаем статус **Ceph**: | [ceph@ceph-node-admin ceph-admin]$ ceph status cluster ca89dd68-e6d7-4f62-b947-62abcc111ac0 health HEALTH_OK monmap e1: 1 mons at {ceph-node-mon=192.168.2.68:6789/0} election epoch 2, quorum 0 ceph-node-mon osdmap e19: 5 osds: 4 up, 4 in flags sortbitwise pgmap v48: 64 pgs, 1 pools, 0 bytes data, 0 objects 133 MB used, 61262 MB / 61395 MB avail 64 active+clean | При получении предупреждения, например: | [ceph@ceph-node-admin ceph-admin]$ ceph status cluster fb82947c-7b0d-4b7d-8bd9-c0386f48c152 health HEALTH_WARN 64 pgs stuck inactive 64 pgs stuck unclean too few PGs per OSD (16 | Ищем решение [[http://docs.ceph.com/docs/hammer/rados/troubleshooting/troubleshooting-pg/|Ceph Troubleshooting]]. == Создание OSD с SSD кэшированием == | ceph osd pool create ssd-cache 128 ceph osd pool set ssd-cache min_size 1 ceph osd pool set ssd-cache size 2 ceph osd pool create one 512 ceph osd pool set one min_size 1 ceph osd pool set one size 2 | | ceph osd pool set ssd-cache crush_ruleset 0 ceph osd pool set one crush_ruleset 1 | | ceph osd tier add one ssd-cache ceph osd tier cache-mode ssd-cache writeback ceph osd tier set-overlay one ssd-cache | | # Включаем фильтр bloom ceph osd pool set ssd-cache hit_set_type bloom # Сколько обращений к объекту что бы он считался горячим ceph osd pool set ssd-cache hit_set_count 4 # Сколько времени объект будет считаться горячим ceph osd pool set ssd-cache hit_set_period 1200 | | # Сколько байтов должно заполниться прежде чем включится механизм очистки кэша ceph osd pool set ssd-cache target_max_bytes 200000000000 # Процент заполнения хранилища, при котором начинается операция промывания ceph osd pool set ssd-cache cache_target_dirty_ratio 0.4 # Процент заполнения хранилища, при котором начинается операция выселения ceph osd pool set ssd-cache cache_target_full_ratio 0.8 # Минимальное количество времени прежде чем объект будет промыт ceph osd pool set ssd-cache cache_min_flush_age 300 # Минимальное количество времени прежде чем объект будет выселен ceph osd pool set ssd-cache cache_min_evict_age 300 | К сожалению OSD автоматически в конфигурационный файл не запишутся. Кроме того даже после записи в конфигурацию автоматическое монтирование этих точек тоже не работает. Чтобы поднять OSD демон при загрузке необходим файл ключ, который лежит на не примонтированном разделе. Поэтому дополняем конфигурационный файл ''ceph.conf'': | ... [osd.0] host = ceph-node-00 [osd.1] host = ceph-node-00 [osd.2] host = ceph-node-01 [osd.3] host = ceph-node-01 | Кроме этого смотрим на каждом узле где есть osd: | mount | grep ceph ... /dev/sdc1 on /var/lib/ceph/osd/ceph-2 type xfs (rw,relatime,attr2,inode64,noquota) /dev/sdb1 on /var/lib/ceph/osd/ceph-1 type xfs (rw,relatime,attr2,inode64,noquota) | Добавляем записи в ''/etc/fstab'' для надежности: | /dev/sdb1 /var/lib/ceph/osd/ceph-1 rw,noatime,attr2,inode64,noquota /dev/sdc1 /var/lib/ceph/osd/ceph-2 rw,noatime,attr2,inode64,noquota | Перезаписываем конфигурацию: | ceph-deploy --overwrite-conf admin ceph-node-admin ceph-node-mon ceph-node-00 ceph-node-01 | На текущем моменте у нас есть кластер с единственным и пока не настроенным пулом. | ceph osd lspools | Получаем: | 0 rbd, | RBD можно считать некоторым аналогом жесткого диска на котором необходимо будет нарезать разделы. Например для Opennebula потребуется три пула: ''files'', ''system'' и ''images''. | ceph osd pool create images 64 64 | Цифра в конце команды - количество PG и PGP для пула. Можно считать, что PG это минимальный реплицирующийся кусок пространства, в которое мы можем запихнуть обьект (файл) или кусок от него. PGP - максимальное количество PG групп для пула. По мануалам есть формула общего количество PG (указано выше): ((количество OSD)//100)/(osd pool default size). То есть 3//100/2 = 150. полученное число ещё необходимо округлить вверх до степени двойки - то есть у нас получается 256. Делим это число на количество пулов, округляем вверх до степени 2 - получаем искомую настройку. 256/2 (system,rbd)=128. Получаем информацию о плейсмент группах: | ceph osd pool get rbd pg_num pg_num: 64 | Задаем значения PG вручную: | ceph osd pool set rbd pg_num 512 ceph osd pool set rbd pgp_num 512 | **Ceph** находится в зависимости от **Ceph** клиентов и **Ceph OSD** демонов, будучи осведомленных о кластерной топологии, которые включают в себя 5 отдельных карт, коллективно называемых как “**Cluster Map**”: - **Монитор**: Содержит **FSID** кластера, положение, адреса и порт каждого монитора. Он так же указывает на текущую версию сервера монитора, когда карта была создана и когда в последний раз изменялась. Чтобы просмотреть карту монитора необходимо выполнить команду: ''ceph mon dump'' - **OSD**: Содержит **FSID** кластера, когда карта была создана и последние изменения, список пулов, размер репликаций, количество **PGs**, список **OSD** и их текущее состояние. Для просмотра **OSD** карты необходимо выполнить команду: ''ceph osd dump'' - **PG**: Содержит версию **PG**, его метки времени, последнию версию **OSD**, полные соотношения и подробную информацию о каждой группе размещения, такие как **PG****ID**, состояние **PG** (например ''active+clean'') и т.д. Для просмотра **PG** карты необходимо выполнить команду: ''ceph pg dump'' - **CRUSH**: Содержит список устройств хранения, отказоустойчивую иерархию домена (**device**,**host**,**rack**,**row**,**room**,**datacenter**) и правила для иерархий при хранений данных. Для просмотра структуры **CRUSH** алгоритма необходимо выполнить команду: ''ceph osd tree'' - **MDS**: Содержит текущую **MDS** версию карты, когда карта была создана и когда в последний момент изменялась. Так же содержится **pool** для хранения метаданных, список серверов метаданных и какие сервера включены и выключены. Для просмотра **MDS** карты, необходимо выполнить ''ceph mds dump'' ==== Терминология ==== **Metadata server (MDS)** — вспомогательный демон для обеспечения синхронного состояния файлов в точках монтирования **CephFS**. Работает по схеме активная копия + резервы, причем активная копия в пределах кластера только одна. **Mon (Monitor)** — элемент инфраструктуры **Ceph**, который обеспечивает адресацию данных внутри кластера и хранит информацию о топологии, состоянии и распределении данных внутри хранилища. Клиент, желающий обратиться к блочному устройству **rbd** или к файлу на примонтированной **cephfs**, получает от монитора имя и положение **rbd header** — специального объекта, описывающего положение прочих объектов, относящихся к запрошенной абстракции (блочное устройство или файл) и далее общается со всеми **OSD**, участвующими в хранении файла. **Объект (Object)** — блок данных фиксированного размера (по умолчанию 4 Мб). Вся информация, хранимая в **Ceph**, квантуется такими блоками. Чтобы избежать путаницы подчеркнем — это не пользовательские объекты из **Object Storage**, а объекты, используемые для внутреннего представления данных в **Ceph**. **OSD (object storage daemon)** — сущность, которая отвечает за хранение данных, основной строительный элемент кластера **Ceph**. На одном физическом сервере может размещаться несколько OSD, каждая из которых имеет под собой отдельное физическое хранилище данных. **Карта OSD (OSD Map)** — карта, ассоциирующая каждой плейсмент-группе набор из одной **Primary OSD** и одной или нескольких **Replica OSD**. Распределение **placement groups (PG)** по нодам хранилища **OSD** описывается срезом карты **osdmap**, в которой указаны положения всех **PG** и их реплик. Каждое изменение расположения **PG** в кластере сопровождается выпуском новой карты **OSD**, которая распространяется среди всех участников. **Плейсмент-группа (Placement Group, PG)** — логическая группа, объединяющая множество объектов, предназначенная для упрощения адресации и синхронизации объектов. Каждый объект состоит лишь в одной плейсмент группе. Количество объектов, участвующих в плейсмент-группе, не регламентировано и может меняться. **Primary OSD — OSD**, выбранная в качестве **Primary** для данной плейсмент-группы. Клиентское IO всегда обслуживается той **OSD**, которая является **Primary** для плейсмент группы, в которой находится интересующий клиента блок данных (объект). **rimary OSD** в асинхронном режиме реплицирует все данные на **Replica OSD**. **RADOS Gateway (RGW)** — вспомогательный демон, исполняющий роль прокси для поддерживаемых API объектных хранилищ. Поддерживает географически разнесенные инсталляции (для разных пулов, или, в представлении Swift, регионов) и режим **active-backup** в пределах одного пула. **Replica OSD (Secondary) — OSD**, которая не является **Primary** для данной плейсмент-группы и используется для репликации. Клиент никогда не общается с ними напрямую. **Фактор репликации (RF)** — избыточность хранения данных. Фактор репликации является целым числом и показывает, сколько копий одного и того же объекта хранит кластер. ==== Список используемых материалов ==== - [[http://docs.ceph.com/docs/master/start/quick-ceph-deploy/|http://docs.ceph.com/docs/master/start/quick-ceph-deploy/]] - [[https://access.redhat.com/documentation/en/red-hat-ceph-storage/|https://access.redhat.com/documentation/en/red-hat-ceph-storage/]] - [[http://onreader.mdl.ru/LearningCeph/content/index.html|http://onreader.mdl.ru/LearningCeph/content/index.html]] - [[http://tracker.ceph.com/|http://tracker.ceph.com/]] - [[https://habrahabr.ru/company/performix/blog/218065/|https://habrahabr.ru/company/performix/blog/218065/]]