Библиотека сайта rus-linux.net
Одновременное управление несколькими серверами
Автор: Жольнай Кирилл,Дата: 21 февраля 2009
Если вы администрируете несколько Linux-серверов, вы неизбежно столкнетесь с тем, что довольно часто приходиться проделывать одни и те же операции над всеми серверами. Например: вносить изменения в конфигурационные файлы (/etc/hosts, скрипты инициализации и т.п.), или производить разовую архивацию на всех серверах. После очередной пресной порции обезьяньей работы мы понимаем, что это не linux-way. Что можно сделать?
Задача # 1
Для примера: нужно поправить /etc/hosts на локальном компьютере и 8 серверах, список которых в файле ~/servers.list
.
$ cat servers.list 192.168.0.1 192.168.0.2 192.168.0.3 192.168.4.44 192.168.0.5 192.168.0.6 192.168.0.7 192.168.8.88
$ cat /etc/hosts 127.0.0.1 localhost.localdomain localhost 192.168.0.1 gate 192.168.0.2 megahost1 192.168.0.3 megahost2 192.168.4.44 megahost3 192.168.0.5 megahost4 192.168.0.6 megahost5 192.168.0.7 megahost6 192.168.8.88 megahost7
Стандартный подход
Обычно для решения этой задачи используем стандартные инструменты: любимый редактор (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. Копируем ключ сначала на одну машину:
$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.1
2. Вводим пароль.
3. Копируем ключ на слеующую машину:
$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.2...
16. Последний пароль.
А лучше в ускоренном режиме:
1. Копируем ключи поочередно на каждую из машин, список которых в файле ~/servers.list:
$ cat ~/servers.list | while read i ; do ssh-copy-id -i ~/.ssh/id_rsa.pub root@"$i" ; done
2. Вводим пароль.
3. Следующий пароль.
...
8. Последний пароль.
1. Редактируем /etc/hosts
2. И копируем на все машины, список которых в файле ~/servers.list:
cat ~/servers.list | while read i ; do scp /etc/hosts root@"$i":/etc/ ; done
Все!
Это и правда все, то есть всего 2 (два) действия. Этой конструкцией можно горы свернуть, но не все, к сожалению. Например, мы сможем выполнить любую команду для каждого из серверов, но мы не увидим вывода этой команды. Можем смириться или двигаться на следующую ступень просветления.
Задача # 2
Нам просто нужно узнать время работы с последней перезагрузки стандартной командой uptime, но со всех серверов. Для этого нам придется воспользоваться одной из программ для параллельного выполнения комманд.
Программы для параллельного выполнения команд
Так как проблема существует не первый день, решений придумана масса, с довольно различными реализациями и подходом :
- shmux
- dsh
- dssh
- fanout
- Kees Cook's gsh
- Mr. Shell
- multi-rsh
- multixterm
- mussh
- pdsh
- pssh
- p-run
- PyDsh
- remote_update.pl
- RGANG
- rshall
- tentakel
- vxargs
Из них бы я особо выделил pssh, pdsh, shmux. А из этих трех мне приглянулся pdsh, за то что: написан на С, давно разрабатывается, часто обновляется, и есть в репозиториях практически всех современных систем (кроме Slackware). И самое главное - не требуется установка на сервера, только на машине, откуда будете работать.
pdsh
PDSH - высокопроизводительная, распараллеленная оболочка (по крайней мере так говорится на официальном сайте. Для доступа к серверам использует либо rsh, либо ssh, что предпочтительней. А так же использует модули расширения, которых мы касаться не будем. Установка, думаю, проблем не вызовет:
$ sudo apt-get install pdsh -y $ yum install pdsh -y
Синтаксис программы прост:
pdsh -w [user@]host,host,... command
Решаем задачу # 2, а по ходу разбираемся:
Вот и все, задача решена. Правда вывод мы получили вразнобой, так как задачи выполняются параллельно, и вывод происходит по мере поступления (в shmux проблема решена). Но сама команда выглядит монструозной, не правда ли? Для решения этой проблемы у pdsh есть свой синтаксис, который отличается от синтаксиса bash из примера, думаю, будет понятно:
$ pdsh -w root@192.168.0.[1-3,5-7],root@192.168.8.88,root@192.168.4.44 uptime
Получилось немного короче. А когда серверов 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:
$ pdcp -w root@192.168.0.[1-3,5-7],root@192.168.8.88,root@192.168.4.44 /etc/hosts /etc/
Просто, да? Единственная трудность в том, что для этого pdsh должен быть установлен на всех машинах, но ведь теперь это не проблема:
$ pdsh -w root@192.168.0.[1-3,5-7],root@192.168.8.88,root@192.168.4.44 yum install pdsh -y
А можно все это еще ускорить или упростить? Можно и нужно, последняя ступень просвещения и выход на космические скорости.
Редактируем .bashrc
Если мы управляем несколькими группами серверов, например хостинговыми (50шт) с Debian, сервера внутреннего проекта (24шт) со Slackware и офисные сервера (10шт) c Fedora. Тогда было бы удобно разделить их на группы. У pdsh на этот счет есть решение, но заставить его работать на Slackware я так и не сумел. Поэтому я пошел по linux-way и добавил в ~/.bashrc вот такие строки:
Это позволило нам разделить сервера на группы, а так же обеспечило возможность автодополнения по табуляции. Для примера установим htop на всех машинах:
$ pdsh-to-servers apt-get install htop -y $ pdsh-to-project "wget http://repos.example.org/htop.tgz && installpkg htop.tgz ; rm htop.tgz" $ pdsh-to-office yum install htop -y
И, собственно, все. А если мы захотим узнать uptime на всех серверах, выполним следующее:
$ pdsh-to-all uptime
Что бы отчистить все сервера от бэкап-файлов, которые остаются после редактирования vim'ом, поступим так:
$ pdsh-to-all "find /etc -name *~ -exec rm -f {} \;"
Думаю, нет необходимости подсчитывать количество сэкономленных телодвижений.
Итого
Если у вас до 10 нетребовательных к вниманию серверов, имеет смысл использовать ssh c аутентификацией по ключам и "ускоряющую конструкцию". Если более, то pdsh, pssh или shmux, дополненных .bashrc.