많은 서버에서 SSH를 통해 자동으로 명령 실행


46

.txt 파일에 다음과 같은 IP 주소 목록이 있습니다.

1.1.1.1
2.2.2.2
3.3.3.3

모든 IP 주소 뒤에는 서버가 있으며 모든 서버에는 포트 22에서 실행되는 sshd가 있습니다. 모든 서버가 known_hosts목록에 없습니다 (내 PC의 Ubuntu 10.04 LTS / bash).

이 서버에서 명령을 실행하고 출력을 수집하려면 어떻게해야합니까?

이상적으로는 모든 서버에서 명령을 병렬로 실행하고 싶습니다.

모든 서버에서 공개 키 인증을 사용합니다.

잠재적 인 함정은 다음과 같습니다.

  • ssh는 주어진 서버 ssh 키를 known_hosts파일 에 넣으라는 메시지를 표시 합니다.
  • 주어진 명령은 0이 아닌 종료 코드를 반환하여 출력이 유효하지 않을 수 있음을 나타냅니다. 나는 그것을 인식해야합니다.
  • 예를 들어 네트워크 오류로 인해 지정된 서버에 연결하지 못할 수 있습니다.
  • 명령이 예상보다 오래 실행되거나 명령을 실행하는 동안 서버가 다운되는 경우 시간 종료가 있어야합니다.

서버는 AIX / ksh입니다 (그러나 나는 그것이 중요하지 않다고 생각합니다.



1
언급 한 링크에는 SSH가 포함되어 있지 않기 때문에 복제본이 아니라고 생각합니다.
LanceBaynes

4
그렇게하지 않으면 모든 컴퓨터에 ssh 서버를 설정하고 작업중인 컴퓨터에서 개인 / 공개 키 쌍을 만들고 공개 키를 서버의 계정에 복사하여 추가 암호 번거 로움을 방지해야합니다. 그것은 내 대답과 @demure에도 적용됩니다.
Anthon

답변:


14

pssh 또는 다른 장치를 설치할 수 없다고 가정하면 다음과 유사한 작업을 수행 할 수 있습니다.

tmpdir=${TMPDIR:-/tmp}/pssh.$$
mkdir -p $tmpdir
count=0
while IFS= read -r userhost; do
    ssh -n -o BatchMode=yes ${userhost} 'uname -a' > ${tmpdir}/${userhost} 2>&1 &
    count=`expr $count + 1`
done < userhost.lst
while [ $count -gt 0 ]; do
    wait $pids
    count=`expr $count - 1`
done
echo "Output for hosts are in $tmpdir"

1
이 스크립트에서 정확히 무엇을 기다 립니까? 타이!
LanceBaynes

서버 키가 knows_hosts 파일에 없으면 어떻게됩니까?
LanceBaynes

5
백그라운드에 스크립트를 넣으면 자식 프로세스가 만들어집니다. 하위 프로세스가 종료되면 상위 프로세스가 종료되거나 상위 프로세스가 하위 프로세스를 대기 할 때까지 프로세스 '슬롯'및 자원이 시스템에 유지됩니다. 이러한 '아직 존재하지 않는'프로세스를 '좀비'프로세스라고합니다. 자녀가 처리하고 자원을 확보 한 후에 정리하는 것이 좋습니다.
Arcege

1
알려지지 않은 경우 문제가 발생할 수 있지만 -o StrictHostKeyChecking=no이를 피하기 위해 추가 할 수 있습니다 . 그러나 호스트 키를 추가 할 수 있도록 명령 줄에서 모든 서버를 먼저 검색하는 것이 좋습니다.
Arcege

1
앞에서 언급했듯이 ssh 프로그램을 백그라운드에 넣고 종료 한 후에도 리소스는 계속 유지됩니다. 이 wait명령은 프로세스의 리턴 코드 (프로세스 종료 방법)를 포함하여 해당 자원을 재생합니다. 그런 다음 나중에 프로그램에서 다른 프로세스를 넣고 백그라운드에서 압축을 말하고 기다려야하는 경우이 루프가 없으면 대기가 압축이 아닌 완성 된 ssh 프로그램 중 하나를 회수합니다-여전히 실행 중입니다. 잘못된 자식 프로세스에서 반환 상태를 얻습니다. 자신을 정리하는 것이 좋습니다.
Arcege

61

여러 시스템에 동시에 로그인하여 일련의 명령을 실행할 수있는 몇 가지 도구가 있습니다. 여기 몇 가지가 있습니다 :


1
pdsh 를 목록 에 추가 할 수 있습니다 .
Riccardo Murri

1
clusterssh가 사용하기에 매우 직관적이라는 것을 알았습니다. 그냥 내 2 센트 ...
josinalvo

1
나는 자주 pssh를 사용한다. 특정 원격 명령에 0이 아닌 종료 코드가 있으며 오류를 의미하지 않는다는 것을 알 수 있기를 원하지만 매우 잘 작동합니다. 그래도 순전히 화장품입니다.
Anthony Clark

1
@AnthonyClark 명령에 "|| true"와 같은 것을 추가 할 수 있습니다.
exic

16

당신이에 경우 파이썬 이상 스크립팅 bash스크립트 다음 원단은 당신을위한 도구가 될 수 있습니다.

로부터 패브릭 홈 페이지 :

Fabric은 응용 프로그램 배포 또는 시스템 관리 작업에 SSH 사용을 간소화하기위한 Python (2.5 이상) 라이브러리 및 명령 줄 도구입니다.

로컬 또는 원격 셸 명령 (일반적으로 또는 sudo를 통해)을 실행하고 파일을 업로드 / 다운로드하고 실행중인 사용자에게 입력하라는 메시지를 표시하거나 실행을 중단하는 등의 보조 기능을 제공하는 기본 작업 제품군을 제공합니다.

일반적으로 하나 이상의 함수를 포함하는 Python 모듈을 만든 다음 fab 명령 줄 도구를 통해이를 실행합니다.


패브릭 v1은 훌륭했습니다. 불행하게도 Fabric v2는이 사용 사례에 유용한 대부분의 기능을 제거했습니다 (현재 권장하지 않음 (2018 년 6 월)).
Meekohi 2016 년

11

나는 이것을 위해 GNU 병렬 을 사용 합니다. 특히, 레시피를 사용할 수 있습니다 :

parallel --tag --nonall --slf your.txt command

your.txt서버 IP 주소 / 이름을 가진 파일 인.


ssh 만 사용하는 다른 방법은 없습니다. 회사 서버를 사용하고 있기 때문에 추가 패키지를 설치하고 싶지 않습니다.
Özzesh

물론, 이전 ssh에도이 작업을 수행 했지만 이전 에는 다른 컴퓨터에 로그인하는 방법과 덜 안전했던 방법이 필요합니다 (예 rsh:). 머신에서 머신으로 가져 오기 위해 현재 사용중인 것을 설명하지 않습니다 ( telnet?, rsh?).
Anthon

1
@ Özzesh는 컨트롤러에서만 가능
Anthon

1
Özzesh 참조 @ GNU 병렬 설치를하지 않는 이유는에 포함되어있는 경우 oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
올레 단게

1
@OleTange 방금 내 답변 %-)에 누가 댓글을 달았는지 알았습니다. 이 훌륭한 소프트웨어에 감사드립니다.
Anthon

8

매우 기본적인 설정 :

for host in $(cat hosts.txt); do ssh "$host" "$command" >"output.$host"; done

이름 / 암호로 인증하는 것은 실제로 좋은 생각이 아닙니다. 이를 위해 개인 키를 설정해야합니다.

ssh-keygen && for host in $(cat hosts.txt); do ssh-copy-id $host; done

1
이것은 내가 찾던 것입니다 !!!!! 감사합니다 michas
Özzesh

위의 스크립트는 나에게 잘 작동하지만 10 개의 서버에서 실행 한 후에는 스크립트가 응답하지 않습니다. 연결된 ssh 서버에서 어떻게 로그 아웃 할 수 있습니까?
Özzesh

명시 적으로 로그 아웃 할 필요는 없습니다. 이 "스크립트"는 ssh $host $command각 호스트마다 실행 됩니다. 진행중인 작업을 찾으려면 해당 명령을 수동으로 실행하십시오.
michas


2

나는 당신이 pssh 와 일반적인 scp, rsync 등의 관련 병렬 버전을 찾고 있다고 생각합니다 .


이것은 삭제되지 않은 한 표입니다. 그러나이 답변 은 +10입니다. 완벽한 이해
Michael Mrozek

@MichaelMrozek 그것은 당신이 알고있는 것보다 더 나쁘다. 두 VTD 중 두 번째는 클릭 행복 사고에 대한 광산입니다. VTD가 삭제 된 경우 VTD를 되돌 리도록 플래그를 지정하거나 ping하기 위해 며칠 동안이 탭을 열었습니다. 아마 투표를하기 위해 지금 뒤집을 수도 있습니다.
Caleb

@Caleb 고침
Michael Mrozek

2

이런 종류의 작업을 쉽게하기 위해 Overcast 라는 오픈 소스 도구 를 만들었습니다.

먼저 서버를 정의하십시오.

overcast import vm.01 --ip 1.1.1.1 --ssh-key /path/to/key
overcast import vm.02 --ip 2.2.2.2 --ssh-key /path/to/key

그런 다음 여러 명령과 스크립트 파일을 순차적으로 또는 병렬로 실행할 수 있습니다.

overcast run vm.* uptime "free -m" /path/to/script --parallel

2

Hypertable 프로젝트는 최근 다중 호스트 SSH 도구를 추가했다. 이 도구는 libssh로 빌드되며 최대 병렬 처리를 위해 연결을 설정하고 명령을 비동기식 및 병렬로 실행합니다. 전체 설명서는 다중 호스트 SSH 도구 를 참조하십시오 . 일련의 호스트에서 명령을 실행하려면 다음과 같이 실행하십시오.

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

다음과 같이 호스트 이름 또는 IP 패턴을 지정할 수도 있습니다.

$ ht ssh 1.1.1.[1-99] uptime
$ ht ssh host[00-99] uptime

또한 --random-start-delay <millis>0에서 <millis>밀리 초 사이의 임의 시간 간격으로 각 호스트에서 명령 시작을 지연 시키는 옵션을 지원합니다 . 이 옵션은 실행중인 명령이 중앙 자원에 액세스 할 때 천둥 무리 문제를 방지하는 데 사용할 수 있습니다.


2

collectnode 를 개발 했습니다. 여러 서버에서 작업을 실행하는 데 매우 간단하고 효과적입니다 (Windows 포함).

CollectNode를 사용하는 방법 :

  1. 작업 할 서버 목록을 작성하십시오.

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. 서브 목록을 전달하는 CollectNode를 실행하십시오.

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. 결과를 필터링 할 수도 있습니다. 예를 들어이 명령은 조건이 완료된 서버 만 표시합니다.

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User' --where="command contain User"
    

https://collectnode.com/5-tasks-collectnode-can-help-managing-servers/


1
CollectNode의 개발자 인 것 같습니다. 이 경우 답변에 공개해야합니다. 그렇지 않으면 스팸 일뿐입니다.
muru

죄송합니다. 제 의도는 아니 었습니다.보다 구체적으로 수정되었습니다.
fvidalmolina

1

정말 좋은 질문에 대한 헤드 업 :

내가 찾은 최고의 솔루션은 놀랍지 않게 tmux입니다.

놀라운 출력을 위해 tmux에서 Ctrl-B : setw synchronize-panes를 수행 할 수 있습니다. 이를 위해 모든 ssh 연결을 Tmux의 1 개 창에서 서로 다른 창에 열어야합니다.


0

여러 호스트에서 명령을 실행하기 위해 이와 같은 것이 작동합니까? 암호가없는 로그인을 위해 모든 호스트가 .ssh / config에 설정되어 있다고 가정합니다.

$ < hosts.txt xargs -I {} ssh {} command


0

/ etc / sxx / hosts 파일을 만듭니다

이렇게 채우십시오 :

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

모든 머신에서 ssh 키를 공유하십시오.

패키지에서 sxx를 설치하십시오.

https://github.com/ericcurtin/sxx/releases

그런 다음 다음과 같이 명령을 실행하십시오.

sxx username@grp_ips "whatever bash command"

출력은 어디에 기록됩니까? 0이 아닌 종료 상태는 어떻게 처리됩니까? 의견에 응답하지 마십시오. 더 명확하고 완전하게 답변을 편집 하십시오.
G-Man은

0

Paramiko http://www.paramiko.org/ 및 스레드 기반 병렬 처리 사용 https://docs.python.org/3/library/threading.html 아래 코드를 사용하면 각 서버에서 여러 명령을 병렬로 실행할 수 있습니다!

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.load_system_host_keys()
ssh.connect(hostname, port, username, password)
t = threading.Thread(target=tasks[index], args=(ssh, box_ip,))
t.start()

참고 : 각 서버에 대해 위의 지침을 반복하십시오.


0

"예상"이 필요하다고 생각합니다.
많은 사람들은 그것이 존재한다는 것을 알지 못합니다. 그것은 당신을 대신하여 질문과 가능한 답변을 할 tcl 기반 프로그램입니다. https://wiki.tcl-lang.org/page/Expect를 살펴보십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.