: Советы по созданию зеркала дистрибутивов

netsdot.ru

! Агентство OnlineJobs - работа Калуга.,картонная упаковка для продуктов питания
Советы по созданию зеркала дистрибутивов

Советы по созданию зеркала дистрибутивов

Вроде бы простая задача, как скажут многие, о чем тут писать. Находим официальный сайт, на нём ищем инструкцию (а то и не ищем, сами умные) и создаём себе зеркало при помощи rsync. Так-то оно так, если зеркалировать раз в сутки, но на самом деле все как правило сложнее. Существует много подземных камней, а также способов оптимизации некоторых процедур. Эта статья расскажет о некоторых подходах которые я выработал за полгода работы mirror.yandex.ru. В статье я хочу обратить внимание в основном на некоторые подходы к rsync.
Выбор железа

Здесь я дам только поверхностные сведения (так как все-таки в железе я не спец). Во-первых следует оценить количество посетителей. Если у вас будет каждую единицу времени 2000 соединений по http и 1000 по ftp, то дела ваши будут довольно плохи. Машина должна быть явно не слабенькой, но гораздо важнее выбрать жёсткие диски. SCSI это вероятно лучший вариант, но благодаря их размерам вы вряд ли получите больше 1.5 Тб дискового пространства (это полка и это всего лишь Debian+Fedora), а вторую полку вам вероятно не дадут. Так что остаётся полка с SATA дисками. Если в неё вставить жёсткие диски размером 500 Гб (а есть диски уже и на 1 Тб), то вы получите около 6.5 Тб. Нужен ли рейд? Мы от него отказались, без него все оказалось быстрее, а перезалить с другой машины не так долго. Но у вас ведь вероятно не будет в момент выхода Ubuntu load average на зеркале 100? Так что решайте сами. Здесь я советы давать не могу. Если вы используете рейд, то вероятно можно поверх него натянуть LVM. Какая должна быть файловая система? Тоже вопрос. Сейчас у нас стоит ReiserFS, раньше была XFS.
Организация структуры каталогов

Теперь перейдём к не менее важной процедуре, организации структуры каталогов. Следует продумать её заранее, чтобы не получилась файлопомойка по принципу ftp.chg.ru (а также множества других зеркал). Я предлагаю делать так. Создаём каталог, например, /storage и в него монтируем либо наши отдельные жёсткие диски, либо разделы LVM. Создаём каталог, например, /mirror который и будет виден через http и ftp, в нём создаём продуманную структуру, и монтируем каталоги из /storage в /mirror примерно такой командой:
mount --bind /storage/fedora /mirror/fedora

В /etc/fstab эта строка будет выглядеть так:
/storage/fedora /mirror/fedora auto bind 0 0

Благодаря этому подходу вы легко можете менять структуру дерева зеркала, не задумываясь о перемещении самих файлов.

О том как настроить Web, FTP и rsync сервера я рассказывать не буду, скажу только что мы используем Lighttpd и vsftpd.
Зеркалирование

Если вы хотите зеркалировать раз в сутки, то я предлагаю в каталог /etc/cron.daily поместить файл mirror.sh, в который прописать следующую строку:
rsync -aH --partial --timeout=1800 --delete --delete-after --delay-updates \
машина_с_которой_зеркалируете::модуль/ /storage/каталог/дистрибутива/ \
> /var/log/дистрибутив.log 2>&1

Просто и безотказно. Ключ --timeout=1800 нужен для того, что если с rsync что-то случится (а это бывает очень часто), то через полчаса бездействия он автоматически уничтожится. Хотя для обновлений раз в сутки это и не такой важный параметр. Ключ --delay-updates следует использовать обязательно. При этом все новые обновления будут сперва записываться во временную папку и только на последней стадии будут перемещены в само дерево. Все ошибки будут записываться в файл /var/log/дистрибутив.log. Для каждого дистрибутива свой файл. Каждые сутки он будет перезаписываться.

Что означает термин "машина_с_которой_зеркалируете::модуль"? Думаю часть до :: не вызывает затруднений, а вот модулем назовём то, что видно при отдаче команды rsync машина_с_которой_зеркалируете::. Например, на cdimage.ubuntu.com один модуль:
$ rsync cdimage.ubuntu.com::
cdimage Ubuntu CD Images

Тоже самое мы можем получить если отдать команду rsync rsync://cdimage.ubuntu.com. Чтобы получить содержимое каталога cdimage можно воспользоваться одной из следующих команд (результат будет одинаков):
rsync cdimage.ubuntu.com::cdimage/
или
rsync rsync://cdimage.ubuntu.com/cdimage/

Не забываем ставить в конце символ /, а то не все сервера показывают листинг без этого символа. Таким образом можно просматривать содержимое каталогов через rsync.

Какие ключи полезно использовать? Ключ -W для копирования файлов целиком (есть вероятность, что снизится нагрузка), --exclude - для игнорирования файлов или каталогов при зеркалировании. У него следующий синтаксис, если необходимо проигнорировать файл, то можно написать так: --exclude=файл, если каталог, то нужно поставить / после его названия. Можно также указывать полный путь, например, --exclude=/i586/a*/. То есть в каталоге i586 будут проигнорированы все каталоги начинающиеся с буквы a.

А вот почему подобная строка нам не подойдёт, если мы хотим зеркалировать дистрибутив часто, раз в час или раз в 15 минут? По многим причинам:
Предыдущее зеркалирование может не успеть закончится к новому запуску rsync;
Подобные логи скудны, а у rsync либо все, либо ничего;
Иногда можно по архиву определить а стоит ли вообще синхронизироваться в данный момент;
А вдруг мы хотим позаботится а наших пользователях и сделать файл с временем последней синхронизации?
Для решения этих проблем я использую самописные скрипты. Ниже приведён один из таких файлов, для зеркалирования Ubuntu:
1. #!/bin/sh
2. if [ -f "/var/lock/ubuntumirror" ]; then
3. echo "Another copy of ubuntumirror script already running";
4. exit 0;
5. else
6. touch /var/lock/ubuntumirror;
7. fi

8. LOGFILE="/var/log/mirrors/ubuntu-$(date +%Y%m%d"-"%H%M%S).log"

9. HOSTNAME="mirror.yandex.ru"
10. HOST="archive.ubuntu.com"
11. TRACE="ls-lR.gz"
12. LOCKFILE="/var/lock/$TRACE"

13. rm -f $LOCKFILE

14. wget --directory-prefix=/var/lock http://$HOST/ubuntu/$TRACE > /dev/null 2>&1

15. REMOTEMD5=$(md5sum $LOCKFILE | awk '{print $1}')
16. LOCALMD5=$(md5sum /storage/ubuntu/ubuntu/$TRACE | awk '{print $1}')

17. echo -e "$REMOTEMD5\n$LOCALMD5"

18. if [ "$REMOTEMD5" != "$LOCALMD5" ]; then


19. rsync -P --timeout=1800 -WvaH \
--exclude "Packages*" --exclude "Sources*" \
--exclude "Release*" \
--exclude "ls-lR.gz" \
rsync://$HOST/ubuntu/ \
/storage/ubuntu/ubuntu/ > $LOGFILE 2>&1

20. rsync -P --timeout=1800 -aWvH --delete --delete-after \
--exclude "project/trace/${HOSTNAME}" \
rsync://$HOST/ubuntu/ \
/storage/ubuntu/ubuntu/ >> $LOGFILE 2>&1

21. LANG=C date -u > "/storage/ubuntu/ubuntu/project/trace/${HOSTNAME}"

22. bzip2 -9 $LOGFILE

23. fi

24. rm -f /var/lock/ubuntumirror
25. rm -f $LOCKFILE

Итак, этот скрипт делает следующие вещи. Создает/Убирает lock-файл запрещающий запуск этого же скрипта, пока зеркалирование активно; определяет нужно ли запускать rsync в данный момент; зеркалирует дерево Ubuntu в два этапа. Теперь по строчкам:

2-7 - при запуске скрипта проверяется нет ли lock-файла. Если его нет, то продолжается работа скрипта, если он есть, то скрипт останавливается.

8 - заводится переменная с именем файла логов. Так как зеркалирование должно происходить довольно часто, то полезно указывать дату и время в имени файла. Потом вы сможете определять, работает rsync или он подвис, сравнивая время последнего изменения log-файла и время в его названии.

9-10 - объявляются различные переменные. 9 - локальное имя машины, 10 - сервер с которого происходит зеркалирование.

11 - заводим переменную с файлом состояния архива. В разных дистрибутивах (на разных зеркалах) он разный. В Slackware, Mandriva и Ubuntu состояние зеркала можно отслеживать по файлы ls-lR.gz, в Debian по файлу /debian/project/.trace/ftp-master.debian.org, но в большинстве дистрибутивов его просто нет. Вам придётся изучить зеркало и найти этот файл самостоятельно (если он есть). Для чего вообще нужен этот подход? Зеркала как правило медленные и получение полного списка всех файлов довольно долгая процедура. Так мы вытягиваем всего один файл и сравниваем его с локальным. Данный подход позволит нам пускать скрипт синхронизации хоть каждую минуту и получать обновления с пылу с жару.

12 - определяется название временного файла, в который будем закачивать файл состояния удалённого архива.

14-18 - вытягиваем файл состояния (здесь я это делаю wget'ом через http, можно использовать rsync), и рассчитываем контрольные суммы для него и для локального файла. Если они не совпадают, то запускаем rsync.

19-20 - rsync проходит в два этапа. Так рекомендуется на сайте Ubuntu, так и здравый смысл от нас требует. На первом мы затягиваем все файлы кроме Packages*, Sources*, Release*, ls-lR.gz, чтобы ни в коем случае не сломать репозиторий до завершения обновления, на втором затягиваем весь репозиторий целиком.

21 - создание файла mirror.yandex.ru в соответствующем каталоге. В Ubuntu этого не требуют, в Debian должен создаваться обязательно.

24-25 - удаляются временные файлы.

Обратите внимание, что лог я записываю не через внутренний логгер rsync'а. Почему? Потому, что натравив на лог-файл команду tail -f вы получите абсолютно ту же картину, что и при запуске rsync с ключом --progress, то есть вы легко сможете увидеть какой файл качается, и сколько от него осталось докачать. Ключ -P в данном примере означает тоже самое, что и --partial --progress.

А как же нам позаботится о наших пользователях (а может и о том, чтобы файлы вовремя попадали на удалённую машину) и создать файл со временем последней синхронизации? Да, если дистрибутив содержит такой файл, то создавать ничего не нужно, а если нет. Вот один из способов, на примере openSUSE:
#!/bin/sh
if [ -f "/var/lock/opensusemirror" ]; then
echo "Another copy of opensusemirror script already running";
exit 0;
else
touch /var/lock/opensusemirror;
fi

LOGFILE="/var/log/mirrors/opensuse-$(date +%Y%m%d"-"%H%M%S).log"

HOSTNAME=".mirror.yandex.ru"
TRACE="$HOSTNAME"


rsync -P --timeout=1800 -WvaH --delete --delete-after --stats \
--exclude=.mirror.yandex.ru \
rsync://rsync.opensuse.org/opensuse-full/opensuse/ \
/storage/aspsuse/opensuse/ > $LOGFILE 2>&1

while [ "$?" -ne 0 -a "$?" -ne 24 ]; do
rsync -P --timeout=1800 -WvaH --delete --delete-after --stats \
--exclude=.mirror.yandex.ru \
rsync://rsync.opensuse.org/opensuse-full/opensuse/ \
/storage/aspsuse/opensuse/ >> $LOGFILE 2>&1
done

if [ "$(grep "Number of files transferred:" $LOGFILE | tail -n 1 | \
awk '{print $NF}')" -ne 0 ]; then
echo "$(date -u)" > /storage/aspsuse/opensuse/$TRACE
fi

bzip2 -9 $LOGFILE

rm -f /var/lock/opensusemirror

Rsync пускается с ключом --stats, что позволит нам получать некоторую расширенную статистику. Нас интересует сколько файлов было передано. Если 0, то нет необходимости пересоздавать файл .mirror.yandex.ru с временем последней синхронизации. Последний if как раз и проверяет на это лог-файл и если количество переданных файлов не равно 0, то файл с временем последней синхронизации пересоздаётся, если нет, то остаётся без изменений. Теперь другие машины могут сравнивать этот файл с локальным и при необходимости запускать rsync.

Обратите внимание, что rsync вызывается дважды, первый раз всегда, а второй раз, только если в первый раз он завершился некорректно. Если код возврата не 0 (все впорядке) и не 24 (обычно это проблемы со стороны сервера - Partial transfer due to vanished source files), то запустить rsync ещё раз. Данный подход должен заставить rsync доделать свою работу в случае аварийного завершения или каких-либо ошибок.
Советы по зеркалированию некоторых дистрибутивов

Debian. Вы можете зеркалировать с любого официального зеркала Push-Primary и Push-Secondary, так как они обновляются по принципу проталкивающего зеркалирования. Как только главный сервер обновился, он через ssh запускает rsync на подчинённых ему машинах. Мы же можем воспользоваться принципом Pull-зеркалирования (это я так назвал). Проверяя каждые, допустим 2 минуты, файл /debian/project/.trace/ftp-master.debian.org на удаленном сервере и запуская rsync при его изменении. В Debian рекомендуют использовать их скрипт для зеркалирования, но в нем ничего такого нет. Ещё одна затычка и всё. В общем зеркалирование Debian почти ничем не отличается от зеркалирования Ubuntu, описанного выше.

Fedora. Никаких файлов, по которым можно отследить состояние обновления репозитория нет. Так что если вы собрались зеркалировать Fedora в один заход, то по идее вам придётся тупо запускать rsync. Если же зеркалировать её по частям, то можно для каждой ветки репозиториев (development, updates, testing/updates) отслеживать файл repomd.xml, который находится в каталоге repodata. При его изменении хотя бы в одной из архитектур необходимо запускать rsync.

Для доступа к главным серверам Fedora необходимо зарегистрироваться и описать своё зеркало. Более подробная информация находится в Вики.

Centos. Файл timestamp.txt находится в корне зеркала.

Mandriva,Slackware, Ubuntu - отслеживать состояние репозитория можно по файлам ls-lR.gz.
Но большинство дистрибутивов не имеет подобных файлов (и Gentoo тоже), так что придётся раз в полчасика или почаще, не жалея удалённый сервер запускать rsync на полную катушку.
Заключение

Как мы видим с зеркалированием не все так просто, или просто, но не всегда. Я думаю подобные примеры и решения смогут вам помочь. В любом случае вам понадобятся знания bash для реализации всех идей. И последнее. Если хотите зазеркалировать дистрибутив, то сперва поищите инструкции на официальном сайте.

| опубликовано: Tigro, 22. Январь 2008, 20:53 — tamerlan311 23. Январь 2008, 00:35 #

А почему через rsync://mirror.yandex.ru
не доступны репозитории debian-multimedia , debian-opera , debian-virtualbox ?

или они считаются слишком мелкими?

Просто я сейчас поднимаю домашнее полузеркало полупрокси для локальной сети.

Весь репозиторий дебиана явно не потянуть (даже одну архитектуру) поэтому папка pool проксируется nginx с сохранением на диск. а всё остальное синхронизируется через rsync.

Дополнительные репозитории хотелось бы тоже зазеркалить (благо размеры не столь внушительные).

Так же к слову, непонятно почему но apt не понимает http redirect. Что очень досадно, всё равно все пакеты подписываются и угрозы безопастности редиректы бы не создали. (но имхо позволили бы иметь более гибкие зеркала)
В ubuntu вроде сделали новый транспорт который называется не http а mirror , но накой новый транспорт так и не понял.

В идеале nginx при отсутствии файла в кеше проксировать запрос на верхнее зеркало (для определенных адресов) или отфутболивать редиректом на тоже зеркало (для остальной локалки)

Жалюзи - бамбуковые жалюзи