Установка кластера CEPH

13/12/2020

ceph

По-настоящему серьезное 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 и находится в постоянной доработке.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *