null

Мониториг Ceph с помощью Zabbix

Жил был кластер Ceph, при развёртывании которого сначала была установлена версия mimic (13), а в последствии Ceph был обновлён до nautilus (14). И мониторился он старым добрым Zabbix-ом с использованием template под названием ceph-mgr Zabbix module. Логика работы была довольно простой - текущий активный mgr узел через zabbix_sender отправлял данные на Zabbix сервер, и всё было хорошо.

И вот наступил момент обновления Ceph, который поэтапно был обновлён до версии squid (19), при этом был произведён переход с ceph-deploy на cephadm, и, соответственно, теперь все процессы Ceph работают в своих контейнерах. Последнее изменение очевидным образом ломает старую логику работы мониторинга, так как, например, в образе контейнера просто нет команды zabbix_send.

Изучение документации показало, что оказывается ещё во времена nautilus (14) для мониторинга уже можно было использовать новый template Ceph by Zabbix agent 2, который, как следует из названия, требует установки Zabbix agent 2 на стороне клиента, что, не являлось проблемой после перехода на Debian 12 ​​​​​​​, и уже использует модель, когда Zabbix сервер обращается к клиенту за данными. А вот тут возникла проблема.

Согласно документации, логика работы Ceph такова, что RESTful API поднимается только на том mgr узле, который сейчас является активным. А в кластере таких узлов должно быть 3 или 5. И возникает вопрос - которому из узлов добавлять template для мониторинга Ceph? Даже если добавить template для всех узлов, то всё равно:

  1. Будешь получать ложные срабатывания о недоступности кластера Ceph при переключении активного mgr
  2. Всякие графики тоже будет необходимо "склеивать" из графиков с нескольких узлов.

Теоретически в Ceph можно получить URL текущего активного mgr, но, к сожалению, Zabbix не умеет использовать в качестве значения макроса значение, возвращаемое другим Item.

В качестве решения возникла идея поднимать плавающий логический IP адрес на активном узле. Для решения этой задачи в linux есть старый добрый Keepalived, который ещё и умеет запускать внешние скрипты для выбора мастера.

Так как информацию о текущем активном mgr можно получить используя команду:

ceph mgr dump

Которая выводит свои данные в формате JSON, то желание использовать простой shell скрипт для обработки вывода очень быстро испарилось, ну а так как сама утилита ceph написана на языке python, то возникла мысль её не использовать, а обратиться из python в Ceph напрямую. С созданием скелета скрипта прекрасно справился ChatGPT, из которого, после небольшой обработки напильником, получился небольшой скриптик checkcephmgr:

#!/usr/bin/python3

import rados
import json
from socket import gethostname
from sys import exit

cluster = rados.Rados(conffile = '/etc/ceph/ceph.conf')
cluster.connect()

cmd = { 'prefix': 'mgr dump', 'format': 'json', }

ret, buf, err = cluster.mon_command(json.dumps(cmd), b'')

mgr = json.loads(buf.decode())

exit(0 if gethostname() == mgr['active_name'] else 1)

Обработка ошибок опущена просто потому, что при их возникновении также будет установлен ненулевой код возврата, что целиком и полностью нас устраивает.

После чего можно приступить к настройке Keepalived, наполнив /etc/keepalived/keepalived.conf примерно таким содержимым:

vrrp_script checkcephmgr {
    script "/path/to/checkcephmgr"
    interval 30
    weight 10
    fall 2
    rise 1
}

vrrp_instance cloud_vip {
    interface br128
    state BACKUP
    virtual_router_id 254
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass SOMEPASS
    }

    virtual_ipaddress {
        192.168.X.254
    }

    track_script {
        checkcephmgr
    }
}

Где необходимо:

  • исправить путь к скрипту checkcephmgr;
  • убедиться в том, что никто в этом широковещательном домене не использует такой же VRRP ID;
  • указать свой уникальный не более чем восьмибуквенный пароль;
  • исправить плавающий IP адрес.

После запуска keepalived будет раз в 30 секунд запускать скрипт, на том узле, на котором сейчас работает активный mgr, скрипт будет возвращать 0, соответственно только на этом узле будет установлен приоритет VRRP равный 110, и, соответственно, плавающий IP адрес будет поднят именно на нужном узле.

Теперь можно пойти в Zabbix, создать для мониторинга Ceph отдельный узел, которому указать плавающий IP адрес и добавить template Ceph by Zabbix agent 2.

После чего можно убедиться в том, что какие-то данные из Ceph уже получаются, но... некоторые значения не могут быть получены с ошибкой Access denied. Для решения и этой проблемы на стросторах интернетов был найден скрипт:

for mgr in $(ceph auth ls | grep ^mgr)
do
  ceph auth caps ${mgr} mds 'allow *' mon 'allow *' osd 'allow *'
done

Который необходимо выполнить на одном из узлов кластера Ceph, после чего mgr получит чуть больше привелений при обращении к mon.

Странно, но о необходимости такого расширения прав не написано ни в описании template на сайте Zabbix, ни в соответствующих разделах документации Ceph.

Теперь, наконец, можно наслаждаться работающим мониторингом.

Next

Коротко о себе:

Работаю в компании Tune-IT и тьютором кафедры Вычислительной техники в СПбГУИТМО.

Очень люблю команду cat, core solaris и IPv6.