Так как Badoo активно развивается и количество сотрудников постоянно увеличивается, мы пришили к выводу, что централизованное резервное копирование гораздо удобнее, чем частичное копирование и хранение информации в различных местах.
В статье мы рассмотрим, как различными способами «забэкапить» довольно большое количество рабочих станций с помощью одного хранилища, не прибегая к серьёзным вложениям и избегая громоздкой реализации.
Заранее оговоримся, что бэкап не охватывает 100% сотрудников, так как не все хранят свои данные на локальных машинах, поэтому у нас не было цели сделать бэкап обязательно-принудительным.
Одной из основных сложностей централизованного бэкапа стало то, что сотрудники используют разные операционные системы.
Как же мы смогли собрать всех на одном сервере?
Примерная статистика, основанная на использовании нашей системы:
Mac OS ~ 66%;
Linux ~ 27%;
Windows ~ 7%.
А теперь подробнее, что скрывается за этими тремя ОС и каким образом мы будем настраивать их у пользователя.
1) Mac OS ― через Time Machine (в последних версиях Mac OS поддерживается из коробки, ниже 10.6 у нас просто нет), на стороне сервера — Netatalk;
2) Windows ― стандартными средствами через «Архивация и восстановление» (Backup and restore), на стороне сервера — Samba;
3) Linux ― несколько вариантов: samba, rsync (доступ по паролю); полноценный ssh отключён за ненадобностью и в целях безопасности.
Забежим вперёд и покажем, как будет выглядеть интерфейс управления пользователями, которые нуждаются в бэкапе:
Администратору нужно выбрать уже существующую учетную запись или завести новую, сгенерировать пароль и указать тип операционной системы.
Аппаратная часть
В качестве хранилища был собран сервер с 24 дисками по 3.5 дюйма и 3 TБ ― большой объём за малые деньги.
Каждый диск монтируется отдельно, RAID или LVM не используется ― при выходе из строя одного из дисков его можно быстро заменить; также решается вопрос с недостатком свободного места: из всех дисков мы выжимаем максимум объёма.
«Что будет, если умрёт один из дисков, на котором были бэкапы пользователей?» ― спросите вы. Попросим забэкапиться ещё раз после замены диска. Вероятность того, что один из 24 дисков умрёт вместе с ноутбуком сотрудника, действительно мала. В крайнем случае мы попытаемся восстановить утраченную информацию.
Главная функция сервера ― хранение информации, поэтому описывать CPU и память не имеет смысла, любые современные процессоры справятся с этим заданием.
Готовим диски
Форматируем и монтируем каждый диск:
parted /dev/sd${i} -s mklabel gpt parted /dev/sd${i} mkpart primary 0GB 2996GB mkfs.ext3 /dev/sd${i}1
Удаляем зарезервированное пространство суперпользователя:
tune2fs -m 0 /dev/sd${i}1
В /etc/fstab для каждого раздела прописываем
UUID=${UUID} /storage/sd${i}1 ext3 noatime,acl,user_xattr,usrquota 0 0
В итоге получаем диски, смонтированные в директорию /storage/sd${i}, где ${i} ― одна из букв нашего диска.
Монтировать диски лучше с привязкой по UUID, т.к. не исключено «перемешивание» дисков, а с таким количеством устройств нам придётся долго восстанавливать правильные пути после внезапной перезагрузки сервера.
Всех пользователей мы будем ограничивать квотой в файловой системе стандартными средствами Linux, поэтому подготовим для этого диски:
quotacheck -cu /storage/sd${i}
Программная часть
Netatalk
В данном решении самое сложное ― Mac OS X, поэтому начнём с настройки afp.
Установим необходимые пакеты:
rpm -Uvh libdb-4_8-4.8.30-18.6.x86_64.rpm rpm -Uvh db-utils-4.8.30-18.6.x86_64.rpm rpm -Uvh netatalk-2.2.4-3.7.x86_64.rpm rpm -Uvh netatalk-devel-2.2.4-3.7.x86_64.rpm
Netatalk будем использовать версии 2.*, т.к. в версии 3.* не поддерживается использование переменных в указаниях путей (http://netatalk.sourceforge.net/3.0/htmldocs/afp.conf.5.html, раздел VARIABLE SUBSTITUTIONS: The use of variables in paths is not supported for now).
Стоит заметить, что пакет Netatalk мы собирали со следующими флагами:
--with-cracklib --with-bdb --enable-tcp-wrappers --enable-zeroconf
В /etc/netatalk/AppleVolumes.default добавим строчку
~/TimeMachine "BackupMachine" allow:@backupuser cnidscheme:dbd options:usedots,upriv,tm volsizelimit:250000 dbpath:/local/netatalk/db/$u
в которой:
allow:@backupuser
― разрешает подключаться пользователям, находящимся в группе backupuser;
BackupMachine
― имя, которое будет отображаться как подключённый диск, физически смонтированный в ~/TimeMachine относительно пользователя;
volsizelimit:250000
― ограничит пользователя квотой в 250 гб, но только если пользователю не задана системная квота. Т.к. в нашем случае мы используем системные квоты, эта опция бесполезна;
tm
― обязательная опция, позволяет TimeMachine на стороне клиента распознать выделенный ресурс, как валидный для бэкапа;
dbpath:/local/netatalk/db/$u
― путь к информации по метаданным пользователя. Нужна в том случае, когда строится список директорий и файлов, которые мы забэкапили. Будет практичней, если это вынести на отдельный диск, например, на SSD;
переменная $u
подставляет имя пользователя, которое нам так нужно и не работает в третьей версии.
Включаем логирование afpd.
В /etc/nettalk/afpd.conf
добавим строчку
-setuplog "default log_info /var/log/afpd.log" -keepsessions -transall -savepassword
в которой:
keepsessions
― сохраняет сессии при выключении afpd;
transall
― включает оба протокола ― AFP-over-Appletalk и AFP-over-TCP;
savepassword
― позволяет запомнить пароль пользователя в локальном keygen (без этой опции TimeMachine в Mac OS 10.8 не работает).
В /etc/netatalk/netatalk.conf
увеличим максимальное количество пользователей до 100
AFPD_MAX_CLIENTS=100
С Netatalk закончили. Подключиться можно стандартным приложением Time Machine, используя адрес вида afp://%SERVERNAME%/
Samba
Samba будет использоваться для подключения как в Windows, так и в Linux.
Настройка довольно проста: в /etc/samba/smb.conf
добавляем
[global] security = user workgroup = Badoo netbios name = BadooBackup local master = no domain master = no preferred master = no socket options = TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192 [homes] comment = Home Directories valid users = %S writable = yes create mask = 0700 directory mask = 0700 browseable = No read only = No
На этом настройка закончена. В Windows можно подключаться через «Проводник», в Linux ― автоматически монтировать при входе в систему.
Управление доступом
Итак, мы закончили с аппаратной частью и приложениями. Осталось разобраться с тем, как предоставлять пользователям несколько способов доступа.
Система управления пользователями у нас уже есть, значит, будем использовать привычные для нас манифесты Puppet.
Данные о пользователях будем хранить в интуитивно понятной таблице MySQL:
| backupusers | CREATE TABLE `backupusers` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL, `username` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, `backup_username` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', `backup_server` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'backupmsk', `password` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', `password_smb` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `shell` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '/bin/false', `map_drive` varchar(6) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'sdc', `quota` int(5) NOT NULL DEFAULT '250', `sftp` tinyint(1) NOT NULL DEFAULT '0', `isactive` tinyint(1) NOT NULL DEFAULT '0', `os` int(1) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
Фреймворк записывает данные именно в эту таблицу.
Несколько особенностей:
поле `map_drive`
― названия сервера и диска, которые будут использоваться для текущего пользователя. Не задается администратором, распределяется автоматически в зависимости от занятого места в том или ином разделе и на сервере. Если места для кого-то хватать не будет, то данные будут перенесены в другой раздел;
поле `isactive`
показывает, разрешено ли сотруднику пользоваться сервером для бэкапа. Если все ОС будут неактивны, перейдёт в значение 0. Данные пользователя при этом не удалятся (полезно, например, при потере ноутбука);
поле `sftp`
позволяет пользователю использовать rsync (об этом ниже). Этот способ позволит «продвинутым» коллегам бэкапить свои данные, используя самописные скрипты.
После обновления таблицы запускается скрипт, который генерирует манифест с данными для каждого пользователя.
Для того чтобы удобно было управлять пользовательскими директориями, добавим функцию в наш манифест:
define backupuser_dirs($name,$map_drive,$home="/home/${name}") { file { "$home": owner => $name, ensure => symlink, target => "/storage/${map_drive}/${name}", require => File["/storage/${map_drive}/${name}"]; "/storage/${map_drive}/${name}": owner => $name, ensure => directory, backup => false, mode => 0711; "$home/TimeMachine": owner => $name, ensure => directory, backup => false, mode => 0711, require => File["$home"]; } }
А вот отрывок манифеста для Puppet одного из пользователей:
@user { "i.ableev": ensure => $hostname ? { /^%servername%$/ => present, # создаем пользователю доступ именно на этом сервере, где он явно объявлен default => absent, # во всех остальных случаях доступ, даже если он и был, отзывается }, home => "/home/i.ableev", # указываем домашнюю директорию; (!) является симлинком на /storage/$map_drive/$name uid => "1217", groups => ['backupuser'], # указываем, в какую группу добавить пользователя password => 'V2UgYXJlIGhpcmluZyEgaHR0cDovL2NvcnAuYmFkb28uY29tL2pvYnMvCg==', # пароль используется при использовании Netatalk и rsync shell => "/bin/false", # отключаем пользователю shell, чтобы ограничить доступ по ssh } @backupuser_dirs { "i.ableev": name => "i.ableev", map_drive =>"sdh", # директория, в которой будет располагаться директория бэкапов пользователя вида /storage/$map_drive/$name require => User["i.ableev"]; } @exec { "i.ableev_quota": command => "/usr/sbin/setquota -u i.ableev 262144000 262144000 0 0 -a", # выделяем пользователю 250 гб … path => "/usr/sbin", onlyif => "/usr/bin/test `/usr/sbin/repquota -ua | /usr/bin/egrep '^i.ableev\s*' | /usr/bin/awk {'print \$4'}` -ne \"262144000\"", # … но выделяем её в том случае, если квота не равна 250 гб. } @line { "i.ableev_smb": # добавляем в файл /etc/samba/smbpasswd строчку вида: # @user:$uid:$hash file => '/etc/samba/smbpasswd', line => 'i.ableev:1217:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:5CDA711BBD899465D8F57D12BDF2BF68:[U ]:LCT-5058462B:', # хеш пароля генерируется на этапе формирования манифеста скриптом }
Теперь у пользователей есть возможность подключаться к серверу, используя Mac OS, Windows или Linux.
rsync
Для предоставления доступа через rsync (но не ssh), мы будем использовать chroot плюс ограниченный по возможностям shell. Манифест и функция в таком случае будут выглядеть несоколько иначе:
define backupuser_dirs_sftp($name,$map_drive,$home) { file { "/home/${name}": owner => $name, ensure => symlink, target => "${home}", require => File["$home"]; "$home": ensure => directory, owner => root, mode => 0755; "$home/sftp": owner => $name, ensure => directory, backup => false, mode => 0711, require => File["$home"]; } } @user { "i.ableev": ensure => $hostname ? { /^backupmsk$/ => present, default => absent, }, home => "/storage/sdh/i.ableev", uid => "1217", groups => ['backupuser'], password => 'V2UgYXJlIGhpcmluZyEgaHR0cDovL2NvcnAuYmFkb28uY29tL2pvYnMvCg==', # задаём пароль для входа shell => "/bin/badooshell", # ограниченный shell позволяет использовать только rsync } @backupuser_dirs_sftp { "i.ableev": name => "i.ableev", map_drive =>"sdh", home => "/storage/sdh/i.ableev", # путь к директории ~/sftp ― туда будут складываться бэкапы require => User["i.ableev"]; } @file { "/storage/sdh/i.ableev/bin": # путь к chroot’у ― здесь будет лежать наш badooshell ensure => directory, recurse => true, purge => true, force => true, backup => false, owner => root, group => root, source => "puppet:///modules/officebackup/bin/"; # отсюда он скачивается } @file { "/storage/sdh/i.ableev/lib64": # минимальный набор библиотек, необходимый для работы rsync: ld-linux-x86-64.so.2 libc.so.6 libpopt.so.0 ensure => directory, recurse => true, purge => true, force => true, backup => false, owner => root, group => root, source => "puppet:///modules/officebackup/lib64/"; }
Все манифесты готовы.
Результаты
Что мы получили в итоге:
- недорогой сервер с 72 терабайтами полезных данных;
- на одном сервере находятся бэкапы всех типов операционных систем пользователей;
- предоставлен доступ всем, кто хочет делать бэкапы.
Enjoy!
Илья Аблеев, ableev, сотрудник эксплуатации Badoo Development
Оригинал комикса: dilbert.com/strips/comic/2007-11-21/
ссылка на оригинал статьи http://habrahabr.ru/company/badoo/blog/177349/
Добавить комментарий