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

Не так давно мне пришлось поднимать 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/

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 24

    –1
    Очень интересно. Спасибо!
      –1
      Спасибо. будем применять!
        +4
        Обращаю внимание, что выполняется команда restart, а не reload. Если, не дай Бог, вы не поставите запятую в конфиге nginx и он упадёт на ста машинах, вы также быстро поправите ошибку и на ста машинах он поправится.
        Эмм, может наоборот? reload делает проверку конфига и при синтаксической ошибке не перегружает конфиг. Рестарт тупо гасит и поднимает сервер, что само по себе недопустимо на «высоконагруженном проекте».
          0
          Совершенно верно, писал вечером — перепутал. Спасибо, в топике поправил!
            +1
            Пожалуйста. Забавно, что мне за это в качестве благодарности два минуса в К прилетело. -)
            Хотя, может это от торопыги снизу ↓.
          –8
          Ааааааа! Они канпеляют в deb-based дистрибутивы программы из сорцов! Сделайте меня развидеть это.
          А вообще интересно, покопаю потом эту штучку.
          Есть ещё puppet для автоматизации управления серверами.
            +1
            Топик не читай!
            @
            Сразу пиши!
            0
            А можно использовать довольно необычный способ, указав при конфигурации (./configure) csync2 путь к тарболлу с библиотекой:
            ./configure --with-libsqlite-source=/path/to/libsqlite.tar.gz

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

              Я повторюсь, программа не новая, а поэтому компиляция из исходников скорее всего и не потребуется, она приведена лишь для полноты информации.
              0
              Если ssl использовать не планируется, то надо добавить в /etc/csync2.cfg
              nossl *-sync *-sync;

              Также надо проверить, что csync2 добавился в inetd, если что добавить
              csync2 stream tcp nowait root /usr/local/sbin/csync2 csync2 -i

                0
                Да, и в /etc/services еще должен быть прописан TCP port 30865.
                0
                >Существуют системы, позволяющие нодам подгружать удалённые конфиги.
                А разве на csync2 нельзя простыми средствами организовать?

                  0
                  не понял вопрос, топик как раз и рассказывает о том, как это «по-простому» организовать на csync2
                    0
                    В контексте «если вы каждый день меняете машины в кластере», разве csynс2 не позволяет подгружать удалённые конфиги?
                      0
                      Нет, он просто синхронизирует уже установленные ноды, а указанные в конце топика программы позволяют раздавать разным нодам разные конфиги, а конфигурирацию производить на одной управляющей машине. Пример: wiki.opscode.com/display/chef/Architecture
                        0
                        csync2+chroot разве не позволяет реализовать тоже самое?
                        chef-client жрёт много ОЗУ (
                          0
                          На всякий поясню — [x]inetd делает chroot на основании хоста…
                  0
                  csync2+chroot разве не позволяет реализовать тоже самое?
                  chef-client жрёт много ОЗУ (
                    0
                    упс ff упал, после поднятия не туда запостил (
                    0
                    Хотел бы уточнить такой момент, чтобы синхронизировать полностью три ноды, надо запускать csync -x на одной ноде, или на всех?
                      0
                      Изменения, которые произошли на ноде 1 при запуске на ней csync2 перельются на ноды 2 и 3
                      Изменения, которые произошли на ноде 2 при запуске на ней csync2 перельются на ноды 1 и 3
                        0
                        Понял вас, спасибо своевременный за ответ.
                      0
                      > Согласитесь, удобно иметь набор файлов (например конфигов), которые всегда буду одинаково выглядеть на серверах с одинаковой ролью?

                      Для этого git лучше подходит: в дополнение к синхронизации получим историю изменений.
                        0
                        Мне часто поступают вопросы, что делать, если появилась ошибка Could not connect?

                        Чаще всего на стороне принимающей ноды не запущен listener или закрыт порт 30865.

                        Для запуска listener вручную запустите на принимающей ноде команду
                        csync2 -ii &

                        Для проверки порта c другой ноды просканьте порт nmap; ом
                        nmap IP -p 30865


                        Теперь всё должно работать!

                        Only users with full accounts can post comments. Log in, please.