LabHub

도커 기초 · 실행과 수명주기 · 실습

생성·시작·종료와 종료코드

LabHub 에서 이어서 보기

이 실습은 진짜 VM 에서 돕니다

이 상자는 파드가 아니라 KubeVirt 가 띄운 가상머신입니다. 리눅스 커널이
따로 돌고 systemd 가 실제로 서비스를 관리하며, docker 는 흉내가 아니라
진짜 도커 엔진입니다. docker run 으로 띄운 컨테이너는 실제로 프로세스가
되고 docker execdocker logs 도 그대로 동작합니다.

예전에는 이 실습이 파드 안에서 돌았습니다. 커널 권한을 전부 내려놓은 상자라
컨테이너를 띄우는 단계가 막혀 있었고, 그래서 이미지 아카이브를 직접 풀어
보는 우회로 배웠습니다. 이제 우회가 필요 없습니다.

알아 둘 것이 둘 있습니다.

목표

컨테이너의 상태 전이를 손으로 만들어 보고, 종료코드 143 · 137 · 42 를 각각
의도적으로 재현해 그 의미를 몸으로 익힙니다.

왜 중요한가

운영에서 가장 자주 받는 신고는 "컨테이너가 죽었어요"입니다. 그런데 죽는
방식은 최소 세 가지이고, 각각 조치가 완전히 다릅니다. 앱이 스스로 끝냈으면
코드를 봐야 하고, SIGTERM 을 받고 끝냈으면 정상 배포이며, SIGKILL 로 죽었으면
앱 로그에는 아무것도 남지 않습니다. 종료코드는 이 셋을 구분하는 가장 싼
신호입니다. 128 을 넘는 값은 128 + 신호번호 라는 규칙 하나만 알면
143 = 128+15 = SIGTERM, 137 = 128+9 = SIGKILL 로 바로 읽힙니다.

단계

1. /root/dk2 를 만들고, alpine:3.20 으로 dk-life 라는 컨테이너를 생성만 합니다. 명령은 sleep 600 입니다.
2. dk-life 를 시작해 running 상태로 만듭니다.
3. alpine:3.20 으로 dk-trap 을 백그라운드 실행하되, SIGTERM 을 받으면 caught-term 을 출력하고 종료코드 143 으로 끝나게 합니다. 그런 다음 정상적으로 정지시킵니다.
4. alpine:3.20 으로 dk-notrap 을 백그라운드 실행하고(명령은 sleep 600), 유예 시간을 2초만 주고 정지시킵니다. 종료코드가 137 이 되어야 합니다.
5. alpine:3.20 으로 dk-fail 을 실행해 종료코드 42 로 끝나게 하고, 그 값을 /root/dk2/exit42.txt 에 숫자만 적습니다.
6. dk-restart 컨테이너를 재시작 정책 on-failure, 최대 3회 로 띄웁니다.
7. 컨테이너 안에서 프로세스 목록을 뽑아 /root/dk2/pid1.txt 로 저장합니다. PID 열이 함께 보여야 합니다.
이 실습 상자 자체가 컨테이너입니다. 여기서 ps -e -o pid,ppid,comm 을 돌리면 PID 1 이 이 컨테이너의 주 명령이라는 것과, 보이는 프로세스가 손에 꼽을 정도라는 것을 동시에 확인할 수 있습니다.
8. /root/dk2/lifecycle.mddk-trap, dk-notrap, dk-fail 세 컨테이너의 이름과 종료코드를 한 줄에 하나씩 적습니다.

참고

단계 8개

  1. 실행하지 않고 만들기만 하기
  2. 만들어 둔 컨테이너 시작하기
  3. SIGTERM 을 받아 정상 종료하기
  4. 핸들러가 없으면 무슨 일이 생기나
  5. 애플리케이션이 낸 종료코드
  6. 실패했을 때만 다시 띄우기
  7. 컨테이너 안의 프로세스 목록
  8. 종료코드 표 만들기