Используя 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
onyxmaster
Спасибо. Немного не по теме, но можете что-нибудь про железки написать, на которых у вас это работает? Надеюсь раз вы показали графики, скорее всего не будет проблемой и рассказать про сетевые карты, коммутаторы и диски.
vankosa Автор
В качестве серверов взяли какие то не очень молодые супермикры, которые особо уже не нужны были. Сетевушки соединены с коммутаторами по SFP 10G, собраны в бондинг (LACP). Диски обычные сата, на них нагрузки в данном случае нет вообще (если не считать логирование VRRP, RGW и gobetween). Можно, конечно, расширить статью описанием поднятия бондинга, но это и так уже миллион раз обсосано
onyxmaster
Спасибо. Про бондинг вопросов нет.