Персональное облачное хранилище своими руками

Облачные сервисы хранения данных сегодня находятся на пике своей популярности. Действительно, иметь возможность получить доступ к своим данным из любого места, где есть подключение к интернету — это очень удобно. Однако, все больше людей начинает задумываться о безопасности данных в публичном облаке. Подлила масла в огонь и программа PRISM, о которой нам поведал белогвардеец Эд.

Спойлер OwnCloud — продукт с открытым исходным кодом, который создан для того, чтобы вернуть данные под контроль их владельцев. Он выступает альтернативой таким монстрам, как Dropbox, iCloud, SkyDrive и иже с ними. имеет удобный веб-интерфейс, встроенный WebDav и десктопных клиентов для синхронизации файлов.

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

Вместо предисловия

OwnCloud умнеет работать со встроенной БД sqlite и . Дальше речь будет идти только о работе с БД . Настройка веб-сервера и установка OwnCloud в этой записи так же не рассматриваются.

Задача организации облачного хранилища файлов на базе OwnCloud с резервированием на уровне сервера в таком виде сводится к двум подзадачам:

  1. Настройка синхронизации файлов
  2. Настройка репликации БД MySQL

Настройка синхронизации файлов

В этом направлении есть два возможных пути решения. Первый — распределенная файловая система. В этом случае данные будут храниться на всех серверах с определенным уровнем резервирования, при этом элементом «RAID» будут являться не диски внутри сервера, а сервер в совокупности. В настоящее время разрабатывается довольно много ПО для реализации распределенного хранилища, среди них: lustre, ceph, glusterfs, openAFS и список можно продолжать. Увы, подобные решения довольно требовательны к ресурсам и обладают меньшей производительностью, чем при работе с обычной файловой системой. Поэтому рассматривать их мы не будем. В этой статье будет рассмотрен второй путь — синхронизация файлов.

На этом пути тоже есть из чего выбирать. Например, про csync2 для синхронизацию конфигурационных файлов уже говорилось ранее. Но, применительно к текущей задаче, у csync2 есть несколько недостатков. Во-первых, он использует sqlite для хранения информации о файлах, что при большом количестве файлом является существенной проблемой. Во-вторых, синхронизация запускается по расписанию, а не по событию, такому как загрузка нового файла.

Начиная с версии 2.6.13 в ядро включена подсистема, которая позволяет получать уведомления об изменениях в файловой системе — . На основе работает lsyncd — демон, который следит за изменениями в локальных директориях и с заданным интервалом времени запускает средство синхронизации, например rsync.

В Debian/Ubuntu может быть установлен из стандартного репозитория:

apt-get install lsyncd

Для конфигурационного файла lsyncd используется скриптовый язык Lua. В нашем случае файл /etc/lsyncd/lsyncd.conf.lua должен выглядеть так:

settings = {
logfile    = "/var/log/lsyncd.log",
statusFile = "/var/run/lsyncd.status",
statusInterval = 10,
}
sync {
default.rsyncssh,
source = "/var/www/owncloud",
host = "192.168.2.2",
targetdir = "/var/www/owncloud",
rsyncOps = {"-ausS", "--temp-dir=/tmp"},
delay = 10,
}
sync {
default.rsyncssh,
source = "/var/www/owncloud",
host = "192.168.3.2",
targetdir = "/var/www/owncloud",
rsyncOps = {"-ausS", "--temp-dir=/tmp"},
delay = 10,
}

В приведенной конфигурации синхронизация посредством rsync запускается поверх ssh, для работы необходимо настроить перекрестную авторизацию между серверами по публичным ключам.

  • rsyncOps — опции, с которыми запускается rsync,
  • delay — время в секундах, в течении которого накапливаются изменения для синхронизации.

Подробности и другие возможные способы синхронизации доступны в официальной документации.

Данный файл конфигурации необходимо распространить по серверам, заменяя значение параметра «host», для обеспечения взаимной синхронизации.

Запускаем синхронизацию:

service lsyncd start

Дополнительно хочу отметить, что inotify имеет несколько параметров ядра Linux. Возможно их придется скорректировать для больших инсталляций:

  • fs.inotify.max_queued_events — максимальное число событий в очереди,
  • fs.inotify.max_user_instances — сколько экземпляров inotify может запустить один пользователь,
  • fs.inotify.max_user_watches — сколько элементов может отслеживать один пользователь.

Настройка репликации БД MySQL

В этом блоге я уже описывал настройку master-master репликации mysql для двух серверов. На этот раз серверов три и задача немного усложняется, репликация будет организована по кольцу.

Необходимо загрузить дамп БД с основного сервера на два дополнительных и привести конфигурацию MySQL к следующему виду:

server-id                = 1
replicate-same-server-id = 0
auto_increment_increment = 3
auto_increment_offset    = 1
log_bin                  = /var/log/mysql/mysql-bin.log
expire_logs_days         = 3
max_binlog_size          = 100M
log-slave-updates
replicate-wild-do-table  = owncloud.%

Значения параметров:

  • server-id — уникальный идентификатор сервера, должен быть различным у всех серверов, которые учатсвуют в репликации.
  • replicate-same-server-id — предотвращает зацикливание репликации, сервер обрабатывает только бинарные логи, идентификатор сервера которого отличается от текущего.
  • auto-increment-increment — шаг изменения AUTO_INCREMENT, должен равняться числу узлов n.
  • auto-increment-offset — начальное значение AUTO_INCREMENT, от 1 до n, на каждом узле.
  • log-slave-updates — заставляет mysql писать изменения из реплицируемых бинарных логов в свой бинарный лог, необходимо для кольцевой репликации.
  • replicate-wild-do-table — в моем случае серверы используются под разные задачи и необходимо реплицировать только БД OwnCloud.

Дальше можно настраивать репликацию по схеме:
MySQL 3-node replication

Для этого выполняем на серверах последовательно:
server-id = 1

CHANGE MASTER TO MASTER_HOST = '192.168.3.2', MASTER_USER = 'replic', MASTER_PASSWORD='secret';
START SLAVE;

server-id = 2

CHANGE MASTER TO MASTER_HOST = '192.168.1.2', MASTER_USER = 'replic', MASTER_PASSWORD='secret';
START SLAVE;

server-id = 3

CHANGE MASTER TO MASTER_HOST = '192.168.2.2', MASTER_USER = 'replic', MASTER_PASSWORD='secret';
START SLAVE;

После этого проверяем состояние репликации:

SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.3.2
Master_User: replic
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 669263
Relay_Log_File: mysqld-relay-bin.000023
Relay_Log_Pos: 88701
Relay_Master_Log_File: mysql-bin.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: owncloud.%
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 669263
Relay_Log_Space: 88901
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3
1 row in set (0.00 sec)