Pull to refresh

csync2 или как облегчить работу с кластером

System administration *
Sandbox
Не так давно мне пришлось поднимать Linux кластер для одного довольно нагруженного проекта. Вернее сказать более важным был вопрос отказоустойчивости, чем нагрузки, но обычно кластер призван решить обе эти проблемы единовременно.
В данном случае я не собираюсь рассматривать архитектуру кластера или нюансы отладки, а рассказать о весьма удобном способе управления кластером, ускорении его настройки и отладки.

Согласитесь, удобно иметь набор файлов (например конфигов), которые всегда буду одинаково выглядеть на серверах с одинаковой ролью? Под катом я расскажу, как этого добиться за максимально короткий срок.

В описываемом кластере семь выделенных серверов, которые общаются друг с другом по внутренней сети со следующими hostname:

Load Balancers lb1 lb2
Application Servers app1 app2
Database Servers db1 db2
Backup server bckp1


А герой сегодняшнего рассказа — csync2, довольно старая программа, которая доступна во многих nix репозиториях, а также может быть скачана в виде tarball или из git репозитория.

Итак, пошаговое руководство по установке, настройке и извлечению пользы из csync2.

Установка


Установка должна быть произведена на всех нодах кластера:

Из репозиториев debian\ubuntu

apt-get install csync2 -y

Из исходников

Перед установкой убедитесь, что у вас в системе присутствует librsync
В противном случае вам необходимо скачать librsync-0.9.7.tar.gz,
и установить его
tar -xf librsync-0.9.7.tar.gz && cd librsync-0.9.7
./configure && make
make install


Также csync2 надеется на наличие libsqlite, которую тоже можно скомпилировать из исходных кодов:
wget www.sqlite.org/sqlite-autoconf-3070603.tar.gz && tar -xf sqlite-autoconf-3070603.tar.gz && cd sqlite-autoconf-3070603
./configure && make
make install


А можно использовать довольно необычный способ, указав при конфигурации (./configure) csync2 путь к тарболлу с библиотекой:
./configure --with-libsqlite-source=/path/to/libsqlite.tar.gz

Других требований я не получал, да и в связи с возрастом программа имеет прекомпилированные пакеты для большинства OS (RedHat RPM, apt-get \ aptitude install csync2, FreeBSD ports)

Скомпилируем сам csync2
cd /usr/local/src && wget oss.linbit.com/csync2/csync2-1.34.tar.gz
tar -xf csync2-1.34.tar.gz && cd csync2-1.34
./configure && make
make install


Я проводил все операции под Ubuntu 10.04 LTS, где csync2 устанавливается одной строчкой.
Если в вашей OS что-то пошло не так — пишите в комментариях, постараюсь помочь.

Первичная настройка


Итак у нас есть установленный csync2 на всех нодах, необходимо связать их воедино и заставить обмениваться файлами между собой.

csync2 обменивается файлами посредством шифрованного SSL соединения, поэтому нужно создать единый csync2-сертификат, который позволит серверам «доверять» друг другу:

Согласно инструкции можно в папке с исходниками выполнить команду
make cert
или (как делал я), сгенерировать сертификат вручную:
openssl genrsa -out /etc/csync2_ssl_key.pem 1024
openssl req -new -key /etc/csync2_ssl_key.pem -out /etc/csync2_ssl_cert.csr
openssl x509 -req -days 600 -in /etc/csync2_ssl_cert.csr -signkey /etc/csync2_ssl_key.pem -out /etc/csync2_ssl_cert.pem


После чего нужно запустить генерацию ключа csync2:
csync2 -k /etc/csync2.cluster.key

Выполнение этой команды занимает довольно длительное время, после чего появляется файл /etc/csync2.cluster.key

Теперь необходимо скопировать его на все ноды вашего кластера, чтобы они оказались в едином облаке синхронизации. Ключей можно создать несколько, чтобы, к примеру, сервера баз данных не могли связываться с серверами Application, но на мой взгляд это совсем не обязательно, если вы не строите кластер для банка.

Первая синхронизация


Самый главный файл программы — /etc/csync2.cnf
Работает он по следующему принципу.
Вы задаёте логические группы серверов и указываете, что в них общего?
Например я использую внутреннюю адресацию не по IP, а по hostname, соответственно я хочу, чтобы файл /etc/hosts у меня на всех-всех машинах был одинаковый, а при добавлении новой ноды мне было достаточно единожды его изменить, все изменения утекли бы на остальные ноды кластера и они знали, кто такой app3, к примеру.
На LoadBalancer'ах у меня стоит nginx, у которого тоже должен быть один и тот же конфиг на разных машинах.

Итак в конфиг-файле я объединяю свои сервера в логические группы:
# Все сервера синхронизируют базовый набор конфигов
group all {
# список хостов или IP, которые входят в эту логическую группу
host app1 app2;
host db1 db2;
host lb1 lb2;
host bckp1;

# ключ авторизации
key /etc/csync2.cluster.key;

# какие файлы \ папки необходимо синхронизировать?
include /etc/hosts; # файл hosts
include /etc/csync2.cfg; # оппа! сам конфиг csync2 тоже можно сюда положить! ;)

auto younger;# как разрешить конфликты? Какой файл новее - тот и правильный
}

# А на серверах LoadBalancer'ов я хочу ещё синхронизировать все конфиги nginx
group lb {
host lb1 lb2;

key /etc/csync2.cluster.key;

include /etc/nginx/*;
auto younger;
}


Теперь запустим csync2 с указанием синхронизировать всё, что можно синхронизировать:
csync2 -x

После первичной авторизации все хосты синхронизируются и указанные вами файлы станут одинаковыми на всех нодах.

Возможные проблемы

Если что-то пошло не так, запустите
csync2 -xv
csync2 -xvv

и т.д.

У меня csync2 ругался на отсутствие доступа на запись /etc/hosts на других машинах, эта проблема сама собой разрешалась после того, как на них первый раз также был запущен csync2.
Если csync2 ругается на SSL — проверьте, скопирован ли на все хосты файл /etc/csync2.cluster.key и правильно ли указан в конфиге.

Других проблем у меня не возникало, если у вас что-то иное — пишите, разберёмся.

Вкусности


Синхронизация всех нужных конфигов это классно, я положил в csync2 конфиги от mysql, php, nginx и так далее. Очень удобным оказалось положить конфиг от csync2 в сам csync2 (почти рекурсия).
Но просто синхронизировать файлы — это далеко не всё.
После изменения файлов nginx, его же надо перезагрузить! А если это надо сделать на ста машинах?

В группу серверов с одинаковой ролью, на которых установлен nginx добавляем:
group lb {
host lb1;
host lb2;
key /etc/csync2.cluster.key;

include /etc/nginx; # какие файлы синхронизировать между этими серверами
action {
pattern /etc/nginx/*; # Какие файлы должны измениться, чтобы выполнилась команда?
exec "/etc/init.d/nginx reload"; # Что за команду запустить?
logfile "/var/log/csync2.actions.log"; # Куда записать вывод?
do-local; # Если указана эта директива, то команду выполнит и тот хост, на котором изначально изменился файл, а не только тот, который получил изменения
}
auto younger;
}


Замечательный пункт action позволяет нам выполнить произвольную bash команду после изменений в тех или иных файлах, в указанном примере он перезагрузит nginx.

Обращаю внимание, что выполняется команда reload, а не restart. Если, не дай Бог, вы не поставите запятую в конфиге nginx и он упадёт на ста машинах, вы также быстро поправите ошибку и на ста машинах он поправится. В принципе можно будет поменять конфиг csync2, но на это уйдёт драгоценное время downtime.

Заключение


Итак мы получили весьма безопасную возможность редактировать привычные нам конфиги без всяких ухищрений, как если бы у нас был всего один сервер, а изменения переливать на N других серверов.
Отмечу, что у csync2 нет головного сервера, поэтому изменения можно вносить на любую ноду и после запуска csync2 -x изменения выльются на остальные.

Я синхронизирую через csync2 не только конфиги, но собственно сами файлы проекта, часть которых загружается пользователями, поэому просто поместил csync2 в крон (догатайтесь на скольких нодах я это делал? верно, на одной и один раз! (: )

Примочки:

На днях я положил в csync2 файл authorized_keys и теперь со своей машины захожу на любую ноду без ввода пароля. Это здорово, когда пароли на всех нодах сложные и разные. А ещё можно скопировать на свой компьютер файл hosts и ходить на ноды по их внутренним именам.
Поверьте, когда вы устанавливаете, настраиваете и отлаживаете кластер даже из семи, как у меня машин, это сэкономит вам тонну времени.

Немного об устройстве

Работает csync2 очень просто. Список всех файлов, которые вы синхронизируете хранится в локальной sqlite базе и сверяется по timestamp. Хранить там сотни гигабайт файлов не получится, но мои 5-6 Gb, разбросанных по нескольким десяткам тысяч файлов он раскидывает весьма успешно. Если у вас файлов больше, не ставьте csync2 в частый крон, он поназапускает кучу копий и серверы начнут тормозить. Базу csync2 можно чистить и вообще проводить с ней всяческие манипуляции. В документации к программе (ссылка чуть ниже) также указана структура используемой БД, так что простор для творчества здесь велик.

Аналоги

Существуют системы, позволяющие нодам подгружать удалённые конфиги. Мне они не понравились, но если вы каждый день меняете машины в кластере, вам стоит на них взглянуть: Chef, Puppet.

============================
Полезные ссылки:
Документация к csync2 (PDF)
Официальный сайт csync2: http://oss.linbit.com/csync2/
Tags:
Hubs:
Total votes 36: ↑33 and ↓3 +30
Views 25K
Comments 24
Comments Comments 24

Posts