도커 기초 · 이미지와 컨테이너 · 이론
이미지는 무엇이고 컨테이너는 무엇인가
한 줄 요약
이미지는 읽기 전용 레이어를 쌓아 만든 파일 트리이고, 컨테이너는 그 위에
쓰기 레이어 하나를 얹은 뒤 실행 중인 평범한 리눅스 프로세스입니다.
왜 이게 필요했나
"컨테이너는 가벼운 VM"이라는 설명이 오래 돌아다녔지만, 이 문장은 거의
모든 실무 문제에서 틀린 예측을 내놓습니다. 호스트에서 ps 를 쳐 보면
컨테이너 안의 nginx 가 그대로 보입니다.
48213 root nginx48261 systemd+ nginx같은 프로세스를 컨테이너 안에서 보면 1 nginx, 29 nginx 로 보입니다.
프로세스가 두 벌 있는 게 아니라 **같은 프로세스를 다른 네임스페이스에서
본 것**입니다. 커널 버전을 확인해 보면 더 분명해집니다. 호스트도,
alpine 컨테이너도, ubuntu 컨테이너도 전부 같은 커널을 보고합니다.
이미지가 제공하는 것은 커널이 아니라 사용자 공간의 파일 트리뿐입니다.
어떻게 동작하나
레이어는 유니온 파일시스템(overlayfs)으로 겹쳐집니다.
merged <- 컨테이너가 보는 뷰 ↑ upperdir (쓰기 가능, 컨테이너 레이어) ↑ lowerdir (읽기 전용, 이미지 레이어들이 겹겹이)- 읽기: 위에서부터 찾아 내려가고, 가장 위의 파일이 이깁니다.
- 쓰기: 아래 레이어의 파일을 고치면 위로 복사한 뒤(copy-up) 고칩니다.
- 삭제: 실제로 지우지 않고 위 레이어에 화이트아웃 표식을 남깁니다.
모든 레이어는 내용의 SHA-256 해시로 이름이 붙습니다. 내용이 같으면 이름도
같기 때문에 중복 저장이 없고, 해시만 비교하면 무결성이 검증됩니다. 이미지
ID 가 sha256:... 인 것도 같은 이유입니다.
현장에서 만나는 모습
같은 베이스를 쓰는 컨테이너 100개가 lowerdir 을 통째로 공유하기 때문에
컨테이너 생성이 빠르고 디스크가 절약됩니다. 반대로 copy-up 비용 때문에
데이터베이스 파일처럼 큰 쓰기는 반드시 볼륨으로 빼야 합니다.
또 하나. docker save 와 docker export 를 헷갈리면 하루가 날아갑니다.
save 는 레이어·태그·히스토리를 포함한 이미지를 내보내고, export 는
컨테이너의 파일시스템 한 장만 내보냅니다. export 한 것을 import 하면
ENTRYPOINT 도 ENV 도 전부 사라진 채로 살아납니다.
다음 실습에서 할 것
이미지 목록을 직접 훑고, 컨테이너를 하나 띄워 로그를 확인하고, 태그가
새 이미지를 만들지 않는다는 것을 이미지 ID 로 증명합니다.