Используя Ceph для хранения бэкапов c помощью их S3-совместимого хранилища RadosGW, мы пришли к тому, что один radosGW не справляется с возложенной на него нагрузкой и решили, что пора бы его разбалансировать с сопутствующей отказоустойчивостью. В итоге пришли к решению балансировки с помощью GoBetween (очень лёгкий L4 балансировщик, подробнее на gobetween.io), а отказоустойчивость организовали с помощью VRRP.
Вышла такая схема:
Нашу реализацию данного действа читайте ниже
Дано:
Задача:
Сделать балансировку с отказоустойчивостью для S3 хранилища, организованному с помощью RadosGW
Этапы:
На серверах установлен CentOS 7.4, сразу после установки ОС обновим всё:
Установим весь софт, который нам потребуется по ТЗ (кроме самого ceph, ибо сначала ставится только его репозиторий):
В данный момент у нас ещё не установлен Ceph, поэтому установим его:
Сразу настроим фаерволл, окрыв нужные порты и разрешив сервисы:
Выключим SELinux (на всякий случай):
Изначально кластер Ceph уже поднят, думаю, подробностей касаться мы тут не будем, тема не этой статьи, сразу перейдём к настройке radosGW.
Конфиг приведён для примера, в вашем случае некоторые параметры могут отличаться:
Не забываем скопировать ключ /etc/ceph/client.radosgw.gateway с любой ноды кластера Ceph
Запустим radosgw:
И добавим его в автостарт:
На master ноде (разница в опциях state и priority):
На backup ноде:
Перезапускаем и добавляем в автостарт (обе ноды):
Для начала скачаем и распакуем бинарник gobetween:
Пишем конфиг gobetween (для SSL соединений указываем местонахождение ключей). Конфиг на обеих нодах одинаковый:
Запуск gobetween производится следующей командой (в автостарт добавляйте любым удобным для вас способом):
Для проверки можно использовать любой S3 клиент, например, такие, как s3cmd или DragonDisk. Вариант проверки для s3cmd будет выглядеть так (при учёте, что в конфиге уже указан в качестве сервера s3.example.com):
Если у вас там уже есть хоть какой то bucket, то в выхлопе будет его имя, если бакетов нет, то будет пустой выхлоп.
Как это выглядит сейчас — можете увидеть на скрине снизу. Статистика за сутки (графики в гигабайтах в секунду):

Нагрузка снизилась значительно, затупов не осталось и теперь все бекапы успевают собраться за ночь (до этого уже в разгар рабочего дня могло ещё собираться).
Надеюсь, данная хаутушка поможет вам в ускорении и уменьшении нагрузки на radosgw
Вышла такая схема:
- master нода vrrp получает поток данных по http(s);
- gobetween раскидывает весь трафик на себя же и backup ноду vrrp;
- radosgw в свою очередь пишут непосредственно в ceph;
- в случае падения master ноды vrrp, backup нода берёт всю нагрузку на себя до тех пор, пока мастер не поднимется
Нашу реализацию данного действа читайте ниже
Дано:
- Кластер Ceph (Jewel)
- IP мониторов: 10.0.1.1, 10.0.1.2, 10.0.1.3
- Два железных сервера (CentOS)
- Первый сервер 10.0.0.1 (назовём его gbt1.example.com)
- Второй сервер 10.0.0.2 (gbt2.example.com)
- Общий IP будет 10.0.0.3 (s3.example.com)
- Домен example.com
Задача:
Сделать балансировку с отказоустойчивостью для S3 хранилища, организованному с помощью RadosGW
Этапы:
- Развернуть RadosGW на двух серверах
- Организовать отказоустойчивость с поомщью VRRP
- Организовать балансировку S3 трафика с помощью GoBetween
- Проверить
Подготовка (на обеих машинах всё идентично)
На серверах установлен CentOS 7.4, сразу после установки ОС обновим всё:
# yum -y update
Установим весь софт, который нам потребуется по ТЗ (кроме самого ceph, ибо сначала ставится только его репозиторий):
# yum -y install keepalived centos-release-ceph-jewel wget
В данный момент у нас ещё не установлен Ceph, поэтому установим его:
# yum -y install ceph-radosgw
Сразу настроим фаерволл, окрыв нужные порты и разрешив сервисы:
# firewall-cmd --permanent --add-port=18080/tcp # firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface enp2s0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT # firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface enp2s0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT # firewall-cmd --permanent --add-port=10050/tcp # firewall-cmd --reload
Выключим SELinux (на всякий случай):
# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux # setenforce 0
Разворачиваем RadosGW
Изначально кластер Ceph уже поднят, думаю, подробностей касаться мы тут не будем, тема не этой статьи, сразу перейдём к настройке radosGW.
Конфиг приведён для примера, в вашем случае некоторые параметры могут отличаться:
# cat /etc/ceph/ceph.conf [global] fsid = 01dea7f3-91f4-48d1-9d44-ba93d4a103c5 mon_host = 10.0.1.1, 10.0.1.2, 10.0.1.3 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.0.1.0/24 [client] rbd_cache = true [client.radosgw.gateway] rgw_frontends = civetweb port=18080 rgw_region = example rgw_region_root_pool = .example.rgw.root rgw_zone = example-s3 rgw_zone_root_pool = .example-s3.rgw.root host = s3 keyring = /etc/ceph/client.radosgw.gateway rgw_dns_name = s3.example.com rgw_print_continue = true
Не забываем скопировать ключ /etc/ceph/client.radosgw.gateway с любой ноды кластера Ceph
Запустим radosgw:
# systemctl start ceph-radosgw@radosgw.gateway
И добавим его в автостарт:
# systemctl enable ceph-radosgw@radosgw.gateway
Разворачиваем VRRP
На master ноде (разница в опциях state и priority):
# cat /etc/keepalived/keepalived.conf global_defs { notification_email { user@example.com } notification_email_from gbt@example.com smtp_server mail.example.com smtp_connect_timeout 30 router_id GBT1 } vrrp_instance VI_1 { state MASTER interface enp2s0 virtual_router_id 33 priority 101 advert_int 1 smtp_alert authentication { auth_type PASS auth_pass 123123123 } virtual_ipaddress { 10.0.0.3 } }
На backup ноде:
# cat /etc/keepalived/keepalived.conf global_defs { notification_email { user@example.com } notification_email_from gbt@example.com smtp_server mail.example.com smtp_connect_timeout 30 router_id GBT1 } vrrp_instance VI_1 { state BACKUP interface enp2s0 virtual_router_id 33 priority 100 advert_int 1 smtp_alert authentication { auth_type PASS auth_pass 123123123 } virtual_ipaddress { 10.0.0.3 } }
Перезапускаем и добавляем в автостарт (обе ноды):
# systemctl restart keepalived # systemctl enable keepalived
Разворачиваем GoBetween
Для начала скачаем и распакуем бинарник gobetween:
# wget https://github.com/yyyar/gobetween/releases/download/0.5.0/gobetween_0.5.0_linux_amd64.tar.gz # tar -xzf gobetween_0.5.0_linux_amd64.tar.gz -C /usr/local/bin/
Пишем конфиг gobetween (для SSL соединений указываем местонахождение ключей). Конфиг на обеих нодах одинаковый:
# cat /etc/gobetween.toml [logging] level = "debug" # "debug" | "info" | "warn" | "error" output = "/var/log/gobetween.log" [api] enabled = true # true | false bind = ":8888" # "host:port" cors = false # cross-origin resource sharing [defaults] max_connections = 0 # Maximum simultaneous connections to the server client_idle_timeout = "0" # Client inactivity duration before forced connection drop backend_idle_timeout = "0" # Backend inactivity duration before forced connection drop backend_connection_timeout = "0" # Backend connection timeout (ignored in udp) [servers] [servers.sample] protocol = "tls" bind = "0.0.0.0:443" balance = "roundrobin" [servers.sample.discovery] kind = "static" static_list = [ "10.0.0.1:18080 weight=1", "10.0.0.2:18080 weight=1" ] [servers.sample.tls] root_ca_cert_path = "/etc/exampleSSC-CA.crt" cert_path = "/etc/s3.example.com.crt" key_path = "/etc/s3.example.com.key" [servers.sample.healthcheck] fails = 1 passes = 1 interval = "2s" timeout="1s" kind = "ping" ping_timeout_duration = "500ms" [servers.sample2] protocol = "tcp" bind = "0.0.0.0:80" balance = "roundrobin" [servers.sample2.discovery] kind = "static" static_list = [ "10.0.0.1:18080 weight=1", "10.0.0.2:18080 weight=1" ] [servers.sample2.healthcheck] fails = 1 passes = 1 interval = "2s" timeout="1s" kind = "ping" ping_timeout_duration = "500ms"
Запуск gobetween производится следующей командой (в автостарт добавляйте любым удобным для вас способом):
# /usr/local/bin/gobetween -c /etc/gobetween.toml
Проверка
Для проверки можно использовать любой S3 клиент, например, такие, как s3cmd или DragonDisk. Вариант проверки для s3cmd будет выглядеть так (при учёте, что в конфиге уже указан в качестве сервера s3.example.com):
# s3cmd ls
Если у вас там уже есть хоть какой то bucket, то в выхлопе будет его имя, если бакетов нет, то будет пустой выхлоп.
Как это выглядит сейчас — можете увидеть на скрине снизу. Статистика за сутки (графики в гигабайтах в секунду):

Итоги
Нагрузка снизилась значительно, затупов не осталось и теперь все бекапы успевают собраться за ночь (до этого уже в разгар рабочего дня могло ещё собираться).
Надеюсь, данная хаутушка поможет вам в ускорении и уменьшении нагрузки на radosgw
