Comments 26
NIH-синдром. Есть же ansible.
+6
Велосипеды разные нужны, велосипеды разные важны.
Я здесь вижу как минимум годный пример для изучения языка, во-вторых, кому-то ansible может не подойти по тем или иным причинам.
Я здесь вижу как минимум годный пример для изучения языка, во-вторых, кому-то ansible может не подойти по тем или иным причинам.
+5
Ansible выглядит очень интересно, спасибо. Но, я думаю, для многих задач системы вроде chef, puppet, ansible слишком громоздки в настройке, если вам нужно всего-лишь, скажем, выполнить «svn up» на всех серверах :). Как мне кажется, системы вроде ansible предназначены больше для управления конфигурациями, а libpssh, GoSSHa подходят для, например, деплоя кода (у нас используется libpssh+uftp для деплоя кода, puppet для сишных сервисов и системных пакетов, а также самописный, в 300 строк впраппер над rsync для управления конфигурациями nginx и прочего).
+5
Мы для деплоя использовали связку fabric + puppet, сейчас хотим заменить fabric на ansible, так как он умеет все то же и даже больше…
0
Из требований, что Ansible заявляет к управляемым хостам — только Python 2.4 (на деле — что-то около Python 2.6 + некоторые операции требуют дополнительные модули), но простые ssh-команды можно выполнять без дополнительной подготовки управляемых серверов.
Но за статью все равно спасибо.
Но за статью все равно спасибо.
+1
Автору, спасибо за статью и интересный опыт!
С другой стороны я давно хотел попробовать Ansible из-за его «безагентности». Недавно разговаривал с ними на SCALE, очень открытые и общительные ребята.
Моя инфраструктура — это зоопарк из Windows и Linux, поэтому puppet как нельзя лучше подходит в качестве единого средства управления конфигурациями. Эх, как бы я хотел роскошь *nix only!
С другой стороны я давно хотел попробовать Ansible из-за его «безагентности». Недавно разговаривал с ними на SCALE, очень открытые и общительные ребята.
Моя инфраструктура — это зоопарк из Windows и Linux, поэтому puppet как нельзя лучше подходит в качестве единого средства управления конфигурациями. Эх, как бы я хотел роскошь *nix only!
0
Расскажите, пожалуйста, почему вы решили сделать свою реализацию, а не воспользовались, к примеру, code.google.com/p/parallel-ssh/?
0
Все выше можно сделать спомошью xargs.
+4
Можно. Но, например, с общим таймаутом на исполнение будет уже довольно тяжело :). А если у вас сотни или тысячи серверов, то держать постоянно запущенными тысячи процессов кажется довольно расточительным, как для CPU, так и по потреблению памяти ядра.
+2
Помню, на старой работе писали скрипт на php, который выполнял команды на операторских компьютерах (~250 штук) по ssh (благо везде стоял одинаковый дистр и логин/пароль на админский аккаунт). Чуть позже всё это чудо мигрировало на самописную систему клиентов и сервера, написанных на python, через которую можно было управлять машинами, обновлять приложения операторов и т.п., а также иногда втихаря издеватся над этими ж операторами (zenity рулил).
Эх, было время…
Эх, было время…
0
Неплохо. По коду бросается в глаза, что background автора — динамические языки ruby/python… )
А что добавлено в расширенной версии для продашна?
А что добавлено в расширенной версии для продашна?
+1
Неужели все так плохо :)? В GoSSHa добавлен JSON-протокол для выполнения команд, поддержка зашифрованных ключей и ssh-agent, загрузка файлов.
+1
Без явных объявлений переменных читать код сложно. Не всегда понятно какой тип возвращает функция… )
0
Интересное замечание… :). Никогда об этом не задумывался, всегда опирался на здравый смысл, когда речь идет о типе возвращаемого значения из функции, слава богу в Go есть определенные соглашения, делающие интуитивное понимание типов возможным :). Но типы же при этом никуда не деваются и компилятор их проверяет, поэтому зачем писать лишние буквы :)?
+2
Типичный подход адепта языков с динамической типизацией… )) Не буду утверждать что этот подход плохой или хороший. У всего есть достоинства и недостатки…
Когда вам нужно будет поправить чужой код или добавить функционал здравого смысла вам не хватит. Вам придется лезть в документацию и/или прыгать по всему коду искать определения функций и типов…
Когда вам нужно будет поправить чужой код или добавить функционал здравого смысла вам не хватит. Вам придется лезть в документацию и/или прыгать по всему коду искать определения функций и типов…
0
Крупный провайдер. Сегментированная сеть с кучей цисок. И одна циска центральная.
Обычный день, ничто не предвещает беды. Вдруг падает вся сеть. Народ в панике ищет в чём проблема. Оборачивается один сисадмин и говорит: «Я дико извиняюсь. Программировал новую циску. Стёр конфиг старый, перегрузил… Оказалось, это был центральный маршрутизатор… Окошком ошибся»
(с)bash
0
sync/WaitGrope еще сейчас популярно в дизайне таких штук на Go
0
В badoo разрешили писать не на PHP/C++?
+1
Написал, для сравнения, то-же самое на Erlang. Запускать не пробовал.
В стандартной библиотеке есть полная реализация SSH сервера, клиента и SFTP.
Экономия строчек на SSH-ключи, но больше места занимает вычитывание ответов.
В стандартной библиотеке есть полная реализация SSH сервера, клиента и SFTP.
main([Cmd | Hosts]) ->
Timeout = 5000,
Master = self(),
erlang:send_after(Timeout, self(), timeout), % запускаем таймер
%% используем генератор списков для запуска параллельной задачи на каждый хост
[spawn_link(fun() -> task(Host, Cmd, Master, Timeout) end) || Host <- Hosts],
await(length(Hosts)).
task(Host, Cmd, Master, Timeout) ->
%% использует $USER, $HOME/.ssh/id_rsa по умолчанию
{ok, Conn} = ssh:connect(Host, 22, {}, Timeout), %тут timeout чисто номинально
%% SSH поддерживает мультиплексирование
{ok, Chan} = ssh_connection:session_channel(Conn, Timeout),
success = ssh_connection:exec(Conn, Chan, Cmd, Timeout),
Response = read_response(Conn, Chan, <<>>),
%% отправляем результат выполнения мастеру
Master ! {result, Host, Response}.
await(0) -> ok; % все результаты получены. Выходим.
await(N) ->
receive
{result, Host, Response} -> % пришло сообщение от одной из задач
io:format("Host: ~s; Response: ~p~n", [Host, Response]),
await(N - 1); % зацикливаемся
timeout -> % пришло сообщение от таймера
io:format("Timeout, but ~p tasks not ready!", [N])
end.
read_response(Conn, Chan, Acc) ->
%% рекурсивно читаем ответ команды
receive
{ssh_cm, Conn, {data, Chan, _, Data}} ->
%% цикл, собираем результат выполнения команды в аккумулятор
read_response(Conn, Chan, <<Acc/binary, Data/binary>>);
{ssh_cm, Conn, {closed, Chan}} ->
%% Команда отработала. Разрываем рекурсию.
Acc
end.
Экономия строчек на SSH-ключи, но больше места занимает вычитывание ответов.
+2
Ещё интересный доклад от Яндекса был на PyCon в прошлом году примерно на эту тему pycon.ru/2013/program/content/distributed-execution/ но там десятки тысяч серверов и вообще всё сложнее.
+1
Да, если серверов очень много, то по CPU намного дешевле один раз открыть соединения и посылать команды на исполнение. Как ни странно, GoSSHa в 500 строк на Go позволяет это делать :). Нет возможности проверить на 10 000 серверов, но на 500 серверах latency тоже получается в районе 0,5 сек на команду.
0
Ну а что,
Но в докладе не об этом. Там именно распределённая сеть какая то используется в стиле «клиентский ПК подключается к 50 аггрегаторам, каждый из которых подключается к другим 50 аггрегаторам, каждый из которых подключен к N конечных серверов». И при этом ответы выдаются не как есть а тоже аггрегируются, мерджатся и т.п. Деталей сейчас уже не помню.
conn.NewSession()
на каждую команду вроде ничего сложного. Но это не так часто нужно. Обычно нужно подключиться и выполнить одну-две команды.Но в докладе не об этом. Там именно распределённая сеть какая то используется в стиле «клиентский ПК подключается к 50 аггрегаторам, каждый из которых подключается к другим 50 аггрегаторам, каждый из которых подключен к N конечных серверов». И при этом ответы выдаются не как есть а тоже аггрегируются, мерджатся и т.п. Деталей сейчас уже не помню.
0
Sign up to leave a comment.
Исполнение SSH-команд на сотнях серверов с помощью Go