PDSH: Параллельное выполнение команд на нескольких Linux-серверах
В данной статье я расскажу вам, как управлять большим парком Linux серверов из консоли одного сервера, выполнять удаленно команды на других серверах и получать их результаты, проверять состояние серверов и выполнять параллельно однотипные работы с помощью утилиты pdsh. Разберемся в ее установке, настройке и параллельном запуске команд на нескольких серверах.
PDSH (parallel distributed shell) — высокопроизводительная утилита для параллельного запуска команд на большом количестве Linux-серверов через ssh. По умолчанию pdsh позволяет поддерживать 32 параллельных соединения с управляемыми северами. Для pdsh есть несколько полезных модулей расширения, которые мы также рассмотрим в этой статье.
С помощью pdsh вы можете:
- Обновлять ПО на серверах;
- Установить необходимые модули или утилиты;
- Запустить какой-то bash скрипт;
- Проверить наличие обновлений и многое другое.
Установка PDSH и дополнительных модулей
Сначала нужно установить утилиту pdsh и нужные модули. В CentOS установка выполняется через менеджер пакетов yum:
yum install epel-release -y
– подключаем репозиторий Epel
yum install pdsh pdsh-mod-genders -y
— устанавливаем pdsh и модуль genders для него.
В целом для настройки pdsh больше ничего и не нужно. Мы установили сам pdsh, а так же установили дополнительный модуль pdsh-mod-genders, о котором я расскажу чуть позже, когда мы перейдем к запуску команд на удаленных серверах.
Настройка сервера управления pdsh и управляемых Linux-серверов.
Чтобы не вводить каждый раз пароли для подключения к удаленным серверам, мы выполним генерацию ключа ssh на сервере управления с установленным pdsh и добавим его на управляемые сервера.
ssh-keygen -q
Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again:
Запустив команду
ssh-keygen -q
на все вопросы просто жмем Enter. Ключ готов, теперь осталось скопировать его на управляемые Linux-сервера. В качестве примера я взял 2 сервера с Linux CentOS.
На управляемых серверах создайте директорию для ssh ключа (если таковой нет):
mkdir /root/.ssh/
Скопируем ключ в данный каталог, я это делаю через echo:
echo -e "ваш ключ с файла /root/.ssh/id_rsa.pub" >> /root/.ssh/authorized_keys
Ключ добавлен, нужно проверить проходит ли соединение с pdsh-сервера:
ssh server1
Все в порядке.
Примеры использования pdsh для запуска команд на множестве серверов
Так как ряд серверов может отличаться по hostname , я для себя сделал такую схему настройки PDSH. В файл hosts на управляющем сервере с pdsh я добавляю каждый управляемый сервер и присваиваю ему удобное мне имя, например:
cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 *.*.*.* server1 *.*.*.* server2
Где вместо звездочек нужно указать IP destination-серверов.
Чтобы pdsh мог подключиться на заданные имена серверов, в файле /root/ssh/known_hosts к ключу каждого управляемого сервера, через запятую нужно добавить желаемое имя сервера, которое мы указали в /etc/hosts. Например:
После этого вы сможете подключаться по тому hostname, которое выбрали для удобства, это нам пригодится, если у нас будет 100500 серверов, которые именуются вразнобой.
Для запуска команды на удаленном сервере через pdsh используется такой конструкция:
pdsh -w server1 'команда'
— я всегда советую брать в кавычки запускаемые команды, так как если вы будете использовать спецсимволы, bash на сервере с pdsh выполнит команду после спецсимвола локально.
Например, чтобы узнать время на удаленных серверах, можно выполнить команду для каждого из них.
pdsh -w server1 'date'
server1: Sat Sep 14 12:27:16 +06 2019
pdsh -w server2 'date'
server2: Sat Sep 14 12:27:21 +06 2019
Или выполнить одну команду сразу для списка серверов:
pdsh -w server1,server2 'date'
server1: Sat Sep 14 12:36:20 +06 2019 server2: Sat Sep 14 12:36:20 +06 2019
Если нужно выполнить команду на 10-ти серверах, получится довольно длинная команда с перечислением всех серверов, что неудобно. Т.к. мы задали собственные hostname для серверов, и pdsh это понимает, при вызове pdsh можно укажите конкретные сервера или диапазон серверов в квадратных скобках:
pdsh -w server[1-2] 'date'
— диапазон серверов в моем случае 2 сервера. Может быть от 1 до 20, выглядеть будет так:
pdsh -w server[1-20] 'date'
pdsh -w server[1,2] 'date'
— конкретные сервера 1 и 2, можно выбрать например 3-4 сервера и команды будет выглядеть следующим образом:
pdsh -w server[1,2,7,9] 'date'
Для более удобного форматирования вывод результатов команд с удаленных серверов можно использовать конструкцию:
pdsh -w server[1-20] ‘uptime’ | sort -n
Рассмотрим ранее установленный модуль pdsh-mod-gendors. Чтобы воспользоваться им, создадим сам файл:
touch /etc/genders
Для чего же он нужен? Genders – это файл с собственным синтаксисом для описания ролей pdsh. Как его можно применить в работе? Например:
- У вас есть 10 серверов с Ubuntu. Мы объединим их в одну группу Ubuntu, пусть их хостнеймы будут ubuntu1-10.
В файл /etc/genders прописываем следующие строки:ubuntu[1-10] ubuntu
- У вас есть 10 серверов с Centos и аналогичные хостнеймы — centos1-10:
centos[1-10] centos
- Так же есть группа серверов для разработчиков — web1-10:
web[1-10] web
- Если есть группа серверов с разными именами, например sys[1-5] и adm[4-8]:
sys[1-5] our adm[4-8] our
Т.е. в файле /etc/genders вы можете создать различные группы Linux серверов. Чтобы pdsh читал данные из файла genders при запуске вместо ключа –w нужно указывать –g.
В моем случае сервера по-прежнему два, но это ничего не меняет:
[root@server etc]# pdsh -g centos 'date'
server1: Sat Sep 14 12:49:59 +06 2019 server2: Sat Sep 14 12:50:00 +06 2019
Так гораздо удобнее и команда выполняется на всех серверах в группе.
По умолчанию pdsh позволяет запускать до 32 параллельных сессий на разных серверах. Количество одновременно запущенных команд указывается с помощью ключа –f. Например, при
-f 1
пока команда не выполнится на первом сервере, ко второму она не перейдет.
На примере нашей команды это выглядит так:
pdsh -g ubuntu 'date' -f 1
Так же можно применять ключи -t и -u:
-
-t
– установить время ожидания подключения в секундах; -
-u
– установить время ожидания выполнения удаленной команды.
И в заключении я хотел бы привести несколько примеров, как вы можете использовать pdsh при управлении группами серверов Linux.
Следующая команда на всех указанных серверха выполнит переход в указанноу нам директорию и скачает в нее iso-образ Centos 7:
pdsh -w server[1,2] 'cd /root && wget _http://mirror.yandex.ru/centos/7.7.1908/isos/x86_64/CentOS-7-x86_64-Minimal-1908.iso'
Хотите быстро проверить какие репозитории установлены на управляемых серверах?
pdsh -w server[1,2] 'yum repolist'
server2: Loaded plugins: fastestmirror server2: Loading mirror speeds from cached hostfile server2: * base: repo.centos.ru server2: * extras: repo.centos.ru server2: * updates: repo.centos.ru server2: repo id repo name status server2: base/7/x86_64 CentOS-7 - Base 10,019 server2: extras/7/x86_64 CentOS-7 - Extras 435 server2: updates/7/x86_64 CentOS-7 - Updates 2,500 server2: repolist: 12,954 server1: Loaded plugins: fastestmirror server1: Loading mirror speeds from cached hostfile server1: * base: repo.centos.ru server1: * extras: repo.centos.ru server1: * updates: repo.centos.ru server1: repo id repo name status server1: base/7/x86_64 CentOS-7 - Base 10,019 server1: extras/7/x86_64 CentOS-7 - Extras 435 server1: updates/7/x86_64 CentOS-7 - Updates 2,500 server1: repolist: 12,954
pdsh -w server[1,2] 'yum install httpd -y'
– установка apache на оба сервера
И проверим установилось ли действительно:
То есть, можно выполнить какую угодно команду сразу на нескольких удаленных серверах. Если вы хотите запустить какой-то скрипт bash, я бы советовал добавить его в какой-то файл и скопировать на нужные сервера, после чего произвести его запуск.
На этом, пожалуй, все, надеюсь информация будет для вас полезной и облегчит рутинные задачи управления множеством серверов Linux.
Linux
PDSH: Параллельное выполнение команд на нескольких Linux-серверах