SSH로 많은 서버에 동시에 같은 명령내리기
예전에 PuTTYCS - 여러개의 putty를 띄워 같은 작업을 동시에 라는 글을 올리고 나서 주변에서 듣는 말.
"그거 기껏해야 수십 대 정도밖에 안되는거 아니에요? 관리해야 할 서버가 몇댄데..."
"화면은 안봐도 되니 그냥 자동화시켜 쭉 돌려버리고 싶어요."
"후후 전 이미 그런 작업을 하기위한 스크립트를 만들어(기존에 있는 걸 약간 고쳐서) 쓰고 있어요. 즐~"
"간단하게 하려면 ssh cmd로 해도 되긴 한데 여러 줄 명령을 못 내리기 때문에 여러 줄 명령을 실행하려면 스크립트를 서버 쪽으로 보내서 실행해야 하는 문제가 있어요."
등등...
뭐 맞는 말도 있고 틀린 말도 있다.
PuttyCS는 예전에 구글에서도 쓴다고 소개한 적 있는 clusterssh처럼 많아야 십여대정도 서버에 인터렉티브하게 함께 보면서 작업하고 싶을 때 쓰는 것이다.
만약 그 단위가 수백 대, 수천 대 단위로 넘어간다면 한 화면에 보기는 불가능하고 어떤 자동화된 절차를 통해서 명령을 내려야 할 것이다.
그렇다면 어떻게 그런 작업을 할 수 있을까?
ssh을 통해 특정서버에 명령을 실행시키려면 다음과 같이 한다.
<myserver 서버에 id로 로그인 하여 ls명령 실행>
ssh id@myserver ls
<ssh키를 등록해놓았을 때는 id는 생략하고 로그인 절차 없이 바로 실행, ;로 구분하여 여러 명령 실행>
ssh myserver "ls -la;df"
그러면 여러줄의 명령이나 특정 쉘스크립트,Perl스크립트 등등을 원격서버에 실행 시키면 어떻게 해야 할까? 간단한 쉘명령이야 ;로 나눠서 한 줄에 넣어서 실행하면 되지만 작업이 복잡해지면 그런 형태로는 한계가 있다. 그럴때는 다음과 같은 방법을 쓸 수 있다.
<HEREDOC을 사용하는 방법>
ssh myserver <<\EOF
ls -la
df
EOF
<별도의 쉘스크립트를 만들고 원격에 스크립트 해석기를 실행시키고 파이프나 리다이렉션으로 보내는 방법>
#!/bin/sh
ls -la
df
가 test_script.sh 이라고 하면
cat test_script.sh | ssh myserver sh
또는
ssh myserver sh < test_script.sh
<Perl 스크립트를 ssh를 통해 실행>
cat perl_script.pl | ssh myserver perl
또는
ssh myserver perl < perl_script.pl
이것을 기초로 여러 서버에 명령을 내리려면 다음처럼 서버의 리스트를 만들고 리스트에 대해 루프를 돌면서 위의 명령을 서버별로 실행하면 될 것이다.
<여러 서버에 루프를 돌면서 지정한 스크립트를 실행하는 스크립트>
#!/bin/sh
SERVERS="
myserver1
myserver2
"
for m in $SERVERS
do
ssh $m sh < test_script.sh
done
이렇게 하면 문제는 순차적으로 실행을 하기 때문에 한 서버씩 실행이 끝날 때 까지 기다려야 해서 속도가 늦고 나중에 결과를 보기가 힘들다는 것이다.
그러면
ssh $m sh < test_script.sh
줄을 다음과 같이
ssh $m sh < test_script.sh > $m.log &
고치면 각 ssh 명령이 fork되어서 백그라운드로 돌고 각 서버에 대한 결과는 서버이름.log 파일로 남게 된다. ( 작업결과는 *.log 파일들에 대해 grep이나 기타 유틸리티로 일괄적으로 확인 가능할 것이다. )
지금까지는 별도의 프로그램을 쓰지 않고 순수하게 기본 명령과 쉘스크립트 가지고 하는 방법이다. 하지만 이런 류의 작업은 다수의 서버를 관리 할 때 빈번하게 발생하므로 좀 더 많은 기능을 지원하면서 이런 작업을 해주는 프로그램이 많다.
shmux 라는 프로그램이 그런 것 중 하나인데 http://web.taranis.org/shmux/ 에 가보면 아랫쪽에 비슷한 기능을 하는 다음과 같은 프로그램 리스트가 쭉 있다.
Perl을 쓴다면 CPAN에만 해도 이런 류의 작업을 위한 모듈/유틸리티들로
http://search.cpan.org/perldoc?Net::SSH
http://search.cpan.org/perldoc?Net::SSH::Expect
http://search.cpan.org/perldoc?GRID::Machine
http://search.cpan.org/perldoc?Script::Remote
http://search.cpan.org/perldoc?Net::FullAuto
http://search.cpan.org/perldoc?netrun
이런 것들 등등.. 이 있다. (물론 이보다 많겠지만 다 찾지는 못했다.)
우와 많다!
보다시피 이런 건 무슨 대단한 기술도 아니고 찾아보면 널리고 널린 게 이런 류의 프로그램이다. 하지만 다들 자기 입맛에 맞지 않는지 아니면 기존에 이런 프로그램이 있는 걸 모르는지 계속 바퀴를 재발명하는 것 같아 안타깝다.
그래서 결론은 "니맘대로 적당한거 골라서 쓰세요." :)
"그거 기껏해야 수십 대 정도밖에 안되는거 아니에요? 관리해야 할 서버가 몇댄데..."
"화면은 안봐도 되니 그냥 자동화시켜 쭉 돌려버리고 싶어요."
"후후 전 이미 그런 작업을 하기위한 스크립트를 만들어(기존에 있는 걸 약간 고쳐서) 쓰고 있어요. 즐~"
"간단하게 하려면 ssh cmd로 해도 되긴 한데 여러 줄 명령을 못 내리기 때문에 여러 줄 명령을 실행하려면 스크립트를 서버 쪽으로 보내서 실행해야 하는 문제가 있어요."
등등...
뭐 맞는 말도 있고 틀린 말도 있다.
PuttyCS는 예전에 구글에서도 쓴다고 소개한 적 있는 clusterssh처럼 많아야 십여대정도 서버에 인터렉티브하게 함께 보면서 작업하고 싶을 때 쓰는 것이다.
만약 그 단위가 수백 대, 수천 대 단위로 넘어간다면 한 화면에 보기는 불가능하고 어떤 자동화된 절차를 통해서 명령을 내려야 할 것이다.
그렇다면 어떻게 그런 작업을 할 수 있을까?
ssh을 통해 특정서버에 명령을 실행시키려면 다음과 같이 한다.
<myserver 서버에 id로 로그인 하여 ls명령 실행>
ssh id@myserver ls
<ssh키를 등록해놓았을 때는 id는 생략하고 로그인 절차 없이 바로 실행, ;로 구분하여 여러 명령 실행>
ssh myserver "ls -la;df"
그러면 여러줄의 명령이나 특정 쉘스크립트,Perl스크립트 등등을 원격서버에 실행 시키면 어떻게 해야 할까? 간단한 쉘명령이야 ;로 나눠서 한 줄에 넣어서 실행하면 되지만 작업이 복잡해지면 그런 형태로는 한계가 있다. 그럴때는 다음과 같은 방법을 쓸 수 있다.
<HEREDOC을 사용하는 방법>
ssh myserver <<\EOF
ls -la
df
EOF
<별도의 쉘스크립트를 만들고 원격에 스크립트 해석기를 실행시키고 파이프나 리다이렉션으로 보내는 방법>
#!/bin/sh
ls -la
df
가 test_script.sh 이라고 하면
cat test_script.sh | ssh myserver sh
또는
ssh myserver sh < test_script.sh
<Perl 스크립트를 ssh를 통해 실행>
cat perl_script.pl | ssh myserver perl
또는
ssh myserver perl < perl_script.pl
이것을 기초로 여러 서버에 명령을 내리려면 다음처럼 서버의 리스트를 만들고 리스트에 대해 루프를 돌면서 위의 명령을 서버별로 실행하면 될 것이다.
<여러 서버에 루프를 돌면서 지정한 스크립트를 실행하는 스크립트>
#!/bin/sh
SERVERS="
myserver1
myserver2
"
for m in $SERVERS
do
ssh $m sh < test_script.sh
done
이렇게 하면 문제는 순차적으로 실행을 하기 때문에 한 서버씩 실행이 끝날 때 까지 기다려야 해서 속도가 늦고 나중에 결과를 보기가 힘들다는 것이다.
그러면
ssh $m sh < test_script.sh
줄을 다음과 같이
ssh $m sh < test_script.sh > $m.log &
고치면 각 ssh 명령이 fork되어서 백그라운드로 돌고 각 서버에 대한 결과는 서버이름.log 파일로 남게 된다. ( 작업결과는 *.log 파일들에 대해 grep이나 기타 유틸리티로 일괄적으로 확인 가능할 것이다. )
지금까지는 별도의 프로그램을 쓰지 않고 순수하게 기본 명령과 쉘스크립트 가지고 하는 방법이다. 하지만 이런 류의 작업은 다수의 서버를 관리 할 때 빈번하게 발생하므로 좀 더 많은 기능을 지원하면서 이런 작업을 해주는 프로그램이 많다.
shmux 라는 프로그램이 그런 것 중 하나인데 http://web.taranis.org/shmux/ 에 가보면 아랫쪽에 비슷한 기능을 하는 다음과 같은 프로그램 리스트가 쭉 있다.
- dsh
- dssh
- fanout
- Kees Cook's gsh
- Mr. Shell
- multi-rsh
- multixterm
- mussh
- pssh
- p-run
- PyDsh
- remote_update.pl
- RGANG
- rshall
- tentakel
- vxargs
Perl을 쓴다면 CPAN에만 해도 이런 류의 작업을 위한 모듈/유틸리티들로
http://search.cpan.org/perldoc?Net::SSH
http://search.cpan.org/perldoc?Net::SSH::Expect
http://search.cpan.org/perldoc?GRID::Machine
http://search.cpan.org/perldoc?Script::Remote
http://search.cpan.org/perldoc?Net::FullAuto
http://search.cpan.org/perldoc?netrun
이런 것들 등등.. 이 있다. (물론 이보다 많겠지만 다 찾지는 못했다.)
우와 많다!
보다시피 이런 건 무슨 대단한 기술도 아니고 찾아보면 널리고 널린 게 이런 류의 프로그램이다. 하지만 다들 자기 입맛에 맞지 않는지 아니면 기존에 이런 프로그램이 있는 걸 모르는지 계속 바퀴를 재발명하는 것 같아 안타깝다.
그래서 결론은 "니맘대로 적당한거 골라서 쓰세요." :)
0 TrackBacks
Listed below are links to blogs that reference this entry: SSH로 많은 서버에 동시에 같은 명령내리기.
TrackBack URL for this entry: http://aero.sarang.net/cgi-bin/mt/mt-tb.cgi/104
이렇게 같은 용도의 프로그램들이 널리고 널려 있으면, 왠지 사용자 입장에서는 모두 다 한번씩은 테스트해봐야 할 것 같은 압박감을 느끼게 되더군요. (일부를 안 써 본 채로 선택하자면 꼭 더 좋은 걸 모르고 놓치는 느낌이) 그래서 저걸 다 테스트하느니 그냥 내가 만들고 말지라고 하는 건지도? :-)
@Raymundo ㅎㅎ 뭐 그렇죠..
Perl과 CPAN이 있다면 상상은 어렵지 않게 현실이 될 것이니... :)