Главная » 2012 » Июнь » 14 » Одновременное управление несколькими серверами Linux
Одновременное управление несколькими серверами Linux
09:56
Автор: Жольнай Кирилл, Дата: 21 февраля 2009
Если вы администрируете несколько Linux-серверов, вы неизбежно столкнетесь с тем, что довольно часто приходиться проделывать одни и те же операции над всеми серверами. Например: вносить изменения в конфигурационные файлы (/etc/hosts, скрипты инициализации и т.п.), или производить разовую архивацию на всех серверах. После очередной пресной порции обезьяньей работы мы понимаем, что это не linux-way. Что можно сделать?
Задача # 1
Для примера: нужно поправить /etc/hosts на локальном компьютере и 8 серверах, список которых в файле ~/servers.list.
Обычно для решения этой задачи используем стандартные инструменты: любимый редактор (vim или nano) и scp (http://ru.wikipedia.org/wiki/SCP), который входит в состав пакета openssh и включен во все современные дистрибутивы.
1. Вносим необходимые правки в /etc/hosts. 2. Копируем на каждый из серверов:
$ scp /etc/hosts root@192.168.0.1
3. Вводим пароль. 4. Опять выполняем команду копирования:
$ scp /etc/hosts root@192.168.0.2
5. И снова вводим пароль. ... 17. И последний раз вводим пароль. То есть выполняем 17 нудных действий. Пришло время подняться на первую ступень просвещения.
Ускоренный стандартный подход
Для начали избавимся от необходимости ввода пароля при входе по ssh или выполнения копирования посредством scp. Для этого мы сгенерируем пару ключей на локальной машине:
$ ssh-keygen -q
Несколько раз нажимаем Enter на все задаваемые вопросы. А затем скопируем этот ключ на все сервера стандартной командой ssh-copy-id, попутно вводя пароль. Можно копировать по одному:
А лучше в ускоренном режиме: 1. Копируем ключи поочередно на каждую из машин, список которых в файле ~/servers.list:
$ cat ~/servers.list | while read i ; do ssh-copy-id -i ~/.ssh/id_rsa.pub root@"$i" ; done
2. Вводим пароль. 3. Следующий пароль. ... 8. Последний пароль.
После копирования ключей ни ssh, ни scp пароль не попросит. А вот теперь опять решаем нашу задачу # 1: 1. Редактируем /etc/hosts 2. И копируем на все машины, список которых в файле ~/servers.list:
cat ~/servers.list | while read i ; do scp /etc/hosts root@"$i":/etc/ ; done
Все! Это и правда все, то есть всего 2 (два) действия. Этой конструкцией можно горы свернуть, но не все, к сожалению. Например, мы сможем выполнить любую команду для каждого из серверов, но мы не увидим вывода этой команды. Можем смириться или двигаться на следующую ступень просветления.
Задача # 2
Нам просто нужно узнать время работы с последней перезагрузки стандартной командой uptime, но со всех серверов. Для этого нам придется воспользоваться одной из программ для параллельного выполнения комманд.
Программы для параллельного выполнения команд
Так как проблема существует не первый день, решений придумана масса, с довольно различными реализациями и подходом :
Из них бы я особо выделил pssh, pdsh, shmux. А из этих трех мне приглянулся pdsh, за то что: написан на С, давно разрабатывается, часто обновляется, и есть в репозиториях практически всех современных систем (кроме Slackware). И самое главное - не требуется установка на сервера, только на машине, откуда будете работать.
pdsh
PDSH - высокопроизводительная, распараллеленная оболочка (по крайней мере так говорится на официальном сайте. Для доступа к серверам использует либо rsh, либо ssh, что предпочтительней. А так же использует модули расширения, которых мы касаться не будем. Установка, думаю, проблем не вызовет:
Вот и все, задача решена. Правда вывод мы получили вразнобой, так как задачи выполняются параллельно, и вывод происходит по мере поступления (в shmux проблема решена). Но сама команда выглядит монструозной, не правда ли? Для решения этой проблемы у pdsh есть свой синтаксис, который отличается от синтаксиса bash из примера, думаю, будет понятно:
Получилось немного короче. А когда серверов 50, разница будет потрясающая.
Если вывод многострочный, да еще и задерживается, мы получим кашу, то есть строки будут поступать на экран по мере формирования. Частично решить проблему можно такой конструкцией:
$ pdsh -w hosts command | sort -n
Если мы хотим выполнить некий скрипт на всех серверах содержащий спецсимволы "; & && | || " обязательно возьмите всю выполняемую команду в кавычки. В противном случае интерпретатор (bash) решит, что команда, выполняемая после спецсимвола, предназначена для локальной машины. Например:
$ pdsh -w hosts "i=~ ; rm -rf *$i"
Интересно, что сделает скрипт, если мы кавычки забудем?
В комплекте с pdsh есть утилита pdcp схожая по функционалу с scp. Решим с ее помощью задачу # 1: 1. Редактируем /etc/hosts 2. Копируем все файлы hosts на удаленные машины в папку /etc:
А можно все это еще ускорить или упростить? Можно и нужно, последняя ступень просвещения и выход на космические скорости.
Редактируем .bashrc
Если мы управляем несколькими группами серверов, например хостинговыми (50шт) с Debian, сервера внутреннего проекта (24шт) со Slackware и офисные сервера (10шт) c Fedora. Тогда было бы удобно разделить их на группы. У pdsh на этот счет есть решение, но заставить его работать на Slackware я так и не сумел. Поэтому я пошел по linux-way и добавил в ~/.bashrc вот такие строки:
alias pdsh-to-all="pdsh -w $servers,$project,$office"
Это позволило нам разделить сервера на группы, а так же обеспечило возможность автодополнения по табуляции. Для примера установим htop на всех машинах:
Думаю, нет необходимости подсчитывать количество сэкономленных телодвижений.
Итого
Если у вас до 10 нетребовательных к вниманию серверов, имеет смысл использовать ssh c аутентификацией по ключам и "ускоряющую конструкцию". Если более, то pdsh, pssh или shmux, дополненных .bashrc.