nRepo — управление обновлениями в Linux

в 15:00, , рубрики: repository, rpm, update, yum, Серверное администрирование, системное администрирование, метки: , , , ,

nRepo — управление обновлениями в Linux

nRepo — это простой и удобный инструмент для управления автоматическими обновлениями на серверных OS Linux.

Нелогичность и устаревшая модель обновлений в Linux.

Начну со странного: в широко известной всем OS Windows Server есть интересное приложение «WSUS», расшифровывается как «Windows Server Update Service». В ее обязанности входит всего одна простая задача — раздавать обновления локальным компьютерам. Очень важный момент, который мне в ней нравится, это абсолютный контроль над всеми обновлениями, ни один пакетик не пролезет мимо администратора, его сначала нужно подтвердить, затем разрешить деплоить его на тестовую группу машин, а затем раздать обновление всем остальным. Конечно же, WSUS, как врочем и сама система обновлений в windows, — говно (простите), но сама идея и концепция вот такого приложения отличная.

А как, тем временем, с обновлениями и с пакетной системой в частности, обстоят дела в Linux (в примере CentOS5):

  • Поставил новую систему на мини-vps, делаешь

yum install nginx -y

No package nginx available.
Error: Nothing to do

Это потому что нужно подключить репозиторий EPEL.

  • Подключил, теперь делаешь

yum install php-fpm -y

No package nginx available.
Error: Nothing to do

Да чтож это такое. Ситуация идиотская, но можно попытаться немного изменить свою жизнь к лучшему, создав локальное зеркало всех репозиториев в один единственный и подключать их одним движением на другие машины.
Идея сама собой приходит на ум: исключить вопрос недоступности каких-то пакетов, это же так просто и удобно!

Следующее, что стало причиной для всей этой суеты, это внезапное появление такой задачи: обновить все и сделать так, чтобы все всегда было обновлено. К счастью, я больше не имею дел с WinServer, поэтому я занялся поисками LSUS. И не нашел.

mrepo.

Зато нашел mrepo «RPM repository management tool supporting ftp/http/sftp/rsync/rhn/you». Фактически это rsync в python обертке, живет вот тут github.com/dagwieers/mrepo. Проект довольно взрослый, но функционал ограничивается созданием локального зеркала репозитория и раздача его локальным клиентам. А еще можно сделать зеркало из образов dvd-дисков. Хорошо, но недостаточно, и вот почему.
Например, есть какой-нибудь nginx, который собран с особенными модулями и его обновлять нельзя, отсюда возникает потребность сделать апдейт, но только без пакета «nginx» пожалуйста. Такая возможность в mrepo не предусмотрена. Если очень хочется, то можно открыть исполняющий python-скрипт и запилить туда руками опции для rsync

 --exclude="nginx*"

но нехорошо как-то вставлять опции в код.
Еще пример для kernel'a: вроде бы «А почему бы и нет?». Но нет. Даже если он стоковый из core-репозитория дистрибутива, обновить его нельзя просто потому что требуется перезагрузка для его подключения. Перезагрузить несколько десятков серверов после апдейта — звучит как-то безумно. А забить на перезагрузку будет менее болезненно, но чревато проблемами в дальнейшем. Вообще, обновление ядра это тема другого топика, но сейчас важно то, что нужно как-то исключить kernel из периодических авто-обновлений.

nRepo.

От форка mrepo мне пришлось отказаться в силу сложности его реализации, legacy в виде поддержки создания локального репозитория с dvd-дисков и языка python. Ну, то есть я против того, чтобы делать из одного полезного инструмента щвейцарский нож с кофеваркой. Можно сделать плагин «кофеварка», если уж совсем без нее никак, но не прикручивать же ее к ножу. А еще я не совсем хорошо знаю python, чтобы написать на нём что-то хорошее. Главные идеи nRepo это «unix-way» и функциональность в управлении пакетами. К слову, первое пока у меня получилось лучше, чем второе, размер скрипта меньше 200 строк.
Если вы являетесь гордым пользователем систем с пакетной системой APT, то вынужден разочаровать, nRepo пока работает только с rpm и тестировался только c yum на CentOS 5/6 (кто знает, может быть скоро будет и APT).

Прототип? Да, прототип.

Ссылка на github — github.com/s1dney/nRepo. Фактически это тот же rsync, но уже в другой обертке на bash. Присутствует очень простая, но гибкая система фильтрования пакетов, ради которой это все и задумывалось.

Подробно о том, как оно работает.

Первая идея реализована следующим образом: в /etc/nrepo/ создается текстовый конфиг *.nrepo для нужной системы и архитектуры, например, centos_6-x86_64. В нем собираeтся список нужых источников-репозиториев в формате «имя_источника=ссылка», ссылка указывает на корень репозитория (в нем находится repodata/), например вот, абсолютно рабочий конфиг репы, где есть почти все необходимое (можно достать в samples/ на гитхабе):

# CentOS 6 x86_64
centos6_os=rsync://mirrors.nl.kernel.org/centos/6/os/x86_64/
centos6_updates=rsync://mirrors.nl.kernel.org/centos/6/updates/x86_64/
epel6=rsync://mirrors.nl.kernel.org/fedora-epel/6/x86_64/
remi6=http://mirror.awanti.com/remi/enterprise/6/remi/x86_64/
rpmforge6=http://mirror.awanti.com/rpmforge/dag/redhat/el6/en/x86_64/rpmforge/

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

exclude_pattern="nginx* httpd* mongodb*"

(тоже самое можно сделать и в include_pattern=""). В том же файле можно задать несколько других полезных и не очень опций.
Теперь можно сделать

nrepo --update

и получить готовое зеркало всех репозиториев. А для того, чтобы с них можно было обновляться, нужно еще поднять какой нибудь nginx и подключить это хранилище к другим серверам. (конфиг для nginx тоже есть в samples/ на гитхабе)
Но чтобы подключить нужен конфиг .repo. Создатель mrepo, например, предлагает сделать его руками. Но я слишком ленив для этого, так появилась первая киллер-фича "--genconf"

nrepo --genconf --hostname=repo.mynetwork.local

Здесь --hostname это dns имя сервера обновлений, если его не указать, то будет использоваться значение, возвращаемое gethostname(), в конфиге .repo это имя используется для генерации http ссылки.
В текущей директории появится конфиг centos_6-x86_64.repo (имя идентично .nrepo), который содержит все необходимое, чтобы yum мог использовать локальное зеркало.

[centos6_os]
name=centos6_os
baseurl=http://shellbox.social/centos6_x86_64/centos6_os/
gpgcheck=0
enable=1
[centos6_updates]
name=centos6_updates
baseurl=http://shellbox.social/centos6_x86_64/centos6_updates/
gpgcheck=0
enable=1
...

Его только нужно положить в /etc/yum/repos.d/ на клиентской машине, при этом конечно сначала не плохо было бы отключить все существующие, как-то так:

ssh root@$целевой_сервер 'for i in `ls /etc/yum.repos.d/` ; do mv /etc/yum.repos.d/$i{,.old} ; done'

и положить новый файл:

scp centos_6-x86-64.repo root@$целевой_сервер:/etc/yum.repos.d/

Таким образом с минимальным количеством телодвижений поднимается один единственный репозиторий, который хранит в себе все, за исключением $exclude пакетов.
Кстати, сразу же новые репы не подтянутся, если в кэше yum что-то есть, то нужно сделать

yum clean all

Немного технических деталей:

  • Для зеркалирования используются утилиты rsync (rsync://) и lftp (http://) (ftp не тестировал за ненадобностью, но скорее всего тоже работает).
  • Для создания метаданных репозитория — createrepo.
  • В процессе выполнения скрипта $exclude_pattern парсится и превращается в элементарный набор опций для rsync или lftp вида --exclude=«nginx*» --exclude=«httpd*», все очень просто.
  • Репозиторий centos6-x86_64 занимает примерно 25гб (для 5 — 20).
  • Основное время при апдейте зеркала занимает обновление xml метаданных, при этом createrepo не умеет работать более чем с 1 ядром и при создании хранилища в 10000 пакетов может обрабатываться от 5 до 20 минут.
  • Если сделать зеркало без опций в exclude_pattern, а потом добавить туда параметров, то скрипт отрежет все лишнее при первом апдейте.
  • Если в exclude_pattern был nginx*, а потом его оттуда удалили, то пакет приедет с первым же апдейтом.

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

В комментариях прошу изложить ваши мысли по поводу скрипта и его актуальности для системных администаторов. И чего еще не хватает, чтобы было полное счастье.

Автор: s1dney

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js