Параллельное выполнение команд на удаленных серверах средствами Bash

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

Принцип работы

Реализация базируется на трех простых составляющих:

  • Файл инвентаризации: список целевых хостов хранится в обычном текстовом файле.
  • Циклическая обработка: скрипт итерируется по списку серверов и инициирует SSH-соединение.
  • Параллелизм: для асинхронного выполнения используется оператор & (перевод процесса в фоновый режим), а для контроля нагрузки применяется счетчик с ожиданием завершения фоновых задач.

Реализация скрипта

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

#!/bin/bash
# parallel-ssh.sh
# Одновременное выполнение команд на хостах

HOSTFILE="hosts.txt"
CMD="$*"
MAX_PARALLEL=5   # ограничение параллельных подключений

if [[ -z "$CMD" ]]; then
    echo "Использование: $0 'команда для выполнения'"
    exit 1
fi

sem=0
while read -r host; do
    [[ -z "$host" || "$host" =~ ^# ]] && continue

    {
        echo ">>> [$host]"
        ssh -o BatchMode=yes -o ConnectTimeout=5 "$host" "$CMD" 2>&1 | sed "s/^/[$host] /"
    } &

    ((sem++))
    if (( sem >= MAX_PARALLEL )); then
        wait -n
        ((sem--))
    fi
done < "$HOSTFILE"

wait

Настройка и запуск

Для начала работы создайте файл hosts.txt, добавив в него IP-адреса или доменные имена целевых узлов:

server1
192.168.1.12
192.168.1.15

Запуск скрипта осуществляется передачей необходимой команды в качестве аргумента:

./parallel-ssh.sh "uptime"

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