13/12/2020
По-настоящему серьезное Open Source решение, которое позволяет организовать отказоустойчивое хранение данных в организации, это CEPH. При этом оно совмещает в себе возможности объектного, блочного и файлового хранения данных. Если аналогичные по функционалу коммерческие продукты стоят колоссальных денег и требуют постоянной покупки сервисов по технической поддержке и гарантии, то CEPH может работать на обычных i386 серверах с использованием недорогого сетевого оборудования. Да, конечно же, чтобы использовать это решение в штате компании должны быть квалифицированные специалисты, понимающие как оно работает и умеющие его настраивать. Как правило, такие специалисты немногочисленны на рынке труда и стоят хороших денег. Однако, и специалисты по серьезным коммерческим системам хранения данных «редкие и дорогие птицы».
Эволюция данной программно-определяемой системы хранения данных показывает неплохие темпы и результаты. Последняя версия данного ПО на текущий момент под названием Octopus хорошо подтянула веб интерфейс. Теперь через графическую панель можно выполнять большое количество задач, оговорюсь сразу, что далеко не все. Раньше веб интерфейс CEPH предоставлял гораздо меньше возможностей и практически все операции проводились через командную строку. Также в последней версии добавилась возможность инсталляции кластера с помощью утилиты cephadm, устанавливаемой на первую ноду создаваемой системы хранения. При этом сам основной функционал хранилища данных в программном продукте CEPH уже давно хорошо себя зарекомендовал.
Процесс установки
Самый простой способ установки кластера CEPH — использование ansible плейбука и ansible ролей от самих разработчиков софта — ceph-ansible. Для использования этого репозитария скачиваем его c github к себе на управляющий хост с помощью команды:
# git clone https://github.com/ceph/ceph-ansible
После этого переходим в директорию с локальным репозитарием ceph-ansible. Нам нужно выбрать ветвь репозитария, в соответствии с которой будет происходить установка кластера. Так stable-5.0 используется для установки последнего стабильного на текущий момент релиза CEPH v15.x.x — Octopus. Чтобы выбрать эту версию выполняем следующую команду:
# git checkout stable-5.0
Далее необходимо проверить в файлике requirements.txt модули Python, которые должны быть установлены в системе на управляющем хосте, и установить их соответствующим образом. К примеру, это можно сделать с помощью команды pip.
# pip install -r requirements.txt
Теперь необходимо настроить инвентарь Ansible в соответствии с запланированным функционалом каждого хоста в кластере CEPH. Допустим, в нашем примере мы будем использовать 3 сервера (192.168.1.101, 192.168.1.102, 192.168.1.103), на каждом из которых должны быть установлены сервисы MON, OSD, MGR, grafana-server. То есть, каждый сервер будет выполнять роль мониторинга кластера, иметь возможность подключать диски, а также обеспечивать интерфейс управления. Для этого в рабочей директории ceph-ansible создаем файлик inventory_hosts, в котором указываем следующее содержание.
[mons]
192.168.1.101
192.168.1.102
192.168.1.103
[osds]
192.168.1.101
192.168.1.102
192.168.1.103
[mgrs]
192.168.1.101
192.168.1.102
192.168.1.103
[grafana-server]
192.168.1.101
192.168.1.102
192.168.1.103
Как Вы понимаете, чтобы плейбук успешно отработал на указанных хостах, на них должен присутствовать ssh rsa публичный ключ с управляющего хоста. Для этого необходимо скопировать этот ключик на эти сервера, если это еще не было сделано до этого.
После этого необходимо немного модернизировать файлы с переменными в подпапке group_vars. В нашем примере с учетом выбранных сервисов, которые будут задействованы в кластере, нам нужно провести следующие манипуляции.
# cp ./group_vars/all.yml.sample ./group_vars/all.yml
# cp ./group_vars/mons.yml.sample ./group_vars/mons.yml
# cp ./group_vars/osds.yml.sample ./group_vars/osds.yml
Если в кластере CEPH будут реализованы дополнительно другие сервисы, то необходимо будет переименовать также и другие файлы с переменными.
Давайте посмотрим по нашему примеру значимое содержимое файлов с переменными. Так файл ./group_vars/all.yml выгляди следующим образом. В нашем случае мы используем одну подсеть 192.168.1.0/24 для удаленного доступа к хостам кластера, балансировки кластера и доступа к CEPH со стороны клиентов. Поэтому значения переменных monitor_address_block, public_network, cluster_network будут идентичными.
---
grafana_server_group_name: grafana-server
ceph_origin: repository
ceph_repository: community
ceph_stable_release: octopus
generate_fsid: true
monitor_address_block: 192.168.1.0/24
journal_size: 5120 # OSD journal size in MB
public_network: 192.168.1.0/24
cluster_network: 192.168.1.0/24
dashboard_enabled: True
dashboard_protocol: https
dashboard_port: 8443
dashboard_admin_user: your_user
dashboard_admin_password: your_password
dashboard_crt: ''
dashboard_key: ''
grafana_admin_user: your_user
grafana_admin_password: your_password
Содержимое файла ./group_vars/mons.yml представлено ниже.
---
dummy:
И содержание файла ./group_vars/osds.yml далее. В данном случае мы задействуем для хранения данных в кластере CEPH диски /dev/sdb и /dev/sdc на каждом из хостов.
---
dummy:
devices:
- /dev/sdb
- /dev/sdc
osd_auto_discovery: false
Теперь осталось подработать сам ansible плейбук, который проводит саму установку CEPH. Для этого вначале копируем его из шаблона с помощью следующей команды:
# cp ./site.yml.sample ./site.yml
После этого редактируем файл ./site.yml таким образом, чтобы он содержал только команды, релевантные сервисам CEPH, которые мы будем устанавливать. В данном случае это MON, OSD, MGR, grafana-server. Всю остальную информацию из файлика удаляем.
---
# Defines deployment design and assigns role to server groups
- hosts:
- mons
- osds
- mgrs
- grafana-server
gather_facts: false
any_errors_fatal: true
become: true
tags: always
vars:
delegate_facts_host: True
pre_tasks:
# If we can't get python2 installed before any module is used we will fail
# so just try what we can to get it installed
- import_tasks: raw_install_python.yml
- name: gather facts
setup:
gather_subset:
- 'all'
- '!facter'
- '!ohai'
when:
- not delegate_facts_host | bool or inventory_hostname in groups.get(client_group_name, [])
- name: gather and delegate facts
setup:
gather_subset:
- 'all'
- '!facter'
- '!ohai'
delegate_to: "{{ item }}"
delegate_facts: True
with_items: "{{ groups['all'] | difference(groups.get('clients', [])) }}"
run_once: true
when: delegate_facts_host | bool
tasks:
- import_role:
name: ceph-defaults
- import_role:
name: ceph-facts
- import_role:
name: ceph-validate
- import_role:
name: ceph-infra
- import_role:
name: ceph-common
- hosts: mons
gather_facts: false
become: True
any_errors_fatal: true
pre_tasks:
- name: set ceph monitor install 'In Progress'
run_once: true
set_stats:
data:
installer_phase_ceph_mon:
status: "In Progress"
start: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
tasks:
- import_role:
name: ceph-defaults
tags: ['ceph_update_config']
- import_role:
name: ceph-facts
tags: ['ceph_update_config']
- import_role:
name: ceph-handler
tags: ['ceph_update_config']
- import_role:
name: ceph-config
tags: ['ceph_update_config']
- import_role:
name: ceph-mon
- import_role:
name: ceph-mgr
when: groups.get(mgr_group_name, []) | length == 0
post_tasks:
- name: set ceph monitor install 'Complete'
run_once: true
set_stats:
data:
installer_phase_ceph_mon:
status: "Complete"
end: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
- hosts: mgrs
gather_facts: false
become: True
any_errors_fatal: true
pre_tasks:
- name: set ceph manager install 'In Progress'
run_once: true
set_stats:
data:
installer_phase_ceph_mgr:
status: "In Progress"
start: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
tasks:
- import_role:
name: ceph-defaults
tags: ['ceph_update_config']
- import_role:
name: ceph-facts
tags: ['ceph_update_config']
- import_role:
name: ceph-handler
tags: ['ceph_update_config']
- import_role:
name: ceph-config
tags: ['ceph_update_config']
- import_role:
name: ceph-mgr
post_tasks:
- name: set ceph manager install 'Complete'
run_once: true
set_stats:
data:
installer_phase_ceph_mgr:
status: "Complete"
end: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
- hosts: osds
gather_facts: false
become: True
any_errors_fatal: true
pre_tasks:
- name: set ceph osd install 'In Progress'
run_once: true
set_stats:
data:
installer_phase_ceph_osd:
status: "In Progress"
start: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
tasks:
- import_role:
name: ceph-defaults
tags: ['ceph_update_config']
- import_role:
name: ceph-facts
tags: ['ceph_update_config']
- import_role:
name: ceph-handler
tags: ['ceph_update_config']
- import_role:
name: ceph-config
tags: ['ceph_update_config']
- import_role:
name: ceph-osd
post_tasks:
- name: set ceph osd install 'Complete'
run_once: true
set_stats:
data:
installer_phase_ceph_osd:
status: "Complete"
end: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
- hosts:
- mons
- osds
- mgrs
gather_facts: false
become: True
any_errors_fatal: true
tasks:
- import_role:
name: ceph-defaults
- import_role:
name: ceph-facts
tasks_from: container_binary.yml
- import_role:
name: ceph-handler
- import_role:
name: ceph-crash
- hosts: mons
gather_facts: false
become: True
any_errors_fatal: true
tasks:
- import_role:
name: ceph-defaults
- name: get ceph status from the first monitor
command: ceph --cluster {{ cluster }} -s
register: ceph_status
changed_when: false
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
- name: "show ceph status for cluster {{ cluster }}"
debug:
msg: "{{ ceph_status.stdout_lines }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
when:
- ceph_status is not skipped
- ceph_status is successful
Когда все подготовительные работы завершены, запускаем плейбук с помощью следующей команды и получаем в результате ее завершения работающий кластер CEPH. Время выполнения плейбука может быть порядка 10 — 20 минут.
# ansible-playbook ./site.yml -i ./inventory_hosts
После успешного завершения отработки плейбука, можно начинать использовать CEPH либо через веб интерфейс, либо через CLI в SSH.
Заключение
Оба продукта — CEPH и Ansible разрабатываются компанией Red Hat. Кроме того, они успешные и реализовавшиеся. Поэтому вполне логично, что довольно-таки сложный процесс развертывание кластера CEPH организуется с помощью плейбука Ansible от разработчиков. При этом ceph-ansible поддерживает различные версии CEPH и находится в постоянной доработке.