-
Notifications
You must be signed in to change notification settings - Fork 3
effective docker
debian:jessie 버전의 Dockerfile을 사용하여 docker 컨테이너를 생성하면 ubuntu에서와 다르게 systemd 또는 sysvinit과 같은 init system이나 cron, syslog, SSH 등을 사용하지 않고 단일 프로세스로 실행된다. 그래서 redis 또는 tomcat official 버전의 컨테이너를 실행시킨 후 ps 명령어를 통해 확인해보면 CMD를 통해 실행된 프로세스의 PID가 1로 되어 있는 것을 볼 수 있다. 이 PID 1로 실행되는 프로세스에는 init system과 같은 특별한 규칙과 책임이 있다.
host와 docker container는 동일한 커널을 공유하기 때문에 host에서 ps 명령을 수행해보면 Dockerfile의 CMD 명령으로 인해 실행된 docker container안의 프로세스도 확인할 수 있다. 해당 프로세스는 host의 PID 순서를 따라 부여된 ID이고 PPID는 해당 프로세스의 docker container의 PID가 된다. 해당 프로세스는 docker conatainer 안에서 다시 매핑되어 1로 시작한다.
redis나 tomcat의 official 이미지를 사용해보면 CMD로 수행되는 시작 COMMAND에 해당하는 프로세스가 PID 1을 가지고 실행된다. PID가 1인 경우 init 프로세스를 의미하는데 이는 모든 프로세스의 부모 프로세스가 된다. 일반적인 ubuntu 서버의 pstree를 보면 systemd가 최상위 프로세스가 되어 모든 프로세스가 이 프로세스의 하위 프로세스가 되는 구조를 가지게 되는데 docker 환경에서는 조금 다르게 동작했다. 예를 들어 redis의 경우 redis-server가 PID 1 로 실행되지만 이 후 bash로 접속하게 되면 PPID가 1이 아닌 0이 되고 bash에서 생성된 프로세스의 부모는 bash가 된다. docker stop 명령어는 docker container의 init 프로세스에 SIGTERM 신호를 보내는 것이고, SIGTERM 신호를 받은 init 프로세스는 모든 서비스들을 중지 시키도록 되어있다. (docker logs 명령도 init 프로세스에 attach한 정보를 보여주는 듯)
- redis docker container 상의 pstree
UID PID PPID C STIME TTY TIME CMD
redis 1 0 0 01:50 ? 00:00:00 redis-server *:6379
redis-server---2*[{redis-server}]
- ubuntu 서버 상의 pstree
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 2016 ? 00:00:06 /sbin/init splash
systemd─┬─accounts-daemon─┬─{gdbus}
│ └─{gmain}
├─agetty
├─cron
├─dbus-daemon
├─irqbalance
├─java───53*[{java}]
├─rsyslogd─┬─{in:imklog}
│ ├─{in:imuxsock}
│ └─{rs:main Q:Reg}
├─screen───bash
...
- test를 위해 파일 생성 후 bash위에 tail 명령을 통해 프로세스를 실행
$ echo 'test' > test
$ bash -c set -e && tail -f test & - ps 명령으로 확인해보면 parent인 bash는 PID가 138이고 tail은 하위 프로세스 이므로 PPID가 138인 것을 볼 수 있다.
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 138 128 0 05:48 ? 00:00:00 bash
root 140 138 0 05:48 ? 00:00:00 tail -f test
root 141 128 0 05:48 ? 00:00:00 ps -ef - 여기서 parent인 bash를 kill 명령으로 제거.
$ kill -9 138
- ps 명령으로 다시 확인해보면 tail의 PPID가 0으로 변경되어 zombie 프로세스가 된 것을 볼 수 있다.
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 140 0 0 05:48 ? 00:00:00 tail -f test
root 142 128 0 05:48 ? 00:00:00 ps -ef
[2]- Killed bash -c set -e && tail -f test
종료 되는 프로세스가 parent process에게 보고 한후 종료 하려하지만 그 parent 프로세스는 child 프로세스를 기다려주지 않을 경우 이 프로세스는 defunct로 표시된다.
- tomcat docker 컨테이너 구동
- child 프로세스로 bash를 구동한 후 tail 명령 실행
$ bash -c set -e && tail -f catalina.2017-01-06.log- 테스트 전 프로세스 확인
UID PID PPID C STIME TTY TIME CMD
root 1 0 1 01:34 ? 00:00:02 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apa
root 47 0 0 01:37 ? 00:00:00 bash
root 49 47 0 01:37 ? 00:00:00 tail -f catalina.2017-01-06.log
- tail 프로세스의 parent가 되는 bash 프로세스 kill
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 01:34 ? 00:00:02 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apa
root 47 0 0 01:37 ? 00:00:00 [bash] <defunct>
root 49 0 0 01:37 ? 00:00:00 tail -f catalina.2017-01-06.log
위와 같이 kill 했던 bash가 defunct 상태가 되었다. 그런데 이 bash의 parent를 보면 kill 되기 전 parent의 PID가 0으로 되어 있었다. 이 후 kill을 하고 나면 tail 프로세스가 좀비 프로세스가 되어 parent가 0이 된다. 이 tail 프로세스 마저 kill 시키고 나면 defunct 되었던 bash 프로세스도 종료되고 tail 프로세스도 종료된다.
- 설치된 모든 패키지에 대한 정보가
/usr/share/doc에 들어있음.