screen을 이용한 데몬 구성
2019년 6월 26일 초안 작성
서론
데몬은 사용자가 직접 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말한다. (위키피디어) 그러나 데몬의 갯수가 늘어나면 어떤 데몬이 백그라운드로 떠 있는지 구분이 어렵고, 다른 유저로 실행한 경우 모든 사용자의 프로세스를 뒤져서 찾아야 하는 어려움이 있다.
$ ps auxf
...
root 1 ... 0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2011 ... 0:00 /usr/lib/systemd/systemd-journald
root 2176 ... 0:00 /usr/sbin/lvmetad -f
root 2199 ... 0:00 /usr/lib/systemd/systemd-udevd
root 3296 ... 0:00 /sbin/auditd
libstor+ 3352 ... 0:00 /usr/bin/lsmd -d
root 3374 ... 0:00 /usr/lib/systemd/systemd-logind
dbus 3375 ... 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root 3431 ... 0:01 /usr/sbin/irqbalance --foreground --hintpolicy=subset
root 3450 ... 0:01 /sbin/rngd -f
chrony 3586 ... 0:00 /usr/sbin/chronyd
rpc 3607 ... 0:00 /sbin/rpcbind -w
root 3618 ... 0:00 /usr/sbin/gssproxy -D
root 4221 ... 0:00 /usr/libexec/postfix/master -w
postfix 4241 ... 0:00 \_ qmgr -l -t unix -u
postfix 18690 ... 0:00 \_ pickup -l -t unix -u
root 4292 ... 0:01 /usr/sbin/rsyslogd -n
root 4294 ... 0:00 /usr/bin/amazon-ssm-agent
root 4373 ... 0:00 /usr/sbin/crond -n
root 4449 ... 0:00 /usr/sbin/atd -f
root 4452 ... 0:41 /usr/bin/dockerd --default-ulimit nofile=1024:4096
root 4664 ... 1:18 \_ docker-containerd --config /var/run/docker/containerd/containerd.toml
root 4501 ... 0:00 /sbin/agetty --noclear tty1 linux
root 4503 ... 0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220
root 4550 ... 0:00 /usr/sbin/sshd -D
root 19443 ... 0:00 \_ sshd: ec2-user [priv]
ec2-user 19449 ... 0:00 \_ sshd: ec2-user@pts/0
ec2-user 19450 ... 0:00 \_ -bash
ec2-user 19479 ... 0:00 \_ ps auxf
polkitd 5384 ... 0:00 /usr/lib/polkit-1/polkitd --no-debug
이처럼 많은 프로세스가 떠 있는 상태에서는 어떤 데몬이 어떤 서비스 용도인지 쉽게 알아차리기 어렵다.
구현 방법
Docker
최근에 많은 서비스들이 docker로 구현되면서, 서비스 데몬을 모두 이미지로 만들어 관리하면 host 프로세스와 명확히 분리할 수 있다. 그러나 docker로 만든 서비스가 아닌 경우나 docker 이미지 내에서는 마찬가지로 데몬 관리가 어렵다.
Terminal Multiplexer
docker 훨씬 이전 부터 terminal multiplexer를 이용한 세션 관리는 터미널의 핵심 부가 기능 중 하나였다. 단순히 foreground 프로세스를 background로 구동하는 nohup
과 달리 screen은 별도의 세션에 foreground 명령을 실행하고 관리할 수 있어 foreground의 잇점을 최대한 살릴 수 있다.
screen
screen은 대표적인 terminal multiplexer로 벌써 30년이 넘는 역사를 자랑한다. 하지만 stable 릴리즈에서 거의 개선이 없어 최근에는 사용자 터미널 용도는 tmux로 많이 갈아탔다.
tmux
tmux가 인기를 끌면서 대세가 됐지만 tmux에는 불필요한 기능이 너무 많아서 굳이 데몬 구동 용도로 필요하진 않다. 하지만 개인 업무용으로는 매우 유용하다.
$ tmux new # 세션 실행
$ CTRL+B,C # 새 윈도우 실행
$ CTRL+B,D # 세션 detach
$ tmux attach # 기존 세션 참여
간혹 tmux 자체가 강제 종료되어 기존 세션을 모두 날려버리는 경우가 있다.
screen
상태
우리가 활용하려는 foreground 프로세스를 위한 terminal multiplexer로 screen은 최적의 기능을 제공한다. screen으로 실행한 프로세스는 아래와 같이 ps
에서도 hierarchy 구조로 보여서 구분이 쉽다.
$ ps uxf
... RSS TTY STAT START TIME COMMAND
... 4552 ? S 04:57 0:00 sshd: ec2-user@pts/0
... 4268 pts/0 Ss 04:57 0:00 \_ -bash
... 4176 pts/0 R+ 04:57 0:00 \_ ps uxf
... 3256 ? Ss Jun17 0:00 SCREEN -S flask
... 4128 pts/3 Ss Jun17 0:00 \_ /bin/bash
... 2904 pts/3 S+ Jun21 0:00 \_ /bin/bash ./run_flask.sh
... 323776 pts/3 Sl+ Jun21 0:31 \_ /home/ec2-user/anaconda3/envs/mt/bin/python /home/ec2-user/anaconda3/envs/mt/bin/flask run --host=0.0.0.0
... 2940 ? Ss Jun17 0:00 SCREEN -S tf-serving
... 4256 pts/1 Ss Jun17 0:00 \_ /bin/bash
... 2940 pts/1 S+ Jun19 0:00 \_ /bin/bash ./run_docker.sh
... 26232 pts/1 Sl+ Jun19 0:15 \_ docker run --runtime=nvidia -it --rm -p 8500:8500 -p 8501:8501 --mount type=bind,source=/home/ec2-user/models
뿐만 아니라 세션 이름을 잘 정해두면 screen -ls
에서 훨씬 더 명확하게 실행 상황을 파악할 수 있다.
$ screen -ls
There are screens on:
8557.flask (Detached)
19446.tf-serving (Detached)
2 Sockets in /var/run/screen/S-ec2-user.
옵션
몇 가지 실행 옵션은 다음과 같다.
-d
: 새션 실행 후 바로 detach하여 빠져 나간다.-m
: 세션에서 실행될 명령을 바로 지정할 수 있다.-S
: 세션 이름을 정한다.
모두 합쳐서 다음과 같이 명령을 내릴 수 있다.
$ screen -dmS flask bash -c './run_flask.sh; exec bash'
-dmS
는 “Start as daemon: Screen session in detached mode.”로, 이 경우 flask 라는 세션 이름으로, ./run_flask.sh
를 실행, 바로 detach 한다. 만약 에러가 나거나 강제로 실행이 종료되어도 exec bash
로 세션은 다시 bash 프롬프트로 떨어진다. 이때 로그를 확인하거나 디버깅 작업을 할 수 있다.
명령
접속한 세션은 (Attached)
로 표시된다. CTRL+D
는 세션을 종료하면서 빠져 나오며, 세션을 그대로 유지하고 싶다면 CTRL+A,D
를 차례로 입력하면 유지한채로 detach 할 수 있다.