부제: 컨테이너는 특별한 가상머신이 아니라, 커널이 격리·제한을 걸어 준 ‘그냥 프로세스’다
쿠버네티스를 공부하려고 앉을 때마다, 나는 늘 그 아래층에서 걸렸다.
머릿속에 있던 감각은 대략 이랬다.
- 도커는 뭔가 동일한 환경에서 연산 명령들을 모아둔 파일이고,
- 컨테이너는 그 도커를 관리하는 프레임워크 같은 것?
방향은 얼추 맞지만, 주어가 한 칸씩 밀려 있다. 이 밀림을 바로잡지 않으면
쿠버네티스로 올라갈 때 개념이 계속 어긋난다. 그래서 이 시리즈의 첫 편은
오케스트레이션 이야기 이전에, "컨테이너란 도대체 무엇인가" 부터
한 줄씩 못박고 간다.
왜 개념을 굳이 정리하고 넘어가나
솔직히 나는 개념 설명을 길게 늘어놓는 걸 즐기는 편이 아니다. 한번 파고들면
깊이가 끝도 없이 이어져서, 정작 "그래서 이걸 어떻게 쓰나" 에서 멀어지기
쉽기 때문이다. 그런데도 이 시리즈를 여는 이유는 하나다 — 각 프레임워크가
어떤 용도로 만들어졌는지, 그 컨셉과 방향을 알아야 그 결에 맞게 쓸 수
있어서다. 도구를 만든 사람의 의도와 어긋나게 쓰면, 되는 것도 힘겹게 되고
어딘가에서 반드시 삐걱댄다.
그래서 이 시리즈는 깊게 파지 않는다. 대신 두 가지만 붙잡고 빠르게
넘어간다 — 프레임워크 한 줄 정의(이게 뭘 하는가)와 큰 그림에서의
한 줄(전체에서 어디에 서 있는가). 딱 쓰기에 어긋나지 않을 만큼만 정리하고,
나머지 깊이는 필요할 때 그때 파는 걸로 남겨 둔다.
먼저 이 시리즈 전체를 지탱하는 두 정의를 한 줄씩 박아 두자. 자세한 풀이는
아래에서, 그리고 쿠버네티스 쪽은 다음 편부터 이어진다.
- 도커(Docker) = 컨테이너를 빌드·실행해 주는 도구(엔진). "동일한 환경을
레시피로 굳혀 어디서든 똑같이 실행"하게 해 준다.- 쿠버네티스(Kubernetes) = 그렇게 만든 컨테이너가 여러 대의 머신에 수십·수백
개로 늘어났을 때, "이 상태로 유지하라"는 선언만으로 배치·복구·확장·교체를
대신 맡아 주는 오케스트레이터(관리자). 컨테이너 하나를 다루는 게 도커라면,
컨테이너 무리를 다루는 게 쿠버네티스다.
이 글(A1)은 앞의 절반 — 도커와 컨테이너 — 를 확실히 굳히는 편이다.
한 줄 정의부터
| 용어 | 한 줄 정의 |
|---|---|
| Dockerfile | 이미지를 어떻게 만들지 적은 레시피(빌드 명령의 나열) |
| Image | 레시피를 실행해 얼려둔 파일시스템 + 메타데이터 스냅샷(정지 상태) |
| Container | 이미지를 실행한 격리된 프로세스(관리 대상) |
| Docker | 이미지를 빌드·실행해 주는 도구/엔진(컨테이너를 만들어 주는 쪽) |
내가 "명령을 모아둔 파일"이라고 감각한 것의 정체는 사실 Dockerfile이었다.
그리고 "컨테이너가 도커를 관리한다"는 완전히 뒤집혀 있었다 — 도커가
컨테이너를 만들고 관리하는 쪽이고, 컨테이너는 관리당하는 대상이다.

네 단어를 ‘흐름’으로 다시 읽기
한 방향으로 흐른다: Dockerfile → (build) → Image → (run) → Container.
- Dockerfile은 레시피다.
FROM node:20,COPY . .,RUN npm ci처럼
"이 이미지를 이렇게 만들어라"를 적은 텍스트 파일. 요리로 치면 조리법. - Image는 그 레시피를 실제로 실행해서 얼려 둔 스냅샷이다. 파일시스템
전체 + 실행 메타데이터(진입점·환경변수)를 담은 정지 상태의 결과물. 조리법대로
만들어 냉동해 둔 밀키트. - Container는 그 밀키트를 데워서 실제로 상에 올린 한 끼다. 이미지를
실행한 살아 있는 프로세스. 같은 이미지로 컨테이너를 100개 띄울 수 있다. - Docker는 이 build·run을 대신 눌러 주는 도구일 뿐이다. 그래서 도커가
아니어도 컨테이너는 존재한다 —containerd,Podman도 같은 일을 한다.
(쿠버네티스가 도커를 걷어내고 containerd로 옮겨 간 것도 이래서 가능했다.)
실제 콘솔로 확인 — 지금 이 블로그를 돌리는 도커에서
이 블로그(WordPress + MariaDB)도 컨테이너 위에서 돈다. 말로만 정리하면
또 밀리니, 진짜 콘솔을 그대로 캡처했다.

세 장면이 각각 한 줄 정의를 눈으로 확인시켜 준다.
docker imagesvsdocker ps— 같은wordpress:6.7-apache가 위에서는
992MB짜리 얼려둔 이미지로, 아래에서는 *실행 중인 프로세스(healthy)*로
나타난다. 이미지(정지) → 컨테이너(실행)의 그 한 칸이다./proc/1/ns— 컨테이너 내부 1번 프로세스가 가진 namespace 목록.
mnt/net/pid/ipc/uts의[번호]가 호스트와 달라서, 프로세스는 자기만의
독립된 세상에 있다고 착각한다. 이게 ‘격리’의 실체다.docker history— 이미지는 통짜가 아니라 레이어의 적층이다.
Dockerfile의 한 줄(RUN·COPY…)이 한 겹의 레이어가 되고, 무거운 줄
(WordPress 다운로드 83.8MB)이 이미지 크기를 좌우한다.
그래서 컨테이너의 정체는? — namespace + cgroup
여기까지 오면 마지막 오해 하나가 남는다. "컨테이너는 가벼운 가상머신
아닌가?" 아니다. 가상머신은 게스트 OS(커널)를 통째로 하나 더 띄우지만,
컨테이너는 호스트 커널을 그대로 공유하는 그냥 프로세스다. 다만 커널이
두 가지 장치로 그 프로세스를 ‘가둔다’.
| 커널 기능 | 하는 일 | 한 줄로 |
|---|---|---|
| namespace | 프로세스가 뭘 볼 수 있나를 격리 | PID·net·mount·ipc·uts·user 를 각자만의 것으로 |
| cgroup | 프로세스가 자원을 얼마나 쓰나를 제한·회계 | CPU·메모리·IO 에 상한과 계량기를 붙임 |
컨테이너 = namespace(격리) + cgroup(제한). 도커는 이 커널 기능을 손으로
다루기 번거로우니 명령 한 줄로 빚어 주는 도구일 뿐이다. 위 콘솔의
/proc/1/ns 가 namespace의 증거였고, cgroup은 나중에 쿠버네티스의
requests/limits 로 다시 등장한다(A5편에서 수미상관으로 잇는다).
주의 — 같은 단어, 다른 뜻: 여기서 말한 리눅스 namespace(컨테이너 격리
커널 기능)와, 다음 편에 나올 쿠버네티스 Namespace(클러스터를 논리적으로
나누는 폴더)는 이름만 같고 완전히 다른 것이다. 이 시리즈 내내 이 함정을
계속 짚어 줄 것이다.
정리 — 밀린 주어를 제자리로
- 명령을 모아둔 파일 = Dockerfile(레시피)
- 얼려둔 스냅샷 = Image
- 실행된 격리 프로세스 = Container(관리 대상)
- 그걸 만들어 주는 도구 = Docker(관리 주체)
- 컨테이너의 정체 = 커널이 namespace로 격리하고 cgroup으로 제한한 프로세스
한 칸씩 밀렸던 주어를 제자리에 놓고 나면, 다음 질문이 자연스럽다.
컨테이너 하나는 이렇게 이해했는데, 이 컨테이너가 수십·수백 개로 늘어나
여러 머신에 흩어지면 누가 관리하는가? 그 답이 쿠버네티스이고,
다음 편(A2)에서 Control Plane·Node·Pod·Namespace 로 클러스터 아키텍처를
같은 방식 — 개념마다 한 줄 정의 — 으로 풀어 간다.
참고
- Docker Docs — Docker overview, Images and layers
- Linux man-pages —
namespaces(7),cgroups(7) - 콘솔 캡처: 이 블로그를 구동 중인
wordpress:6.7-apache/mariadb:10.11컨테이너
답글 남기기