Инструментарий системного администратора: Распределенное администрирование при помощи SSH

Эта статья посвящена безопасной оболочке Secure Shell (SSH) для запуска команд на удаленных системах UNIX®. При помощи простых скриптов можно создать систему, которая позволит одновременно управлять множеством систем с одного компьютера без необходимости подключаться к ним по отдельности. Кроме того, в статье даны основы распределенного управления компьютерами, скриптами и решениями, использующими эту технологию.

Мартин Браун (Martin C. Brown) , Внештатный автор и консультант компании MCslp, Свободный писатель

Мартин Браун – бывший руководитель IT подразделения с опытом работы в области межплатформенной интеграции. Обладая большим опытом разработчика, он создал динамические сайты для множества крупных клиентов, включая HP и Oracle, и на данный момент является техническим директором ресурса Foodware.net. В настоящее время Мартин в качестве внештатного автора и консультанта сотрудничает с корпорацией Microsoft, работает редактором (LAMP Technologies Editor) журнала LinuxWorld, является видным членом группы AnswerSquad.com. Его перу принадлежат книги на совершенно разные темы: от сертификации Microsoft, компьютеры iMac до программирования открытого исходного кода. При всем этом он продолжает плодотворно работать в области программирования для разных платформ и сред. Связаться с Мартином можно посредством его персонального Web-сайта по адресу http://www.mcslp.com.



02.07.2010

Об этой серии статей

Обычно администратор UNIX® регулярно применяет ряд утилит, приемов и систем. Для упрощения различных процессов можно использовать основные утилиты, операторы командной строки и сценарии. Часть этих инструментов поставляется вместе с операционной системой, но бОльшая часть приемов нарабатывается на основе практического опыта и желания администратора упростить свою жизнь. Цель этой серии статей - рассказать о бОльшей части доступных инструментов для различных UNIX-систем, включая методы упрощения администрирования гетерогенных сред.

Упрощение удаленного входа в систему

Утилиты Secure Shell (SSH) обеспечивают безопасность входа в систему и обмена информацией с удаленным хостом. Существует множество подобных утилит, в том числе общего назначения (обеспечивающих удаленное терминальное подключение), SCP (безопасное решение для копирования между хостами) и SFTP (безопасное решение для копирования файлов, работающее подобно стандартным средствам FTP).

Безопасность работы всех этих утилит обеспечивает шифрование передаваемой информации. Кроме аутентификации, соединения защищены при помощи механизма открытых или закрытых ключей. Одно из основных преимуществ протокола SSH заключается в том, что он позволяет обойтись без обычного обмена логином и паролем, вместо этого копируя открытый ключ на удаленную машину.

Как бы ни был удобен SSH для входа на удаленную машину (поскольку исключает ввод пароля), он еще более удобен для удаленного администрирования. Необходимость ввода пароля может сделать автоматизацию удаленного администрирования (например, запуск команды при помощи планировщика cron) невозможной, поскольку вы, естественно, не захотите указывать пароль в скрипте.

При использовании SSH для запуска команд на множестве машин без передачи открытого ключа, потребуется ввод пароля на каждой машине.

Простой и быстрый способ автоматизации входа в систему заключается в создании открытого ключа:

$ ssh-keygen -t rsa

Следуйте инструкциям на экране, но не вводите пароль, когда он будет запрошен, иначе придется вводить его всякий раз при использовании этого ключа. Будут созданы файлы закрытого и открытого ключей. Теперь нужно только добавить содержимое файла открытого ключа в .ssh/id_rsa.pub и добавить его в файл .ssh/authorized_keys на удаленном хосте для учетной записи, которая используется для входа в систему. Необходимо добавить содержимое файла открытого ключа на каждый компьютер, на котором вы хотели бы входить в систему автоматически.

Удаленный запуск команд

Существует множество способов удаленного запуска команд.

Можно запускать удаленные команды по одной, добавляя их в SSH после информации об имени пользователя и хоста. Например, чтобы получить информацию о дисках удаленного хоста, можно использовать команду, приведенную листинге 1 ниже, которая возвращает соответствующую выдачу.

Листинг 1. Запуск простой команды в SSH
$ ssh mc@gentoo.vm df

Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda3             14544820   3611520  10194464  27% /
udev                    128044       564    127480   1% /dev
/dev/hdc1              1968872     50340   1818516   3% /var/tmp
/dev/hdc2              1968904   1482220    386668  80% /usr/portage
/dev/hdc3              1968904     35760   1833128   2% /home/build
shm                     128044         0    128044   0% /dev/shm

Обратите внимание, что последовательность команд в листинге 1 потребует ввода пароля, если до этого на удаленный хост не был загружен открытый ключ.

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

Пример последовательного запуска поверки диска и времени работы показан в листинге 2.

Листинг 2. Проверка диска и времени работы
$ ssh mc@gentoo.vm "df;uptime"
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda3             14544820   3611520  10194464  27% /
udev                    128044       564    127480   1% /dev
/dev/hdc1              1968872     50340   1818516   3% /var/tmp
/dev/hdc2              1968904   1488100    380788  80% /usr/portage
/dev/hdc3              1968904     35760   1833128   2% /home/build
shm                     128044         0    128044   0% /dev/shm
 14:31:27 up 12 min,  2 users,  load average: 0.01, 0.05, 0.06

Можно указать столько команд, сколько нужно. Также возможно использование отбора при помощи grep или других программ, но необходимо убедиться в том, что вся последовательность удаленных команд заключена в кавычки (см. листинг 3).

Листинг 3. Отбор при помощи grep
$ ssh root@gentoo.vm "cat /var/log/messages|grep 'su\['"
Dec 17 18:05:37 localhost su[19218]: pam_authenticate: Permission denied
Dec 17 18:05:37 localhost su[19218]: FAILED su for root by mc
Dec 17 18:05:37 localhost su[19218]: - pts/1 mc:root
Dec 17 18:06:31 localhost su[19221]: pam_authenticate: Permission denied
Dec 17 18:06:31 localhost su[19221]: FAILED su for root by mc
Dec 17 18:06:31 localhost su[19221]: - pts/1 mc:root
Dec 17 18:06:40 localhost su[19222]: pam_authenticate: Permission denied
Dec 17 18:06:40 localhost su[19222]: FAILED su for root by mc
...

Первое, на что следует обратить внимание в листинге 3, - это то, что вход на удаленную машину осуществляется от имени суперпользователя root потому что файл, который необходимо просмотреть, доступен только суперпользователю. Для корректной работы убедитесь в том, что система поддерживает удаленный вход от имени root.

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

Листинг 4. Локальный отбор выдачи
$ ssh root@gentoo.vm "cat /var/log/messages" | grep 'su\[' 
Dec 17 18:05:37 localhost su[19218]: pam_authenticate: Permission denied
Dec 17 18:05:37 localhost su[19218]: FAILED su for root by mc
Dec 17 18:05:37 localhost su[19218]: - pts/1 mc:root
Dec 17 18:06:31 localhost su[19221]: pam_authenticate: Permission denied
Dec 17 18:06:31 localhost su[19221]: FAILED su for root by mc
Dec 17 18:06:31 localhost su[19221]: - pts/1 mc:root
Dec 17 18:06:40 localhost su[19222]: pam_authenticate: Permission denied
Dec 17 18:06:40 localhost su[19222]: FAILED su for root by mc
Dec 17 18:06:40 localhost su[19222]: - pts/1 mc:root

Естественно, результат будет одинаковым.

Тем не менее, использование цепочки команд при помощи вертикальной черты «|» является удобным, когда необходимо передать информацию удаленной команде. Например, можно использовать команду ls вместе с du для получения информации о размере нескольких каталогов, как показано в листинге 5.

Листинг 5. Определение размера нескольких каталогов
ssh root@gentoo.vm "ls -d /usr/local/* |xargs du -sh "
Password: 
4.0K    /usr/local/bin
4.0K    /usr/local/games
4.0K    /usr/local/lib
0       /usr/local/man
4.0K    /usr/local/sbin
12K     /usr/local/share
4.0K    /usr/local/src

До того как приступить к использованию этих способов на множестве машин, рассмотрим простой трюк для запуска удаленного интерактивного сеанса на отдельном компьютере без необходимости входа в систему.

Интерактивное подключение к одному компьютеру

Как было сказано выше, на одном компьютере можно запускать несколько различных команд и цепочек команд. Одно из преимуществ SSH заключается в том, что хотя команда выполняется удаленно, устройства ввода и вывода находятся на локальном компьютере. Можно использовать это в качестве способа обмена информацией между двумя машинами для команд, которые нужно выполнить.

Таким образом, можно использовать почти все команды. Тем не менее, поскольку команды запускаются из командной строки, существуют некоторые ограничения. Например, попытка редактировать удаленный файл редактором, при помощи способов и приемов, показанных выше, как правило, заканчивается безуспешно (см. листинг 6).

Листинг 6. Неудачное редактирование удаленного файла
$ ssh root@gentoo.vm "emacs /etc/amavisd.conf"
emacs: standard input is not a tty

Чтобы решить эту проблему, укажите SSH создавать псевдотерминал tty так, чтобы было возможно работать с удаленным приложением напрямую.

Запуск удаленной команды на множестве машин

До сих пор мы говорили о запуске одной команды или набора команд на одной удаленной машине. Хотя использование удаленного интерактивного сеанса удобно для администрирования отдельных компьютеров при помощи SSH, вы наверняка захотите автоматизировать этот процесс, что означает сокращение использования интерактивных элементов.

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

Это можно сделать при помощи очень простого цикла for, как показано в листинге 7.

Листинг 7. Цикл for для удаленного запуска команд
for remote in mc@gentoo.vm mc@redhat; do echo $remote; ssh $remote 'df -h'; done
mc@gentoo.vm
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda3              14G  4.1G  9.2G  31% /
udev                  126M  564K  125M   1% /dev
/dev/hdc1             1.9G   56M  1.8G   4% /var/tmp
/dev/hdc2             1.9G  1.3G  558M  70% /usr/portage
/dev/hdc3             1.9G   35M  1.8G   2% /home/build
shm                   126M     0  126M   0% /dev/shm
mc@redhat
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      7.1G  5.5G  1.3G  82% /
/dev/hda1              99M   13M   82M  14% /boot
none                  125M     0  125M   0% /dev/shm

На основе этого несложно создать простой скрипт, приведенный в листинге 8.

Листинг 8. Сокращение цикла for до простой команды
#!/bin/bash

# Скрипт для запуска команд на множестве машин

# Общие параметры

TIMEOUT=10
ERRLOG=/tmp/remote-err-$$.log
OUTLOG=/tmp/remote-out-$$.log

# Extract the command line

MACHINES=$1;shift
COMMAND=$1;shift

for machine in $MACHINES
do
    echo $machine
    ssh -oConnectTimeout=$TIMEOUT $machine $
    COMMAND >>$OUTLOG 2 >>$ERRLOG

done

cat $OUTLOG
cat $ERRLOG >&2
rm -f $OUTLOG $ERRLOG

MACHINES и COMMAND представляют собой переменные, обрабатываемые в командной строке. При использовании скрипта имя пользователя, хоста и выполняемую команду необходимо заключить в двойные кавычки, чтобы они определялись в качестве одного аргумента.

Единственным дополнением является параметр TIMEOUT. Он назначает для SSH параметр ConnectTimout, чтобы при запуске команды не пришлось напрасно ждать подключения к хосту, который может быть отключен. Значение по умолчанию указано в начале скрипта и гарантирует, что ждать слишком долго не придется.

При запуске команд, выдача отправляется в несколько файлов журналов, на одно стандартное устройство вывода и другое стандартное устройство вывода сообщений об ошибках. Затем можно выводить эту информацию по отдельности в соответствующие места. Это подчеркивает одно из преимуществ использования SSH – вывод от удаленных машин перенаправляются на одно устройстов (стандартное устройство вывода, стандартное устройство вывода сообщений об ошибках), поэтому можно перенаправить выдачу на локальное устройство.

Например, можно повторить проверку df при помощи скрипта:

$ runremote.sh "gentoo redhat" "df -h"

Поскольку стандартные устройства вывода и сообщений об ошибках перенаправлены, можно даже создать журнал всего процесса:

$ runremote.sh "gentoo redhat" "df -h" 2>/tmp/error.log

Использование удаленных команд для мониторинга производительности

При использовании скрипта runremote.sh возможно вам захочется поэкспериментировать со значением времени ожидания и изменить это значение в зависимости от своих задач. Например, если скрипт используется для получения снимка текущего состояния, проверяя время работы группы машин, не следует ждать подключения и выполнения команд слишком долго, иначе снимок будет неточным.

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

Немного скорректированный скрипт runremote2 приведен в листинге 9. Он запускает удаленные команды почти одновременно (в фоновом режиме), а затем выполняет вывод в отдельные файлы журналов.

Листинг 9. Скрипт, выполняющий удаленные команды почти одновременно
#!/bin/bash

# Скрипт для запуска команд на множестве машин

# Общие параметры

TIMEOUT=10
ERRLOG=/tmp/remote-err-$$.log
OUTLOG=/tmp/remote-out-$$.log

# Обработка командной строки

MACHINES=$1;shift
COMMAND=$1;shift

for machine in $MACHINES
do
    echo $machine >>$OUTLOG.$machine
    ssh -oConnectTimeout=$TIMEOUT 
    $machine $COMMAND >>$OUTLOG.$machine
	2>>$ERRLOG.$machine &
done

# Ждать завершения дочерних процессов

wait

cat $OUTLOG.*
cat $ERRLOG.* >&2
rm -f $OUTLOG.* $ERRLOG.*

Этот скрипт также выводит имя обрабатываемого компьютера в журнал (отдельный для каждой машины). Чтобы гарантировать, что скрипт не закроется до завершения всех удаленных команд, необходимо добавить команду wait для ожидания завершения дочерних процессов скрипта.

Теперь можно использовать этот скрипт для одновременной проверки множества машин (см. листинг 10).

Листинг 10. Использование скрипта для одновременной проверки множества машин
$ runremote2.sh "narcissus gentoo.vm droopy@nostromo mcbrown@nautilus" 'uptime'
droopy@nostromo
19:15  up 9 days, 23:42, 1 user, load averages: 0.01 0.03 0.00
gentoo.vm
 18:10:23 up 1 day, 10:02,  2 users,  load average: 1.72, 1.84, 1.79
mcbrown@nautilus
19:15  up 10:08, 4 users, load averages: 0.40 0.37 0.29
narcissus
19:15  up 8 days,  7:04, 4 users, load averages: 0.53 0.54 0.57

Этот вид мониторинга удобен, когда необходимо получить представление обо всей сети – например, для выявления проблемы с группой кластеров компьютеров, обслуживающих web-службы или базы данных, и выявить пиковые значения или проблемы, общие для группы машин.

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

Запуск одинаковых действий на множестве машин

Создание учетных записей пользователей на множестве машин может стать утомительной процедурой делом. Разумеется, существуют различные решения этой проблемы на основе средств единого входа, таких как Network Information Service (NIS) или решении на основе LDAP, но не всегда возможно синхронизировать учетные записи таким способом.

Для этого можно использовать SSH, запустив команду adduser на множестве машин. Но в ОС Solaris эта команда называется useradd. Параметры командной строки в основном совпадают, поэтому можно использовать скрипт run-remote.sh дважды (см. листинг 11).

Листинг 11. Двойной запуск скрипта run-remote.sh
$ runremote.sh "gentoo redhat" "adduser -u 1000 -G sales,marketing mcbrown"
$ runremote.sh "solaris solaris-x86" "useradd -u 1000 -G sales,marketing mcbrown"

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

Намного лучше будет использовать совет, приведенный в статье Инструментарий системного администратора: Стандартизация инструментов командной строки UNIX (см. раздел Ресурсы) для использования одинаковой команды на множестве машин:

$ runremote.sh "gentoo solaris" "adduser.sh -u 1000 -G sales,marketing mcbrown"

Заключение

В этой статье вы познакомились с простым, но мощным методом запуска команд на удаленных машинах. Хотя основы этого процесса очевидны, можно расширить функциональность для выполнения некоторых задач удаленного администрирования (например, возможность перенаправлять и создавать цепочку из удаленного и локального ввода). При помощи некоторых простых приемов в скриптах можно использовать эту систему для одновременного удаленного администрирования множества машин, облегчая многие повторяющиеся задачи и мониторинг производительности.

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=498921
ArticleTitle=Инструментарий системного администратора: Распределенное администрирование при помощи SSH
publish-date=07022010