[Системное администрирование] ossh: параллельное выполнение команд на многих серверах
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Иногда бывает нужно запустить патч Бармина какую-то команду на многих серверах и желательно не ждать слишком долго результатов выполнения. Для этого я написал ossh (One SSH to rule them all). Вот пример его работы:
$ wc -l /tmp/ossh.ips
21418 /tmp/ossh.ips
$ time ossh -n -h /tmp/ossh.ips -c uptime -p 1000 >/tmp/ossh.out
real 3m10.310s
user 0m30.970s
sys 0m19.282s
$ grep 'load average' /tmp/ossh.out | sort -n -k5 | tail -n1
10.23.91.97 [1] 13:37:55 up 828 days, 2:34, 0 users, load average: 8.29, 4.45, 3.90
$
В данном примере в файле /tmp/ossh.ips находится 21418 ip адресов машин. -n означает, что не нужно делать реверс запросы, чтобы определить имя по адресу. -c uptime задает команду, которую я хочу выполнить. -p 1000 позволяет использовать до 1000 соединений одновременно. Как видно из вывода отработала команда достаточно быстро.
Что еще умеет ossh?
$ ossh -?
Usage: ossh [-?AinPv] [-c COMMAND] [-C COMMAND_FILE] [-H HOST_STRING] [-h HOST_FILE] [-I FILTER] [-k PRIVATE_KEY] [-l USER] [-o PORT] [-p PARALLELISM] [-T TIMEOUT] [-t TIMEOUT] [parameters ...]
-?, --help Show help
-A, --askpass Prompt for a password for ssh connects
-c, --command=COMMAND
Command to run
-C, --command-file=COMMAND_FILE
file with commands to run
-H, --host=HOST_STRING
Add the given HOST_STRING to the list of hosts
-h, --hosts=HOST_FILE
Read hosts from file
-i, --ignore-failures
Ignore connection failures in the preconnect mode
-I, --inventory=FILTER
Use FILTER expression to select hosts from inventory
-k, --key=PRIVATE_KEY
Use this private key
-l, --user=USER Username for connections [$LOGNAME]
-n, --showip In the output show ips instead of names
-o, --port=PORT Port to connect to [22]
-p, --par=PARALLELISM
How many hosts to run simultaneously [512]
-P, --preconnect Connect to all hosts before running command
-T, --connect-timeout=TIMEOUT
Connect timeout in seconds [60]
-t, --timeout=TIMEOUT
Run timeout in seconds
-v, --verbose Verbose output
$
Список хостов можно задать либо прямо в командной строке через опцию -H (в случае нескольких хостов их надо перечислить через пробел, а весь список взять в кавычки как в примерах ниже) либо загрузить из файла при помощи опции -h. Строки в файле, начинающиеся с #, игнорируются. Адрес может содержать порт: my.host:2222. Можно использовать brace expansion: «host{1,3..5}.com» превратится в «host1.com host3.com host4.com host5.com». И -H и -h можно использовать многократно.
Для авторизации будут использованы
- пароль, который ossh запросит при использовании опции -A
- ssh ключ, заданный опцией -k
- ssh-agent (в этом случае у вас должна быть определена переменная окружения SSH_AUTH_SOCK)
Именно в таком порядке.
Иногда бывает нужно убедиться, что вы можете залогиниться на все машины прежде чем выполнить команду. Для этого есть опция -P. По умолчанию если хоть одна машина будет недоступна ossh завершится с ошибкой. Если вы хотите игнорировать неудачные соединения используйте опцию -i.
Ossh может использовать вашу систему инвентаризации. Для этого в путях должна находится команда ossh-inventory, которой будут переданы параметры опции -I. Эта опция может быть использована многократно. Команда ossh-inventory должна выдавать на стандартный вывод строки в формате:
имя_машины адрес_машины
Где адрес_машины может быть как днс именем, так и ip адресом.
Команды для выполнения задаются опциями -C (читать из файла) или -c (брать из командной строки). Эти опции могут использоваться многократно. При наличии и -C и -c сперва выполнятся команды из файлов, потом из командной строки.
Помимо просто выполнения команд при помощи ossh можно стримить логи в реальном времени:
$ ossh -H "web05 web06" -c "tail -f -c 0 /var/log/nginx/access.log|grep --line-buffered Wget"
web05 192.168.1.23 - - [22/Jun/2016:12:24:02 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
web05 192.168.1.49 - - [22/Jun/2016:12:24:07 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
web06 192.168.1.117 - - [22/Jun/2016:12:24:23 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
web05 192.168.1.29 - - [22/Jun/2016:12:24:30 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
...
Вот симуляция rolling deployment:
$ ossh -p 1 -H "test0{1..3}" -c "sleep 10 && date"
test01 Wed Jun 22 12:38:24 PDT 2016
test02 Wed Jun 22 12:38:34 PDT 2016
test03 Wed Jun 22 12:38:44 PDT 2016
$
Видно, что команды выполняются на машинах последовательно. В каждый момент времени задействована только одна машина. Для настоящего деплоймента «sleep 10 && date» надо заменить на, к примеру, “apt-get install -y your_package”.
Именно для деплоймента была написана самая первая версия ossh. Кто-то спросит почему я не использовал какую-то общепринятую систему управления конфигурациями? Дело в том, что это было в далеком 2013-м году и мы использовали chef. Было ясно, что chef нас не устраивает в частности неопределенностью когда именно будут применены изменения (chef-client отрабатывал раз в 30 минут). Для того, чтобы согласованно выкатывать изменения на многих машинах некоторые разработчики применяли грязный хак: chef-client не работал постоянно, а однократно запускался (через ssh) только в тот момент, когда было нужно сделать деплоймент. Уже в тот момент шла работа по замене chef на salt, но переход был не простым и завершение его требовало дополнительного времени. Мы же разрабатывали новый сервис, который требовал частых деплойментов и раскатывался единственным дебиановским пакетом. Сперва мы использовали утилиту knife из состава chef. Эта утилита позволяла соединяться по ssh с нужными серверами и выполнять на них команды. В какой-то моент я понял, что chef в данном случае является лишним звеном и написал ossh.
Важно отметить, что ossh является инструментом для разрешения масштабных и нестандартных проблем. Если необходимость использовать ossh возникает часто это повод задуматься все ли у вас хорошо с инфраструктурой и управлением серверами. Вот некоторые ситуации, в которых ossh помог лично мне:
- Однажды я наводил порядок в /root/.ssh/authorized_keys на большом количестве серверов (на тот момент их было около 7000). Разработчики прописали туда свои ключи, в частности для процессов обновления своих сервисов. Нужно было получить список всех ключей, использованных на всех машинах, и убедиться, что удаление этих ключей не приведет к катастрофическим последствиям.
- Для безболезненного прохождения leap second
- Когда мы боролись с TCP SACK PANIC правила для iptables выкатывались системой управления конфигураций. Чтобы убедиться, что все хорошо, я проверил наличие нужных правил при помощи ossh. И это было совсем не зря, обнаружились машины, на которых правила не применились.
- Иногда мне приходится создавать тестовые среды состоящие из сотен (а иногда из тысяч) машин. Часто эти машины изолированы от production сети и не доступны для штатной системы управления конфигурациями. В подобных ситуациях конфигурирование машин можно проводить при помощи ossh.
Предвижу вопрос почему я не использовал готовое решение. Как я упомянул выше необходимость в прогонах команд на тысячах машин первый раз возникла у меня в 2013-м году. На тот момент мне удалось найти только parallel ssh, который не устроил меня следующим:
- Мне не удалось поднять параллелизм выше 150, начали возникать ошибки при соединении с удаленными серверами
- parallel ssh накапливал весь вывод и выдавал его по завершении команды. Стримить логи, к примеру, с его помощью было невозможно
- Вывод parallel ssh был (лично для меня) неудобен для парсинга
Исходно ossh был написан на ruby, для увеличения производительности я задействовал event machine, а потом и fiber-ы. Относительно недавно я переписал ossh на go. Буду признателен если go-эксперты (я таковым на данный момент не являюсь) посмотрят на мой код и укажут на возможные способы улучшить его.
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, *nix] FOSS News №60 – дайджест материалов о свободном и открытом ПО за 8-14 марта 2021 года
- [Системное администрирование, DevOps, Kubernetes] Как заменить container runtime в Kubernetes (перевод)
- [Информационная безопасность, Open source, Системное администрирование, GitHub, Разработка под Linux] Эксперты обнаружили критическую уязвимость в подсистеме iSCSI ядра Linux, баг в коде был с 2006 года
- [Python, *nix, C, Разработка под Linux] C и Python: мост между мирами
- Уязвимость в подсистеме iSCSI ядра Linux, позволяющая поднять свои привилегии
- [Информационная безопасность, Системное администрирование, 1С] Приключения персональных данных в России. Как стоматология защитила персональные данные
- [Информационная безопасность, Системное администрирование, IT-компании] Microsoft подтвердила проблемы с мартовскими обновлениями для различных версий Windows 10
- [Программирование, C++, C, Разработка под Linux] Неблокирующие паттерны: атомарные операции и частичные барьеры памяти (перевод)
- Весеннее обновление стартовых наборов ALT p9
- [Информационная безопасность, Системное администрирование, IT-инфраструктура, Софт] Файрвол PF в ОС FreeBSD
Теги для поиска: #_sistemnoe_administrirovanie (Системное администрирование), #_ssh, #_linux, #_sistemnoe_administrirovanie (
Системное администрирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:17
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Иногда бывает нужно запустить патч Бармина какую-то команду на многих серверах и желательно не ждать слишком долго результатов выполнения. Для этого я написал ossh (One SSH to rule them all). Вот пример его работы: $ wc -l /tmp/ossh.ips
21418 /tmp/ossh.ips $ time ossh -n -h /tmp/ossh.ips -c uptime -p 1000 >/tmp/ossh.out real 3m10.310s user 0m30.970s sys 0m19.282s $ grep 'load average' /tmp/ossh.out | sort -n -k5 | tail -n1 10.23.91.97 [1] 13:37:55 up 828 days, 2:34, 0 users, load average: 8.29, 4.45, 3.90 $ В данном примере в файле /tmp/ossh.ips находится 21418 ip адресов машин. -n означает, что не нужно делать реверс запросы, чтобы определить имя по адресу. -c uptime задает команду, которую я хочу выполнить. -p 1000 позволяет использовать до 1000 соединений одновременно. Как видно из вывода отработала команда достаточно быстро. Что еще умеет ossh? $ ossh -?
Usage: ossh [-?AinPv] [-c COMMAND] [-C COMMAND_FILE] [-H HOST_STRING] [-h HOST_FILE] [-I FILTER] [-k PRIVATE_KEY] [-l USER] [-o PORT] [-p PARALLELISM] [-T TIMEOUT] [-t TIMEOUT] [parameters ...] -?, --help Show help -A, --askpass Prompt for a password for ssh connects -c, --command=COMMAND Command to run -C, --command-file=COMMAND_FILE file with commands to run -H, --host=HOST_STRING Add the given HOST_STRING to the list of hosts -h, --hosts=HOST_FILE Read hosts from file -i, --ignore-failures Ignore connection failures in the preconnect mode -I, --inventory=FILTER Use FILTER expression to select hosts from inventory -k, --key=PRIVATE_KEY Use this private key -l, --user=USER Username for connections [$LOGNAME] -n, --showip In the output show ips instead of names -o, --port=PORT Port to connect to [22] -p, --par=PARALLELISM How many hosts to run simultaneously [512] -P, --preconnect Connect to all hosts before running command -T, --connect-timeout=TIMEOUT Connect timeout in seconds [60] -t, --timeout=TIMEOUT Run timeout in seconds -v, --verbose Verbose output $ Список хостов можно задать либо прямо в командной строке через опцию -H (в случае нескольких хостов их надо перечислить через пробел, а весь список взять в кавычки как в примерах ниже) либо загрузить из файла при помощи опции -h. Строки в файле, начинающиеся с #, игнорируются. Адрес может содержать порт: my.host:2222. Можно использовать brace expansion: «host{1,3..5}.com» превратится в «host1.com host3.com host4.com host5.com». И -H и -h можно использовать многократно. Для авторизации будут использованы
Именно в таком порядке. Иногда бывает нужно убедиться, что вы можете залогиниться на все машины прежде чем выполнить команду. Для этого есть опция -P. По умолчанию если хоть одна машина будет недоступна ossh завершится с ошибкой. Если вы хотите игнорировать неудачные соединения используйте опцию -i. Ossh может использовать вашу систему инвентаризации. Для этого в путях должна находится команда ossh-inventory, которой будут переданы параметры опции -I. Эта опция может быть использована многократно. Команда ossh-inventory должна выдавать на стандартный вывод строки в формате: имя_машины адрес_машины
Где адрес_машины может быть как днс именем, так и ip адресом. Команды для выполнения задаются опциями -C (читать из файла) или -c (брать из командной строки). Эти опции могут использоваться многократно. При наличии и -C и -c сперва выполнятся команды из файлов, потом из командной строки. Помимо просто выполнения команд при помощи ossh можно стримить логи в реальном времени: $ ossh -H "web05 web06" -c "tail -f -c 0 /var/log/nginx/access.log|grep --line-buffered Wget"
web05 192.168.1.23 - - [22/Jun/2016:12:24:02 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)" web05 192.168.1.49 - - [22/Jun/2016:12:24:07 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)" web06 192.168.1.117 - - [22/Jun/2016:12:24:23 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)" web05 192.168.1.29 - - [22/Jun/2016:12:24:30 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)" ... Вот симуляция rolling deployment: $ ossh -p 1 -H "test0{1..3}" -c "sleep 10 && date"
test01 Wed Jun 22 12:38:24 PDT 2016 test02 Wed Jun 22 12:38:34 PDT 2016 test03 Wed Jun 22 12:38:44 PDT 2016 $ Видно, что команды выполняются на машинах последовательно. В каждый момент времени задействована только одна машина. Для настоящего деплоймента «sleep 10 && date» надо заменить на, к примеру, “apt-get install -y your_package”. Именно для деплоймента была написана самая первая версия ossh. Кто-то спросит почему я не использовал какую-то общепринятую систему управления конфигурациями? Дело в том, что это было в далеком 2013-м году и мы использовали chef. Было ясно, что chef нас не устраивает в частности неопределенностью когда именно будут применены изменения (chef-client отрабатывал раз в 30 минут). Для того, чтобы согласованно выкатывать изменения на многих машинах некоторые разработчики применяли грязный хак: chef-client не работал постоянно, а однократно запускался (через ssh) только в тот момент, когда было нужно сделать деплоймент. Уже в тот момент шла работа по замене chef на salt, но переход был не простым и завершение его требовало дополнительного времени. Мы же разрабатывали новый сервис, который требовал частых деплойментов и раскатывался единственным дебиановским пакетом. Сперва мы использовали утилиту knife из состава chef. Эта утилита позволяла соединяться по ssh с нужными серверами и выполнять на них команды. В какой-то моент я понял, что chef в данном случае является лишним звеном и написал ossh. Важно отметить, что ossh является инструментом для разрешения масштабных и нестандартных проблем. Если необходимость использовать ossh возникает часто это повод задуматься все ли у вас хорошо с инфраструктурой и управлением серверами. Вот некоторые ситуации, в которых ossh помог лично мне:
Предвижу вопрос почему я не использовал готовое решение. Как я упомянул выше необходимость в прогонах команд на тысячах машин первый раз возникла у меня в 2013-м году. На тот момент мне удалось найти только parallel ssh, который не устроил меня следующим:
Исходно ossh был написан на ruby, для увеличения производительности я задействовал event machine, а потом и fiber-ы. Относительно недавно я переписал ossh на go. Буду признателен если go-эксперты (я таковым на данный момент не являюсь) посмотрят на мой код и укажут на возможные способы улучшить его. =========== Источник: habr.com =========== Похожие новости:
Системное администрирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:17
Часовой пояс: UTC + 5