상황
회사 특정 프로그램의 배포 방식이 최첨단 수동인게 하나 있었다.
자바 프로그램이고, 로컬에서 fatjar를 만들어 scp로 배포하고 미리 scp로 넣어둔 쉘 스크립트를 실행해서 서버를 구동하는 방식이었다.
배포를 좀 더 쉽게 하기 위해 ansible로 배포스크립트를 만들고자 했다.
큰 흐름은 빌드 > 소스 배포 > 프로세스 스탑 > 프로세스 실행 으로 비교적 간단한 순서 였다.
프로세스 스탑, 실행 모두 쉘 스크립트를 서버에 넣어두고 실행만 하면됐다.
그런데 스탑은 잘 되는데 실행이 안 된다. 왜?
문제의 스크립트
#!/bin/bash
JVM_OPT=블라블라
export JVM_OPT
java $JVM_OPT -jar app.jar >> {{출력파일}} 2>&1 &
보기에는 별 문제가 없어보인다.
실제로 ssh 접속하여 서버에 들어있는 이 스크립트를 실행하면 문제없이 프로세스가 잘 구동된다.
그런데 왜 앤서블로 구동하면 아무 에러도 없이 프로세스가 구동되지 않을까?
원인은 SIGHUP
여기서부터는 뇌피셜이 좀 섞인다. (얕은 지식때문에..)
기본적으로 앤서블의 태스크는 각각의 ssh 커넥션을 만들어서 실행된다.
그런데 이 커넥션이 끊어지면 태스크가 실행한 프로세스와의 연결이 끊어지면서 SIGHUP가 발생한다 (그런것 같다)
관련 구글링: https://stackoverflow.com/questions/27837917/ansible-how-to-suppress-sighup
아뿔사 싶었다. 스크립트의 java 커맨드 앞에 nohup 명령어를 붙여주니 그제서야 잘 동작한다.
하....... 내 반나절
Daemon의 권장 사항
이 뿐만 아니라 완벽한? 데몬(백그라운드) 프로세스가 되기 위해서는 표준입력, 표준출력, 표준에러 스트림 도 제어할 필요가 있다.
https://ko.wikipedia.org/wiki/데몬_(컴퓨팅)
위키 문서에 따르면 '/dev/null을 stdin, stdout, stderr로 설정한다.' 라는 문항이 있다.
이를 통해 표준 입출력, 표준에러 를 끊어서 연결된 터미널 디바이스가 없도록 할 수 있다.
수정된 스크립트
#!/bin/bash
JVM_OPT=블라블라
export JVM_OPT
nohup java $JVM_OPT -jar app.jar >> {{출력파일}} 2>&1 < /dev/null &
'배포 & 자동화 > Ansible' 카테고리의 다른 글
Ansible이란? (1) | 2019.06.24 |
---|