ansible "Shared connection to xxx closed"

2개의 jenkins(젠키스) job(잡) 이 스케줄링에 의해 동시 실행될때
"Shared connection to 아이피 closed"

에러를 발생하며 ssh 접속이 되지 않는다.
각각의 젠킨스 잡은 ansible-playbook 을 수행하는데 2개 모두 같은 호스트를 대상으로 하고 있다.
ansible version : 2.2.1.0
user : ysoftman (가정)
jenkins host os : centos 7.2
target host name : ysoftman-file-server (10.10.10.10) (가정)
target host os : centos 7.2

다음과 같은 에러 메시지와 함께 접속 실패가 발생한다.
(ansible-playbook 실행시 -vvvv 옵션)
<10.10.10.10> SSH: EXEC ssh -vvv -o ControlMaster=auto -o ControlPersist=30m -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ysoftman -o ConnectTimeout=10 -o ControlPath=/ysoftman/.ansible/cp/ansible-ssh-%h-%p-%r -tt 10.10.10.10 '/bin/sh -c '"'"'/usr/bin/python /ysoftman/.ansible/tmp/ansible-tmp-1488621902.23-156878567418929/command.py; rm -rf "/ysoftman/.ansible/tmp/ansible-tmp-1488621902.23-156878567418929/" > /dev/null 2>&1 && sleep 0'"'"''
fatal: [ysoftman-file-server]: UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 27663\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 4\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Control master terminated unexpectedly\r\nShared connection to 10.10.10.10 closed.\r\n", 
    "unreachable": true
}

관련해서 구글링을 열심해 해봤는데

에서는 ControlPath 에 명시된 소켓 경로가 너무 길어서 발생한것으로 2.3 에서는 수정되었다고 한다. 그런데 위 트레이스 로그를 보면 경로명이 긴것도 아니고 동시실행될때만 접속실패가 발생하고 각각의 ansible 잡이 독립적으로 수행될때는 접속이 문제가 없어 이 원인은 아닌것으로 생각된다.


에 나와 같은 문제를 제기하고 있었고 다음과 같이 ansible-playbook 실행시 paramiko(파이썬으로 구현한 openssh) connection 를 사용하라고 한다.
ansible-playbook -i ./ysoftman ysoftman.yml -c paramiko -vvvv

또는


와 같이 playbook(.yml) 에 명시할 수 도 있다.
connection: paramiko

또는

http://docs.ansible.com/ansible/intro_configuration.html#transport
와 같이 ansible.cfg 에 명시한다.
(디폴트 smart 로 설정하면 play에  명시된 connection 을 따른다.)
transport = paramiko

문제가 되었던 서버에서는 paramiko 사용으로 해결되었다.
그런데 다른 서버의 콘솔에서 ansible-playbook 명령을 실행하면 접속 인증 실패가 발생한다. -c ssh 나 -c smart 를 옵션을 주어 실행하면 잘된다.

A 장비(젠킨스)에서 ansible 실행시 -c ssh | smart | paramiko 모두 동작
B 장비(로컬)에서 ansible 실행시 -c paramiko 인증 실패

원인은 B 장비의에서 -c paramiko 를 사용할 경우 .ssh/config 설정파일을 사용하지 않고 .ssh/id_rsa (기본 개인키)파일만 바라보고 있어 인증을 할 수 없는 것이다.
id_rsa 파일이 존재하지 않는다면 : No authentication methods available
id_rsa 파일이 존재하지만 대상 호스트에 공개키가 등록되지 않았다면 : Authentication failed
에러가 발생한다.
.ssh/config 에 명시된 private_key 파일을 id_rsa 로 복사하였더니, -c paramiko 로도 실행이 잘 된다.

[참고1]

에 보면 레드햇계열의 버전 6 이하에서는 openssh 버전이 오래된 ControlPersist 같은 ssh 성능 향상 옵션을 사용할 수 없어 ansible 이 ssh 접속에 paramiko 를 강제로 사용했다고 한다.

[참고2]
controlpersist 로 유지되는 커넥션 종료하기
ssh -o ControlPath=/Users/ysoftman/.ansible/cp/ansible-ssh-10.10.10.10-ysoftman -O exit ysoftman@10.10.10.10
또는 소켓 파일을 모두 삭제
rm -rf ~/.ansible/cp/

comments:

댓글 쓰기