Thank you for reading this post, don't forget to subscribe!
Lsyncd позволяет отслеживать состояние каталога с помощью подсистемы ядра inotify, и при помощи утилиты синхронизации rsync, менять содержимое другого каталога, таким образом, приводя оба каталога к единому виду. Это может использоваться для зеркалирования кластерной системы или создания оперативного бэкапа (не путать с полноценной резервной копией).
Установка и тестовый запуск
Выполним установку lsyncd на CentOS, а также настроим сервис для синхронизации двух каталогов на локальном компьютере.
Установка
Выполняем команды:
yum install epel-release
yum install lsyncd
Разрешаем автозапуск сервиса:
systemctl enable lsyncd
Настройка и запуск
Открываем конфигурационный файл:
vi /etc/lsyncd.conf
Приводим его к виду:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
settings { logfile = "/var/log/lsyncd.log", statusFile = "/var/log/lsyncd.stat", statusInterval = 5, insist = true, nodaemon = false, } sync { default.rsync, source="/tmp/source", target="/tmp/target", } |
[/codesyntax]
* где:
- settings — общие настройки.
- logfile — путь до файла логов.
- statusFile — файл, в который заносятся изменения, найденные с помощью inotify.
- statusInterval — интервал в секундах для обновления statusFile.
- insist — позволяет продолжить работу сервиса, даже если одна или несколько целевых директорий недоступны.
- nodaemon — отключаться или нет от вызывающей стороны. Проще говоря, если разрешить, то будет больше информации по его работе. Для боевого режима можно отключить.
- sync — настройка для синхронизации конкретного ресурса. Для каждого создается своя секция sync.
- default.rsync — должен использоваться протокол для синхронизации rsync.
- source — источник, откуда синхронизируем данные.
- target — куда синхронизируем.
* в данном примере мы синхронизируем два каталога на локальном компьютере. Таким же образом, можно синхронизировать данные и в подмонтированных каталогах, например, по nfs или cifs (smb).
Создадим два тестовых каталога:
mkdir /tmp/source
mkdir /tmp/target
Перезапускаем сервис lsyncd:
systemctl restart lsyncd
Пробуем создать тестовый файл к каталоге-источнике:
touch /tmp/source/testfile
Ждем 5-10 секунд. Проверяем содержимое каталога-цели:
ls /tmp/target/
Мы должны увидеть файл:
testfile
Сервис готов к работе.
Синхронизация по сети (SSH)
Для корректной передачи данных по сети с помощью SSH, нужно настроить возможность беспарольного подключения, затем — сам Lsyncd. Рассмотрим оба процесса по очереди.
SSH без пароля (по сертификату)
На компьютере, с которого будем передавать файлы (lsyncd) генерируем ключи:
ssh-keygen -t rsa
… на все запросы просто нажимаем Enter.
Переносим id_rsa.pub на целевой компьютер (куда будем передавать данные с помощью lsyncd):
scp /root/.ssh/id_rsa.pub mid@192.168.1.15:/home/mid/.ssh/authorized_keys
* если мы получим ошибку scp: /home/<user>/.ssh/authorized_keys: No such file or directory, необходимо на удаленном компьютере создать каталог .ssh в профиле пользователя, которому мы пытаемся передать ключ. Например, командами, mkdir /home/mid/.ssh и chown mid:mid /home/mid/.ssh.
* обратите внимание, что мы передаем созданный ключ в каталог пользователя mid. Это значит, что мы будем подключаться к целевому компьютеру от этого пользователя. Важно, чтобы у последнего были подходящие права для редактирования файлов в целевой папке, в которую мы будем синхронизировать данные.
Пробуем подключиться к удаленному компьютеру:
ssh mid@192.168.1.15
Мы должны подключиться по SSH без ввода пароля. В противном случае, на целевом компьютере (к которому у нас не получилось подключиться) открываем конфигурационный файл для ssh:
vi /etc/ssh/sshd_config
И приводим опцию AuthorizedKeysFile к следующему значению:
AuthorizedKeysFile .ssh/authorized_keys
Перезапускаем sshd:
systemctl restart sshd
Снова пробуем подключиться по SSH.
Настройка Lsyncd для синхронизации по сети
Открываем конфигурационный файл:
vi /etc/lsyncd.conf
Добавляем блок настроек sync:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
sync { default.rsyncssh, source = "/tmp/source", host = "mid@192.168.1.15", targetdir = "/tmp/target", rsync = { _extra = { "-a" } } } |
[/codesyntax]
* где:
- default.rsyncssh — в качестве протокола будем использовать rsync через ssh.
- source — указываем источник данных.
- host — удаленный компьютер, на который будет идти передача данных. До знака @ указывается пользователь, под которым будет идти подключение.
- targetdir — каталог на удаленном хосте, в который будет выполняться синхронизация.
- rsync, _extra — дополнительные ключи запуска rsync. В нашем примере запускаем в режиме архивирования.
На целевом компьютере создаем каталог, куда будем синхронизировать данные:
mkdir /tmp/target
И не забываем назначить ему владельца, от пользователя которого мы планируем подключиться по ssh:
chown mid:mid /tmp/target
Также на целевом компьютере необходимо установить rsync.
а) на CentOS:
yum install rsync
б) на Ubuntu:
apt-get install rsync
После на компьютере источнике перезапускаем lsync:
systemctl restart lsyncd
Ждем 5-10 секунд и проверяем на целевом компьютере наличие файла:
ls /tmp/target/
Мы должны увидеть файл:
testfile
Передача по сети работает.
Полезные опции
Рассмотрим примеры использования некоторых настроек, которые могут показаться полезными.
Исключения
Мы можем настроить исключение файлов по маске, которые не нужно передавать в другую директорию. Это делается с помощью опций exclude или excludeFrom в разделе sync, например:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
sync { ... exclude = { '*.bak' , '*.tmp' }, } sync { ... excludeFrom="/etc/lsyncd.exclude", } |
[/codesyntax]
* в первом блоке мы исключим все файлы, которые заканчиваются на .bak или .tmp. Для второго мы будем использовать файл /etc/lsyncd.exclude, в котором перечислим исключения.
Для второго блока создаем файл с исключениями:
vi /etc/lsyncd.exclude
*.tmp
*.bak
testfile.txt
test/
* в данном примере мы игнорируем файлы, заканчиваются на .bak или .tmp,а также файл testfile.txt и содержимое каталога test.
Комментарии
Стоит обратить внимание, что комментарии в конфигурационном файле ставятся с помощью двух дефисов, например:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
sync { -- протокол синхронизации default.rsyncssh, -- источник данных source = "/tmp/source", -- сервер назначения host = "mid@192.168.1.15", -- каталог назначения targetdir = "/tmp/target", } |
[/codesyntax]
Порт SSH
Отдельный порт для подключения по ssh мы можем указать в блоке sync, разделе ssh:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
sync { default.rsyncssh, source = "/tmp/source", ... ssh = { port = 2222 } } |
[/codesyntax]
* в этом примере мы указываем использовать порт 2222 для подключения по SSH.
Ограничения
При необходимости, мы можем установить некоторые значения для ограничения или обхода ограничений. Настройки задаются в блоке settings:
[codesyntax lang="php"]
1 2 3 4 5 6 |
settings { ... statusInterval = 5 maxDelays = 900, maxProcesses = 6, } |
[/codesyntax]
* где:
- statusInterval — как говорилось выше, задает интервал обновления статус-файла в секундах. Чем ниже значение, тем быстрее файлы попадают в очередь для синхронизации.
- maxDelays — задает количество файлов в очереди, при достижении которого задачи синхронизации будут запускаться ниже таймера задержки.
- maxProcesses — максимальное количество процессов, которое сможет запустить lsync.
Установка прав
Мы можем задать права после синхронизации. Это настраивается в блоке sync, разделе rsync:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
sync { ... rsync = { ... owner=true, chown="nginx:nginx" chmod="775" perms=true } } |
[/codesyntax]
* где:
- owner — говорит, сохранять ли владельца файла.
- chown — задает конкретного владельца и группу.
- chmod — задает права на синхронизированные файлы.
- perms — говорит, сохранять ли права.
Возможные ошибки
В процессе настройки и эксплуатации системы, мы можем столкнуться с различными проблемами. Опишем решение некоторых из них.
1. Consider increasing /proc/sys/fs/inotify/max_user_watches
Данную ошибку мы можем увидеть в логе или статусе сервиса lsyncd. При этом, сама служба останавливается с ошибкой.
Причина: для оптимизации нагрузки, ядро Linux не позволяет сильно нагружать подсистему inotify. Но если мы указываем каталог синхронизации с большим количеством файлов, это приведет к тому, что мы упремся в установленный лимит.
Решение: необходимо увеличить предел наблюдения за ядром inotify. Для этого создаем файл настройки ядра:
vi /etc/sysctl.d/10-max_user_watches.conf
fs.inotify.max_user_watches = 524288
Применяем настройки:
sysctl -p /etc/sysctl.d/10-max_user_watches.conf
Перезапускаем сервис:
systemctl restart lsyncd
И проверяем его состояние:
systemctl status lsyncd
2. bash: rsync: command not found
Данную ошибку можно увидеть в статусе сервиса. При этом, сам сервис завершает свою работу. Полный лог имеет, примерно, такой вид:
… lsyncd[20316]: bash: rsync: command not found
… lsyncd[20316]: rsync: connection unexpectedly closed (0 bytes received so far) [sender]
… lsyncd[20316]: rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.3]
Причина: на компьютере, с которым мы устанавливаем соединение по rsync не установлена одноименная утилита.
Решение: для установки необходимого пакета выполняем подходящую команду.
а) на CentOS:
yum install rsync
б) на Ubuntu:
apt-get install rsync
На компьютере с lsync перезапускаем сервис:
systemctl restart lsyncd