부제: Docker는 개발자 경험을, Podman은 리눅스 표준·보안·쿠버네티스 친화성을 앞세운다 — 같은 컨테이너를 다르게 바라보는 두 도구
앞선 A1편에서 "도커가 아니어도 컨테이너는 존재한다 — containerd, Podman도 같은 일을 한다"고 한 줄로 지나갔습니다. 그 문장을 쓰고 나서, 정작 저는 Podman이 Docker와 뭐가 다른지를 제대로 설명하지 못한다는 걸 깨달았습니다. 그래서 따로 찾아 정리했습니다.
결론부터 말하면, Podman은 흔히 "Docker의 대체재"로 소개되지만 실은 컨테이너를 바라보는 철학 자체가 조금 다릅니다.
- Docker = 개발자 경험(DX)과 생태계를 최우선으로 둔 컨테이너 도구.
- Podman = 리눅스 표준·보안·쿠버네티스 친화성을 최우선으로 둔 컨테이너 도구.
이미지 포맷(OCI)도 같고 CLI 사용감도 거의 같아서 "그놈이 그놈" 같지만, 그 아래에서 누가 컨테이너를 실행하느냐가 다릅니다. 이 한 축이 나머지 차이를 거의 다 만들어 냅니다.
한눈에 보는 비교
| 항목 | Docker | Podman |
|---|---|---|
| 실행 방식 | dockerd(데몬) 필요 | 데몬 없음(daemonless) |
| Rootless | 지원(추가 설정) | 기본 지원 |
| 기본 보안 모델 | root 중심 | 일반 사용자 실행 권장 |
| systemd 연동 | 제한적 | 매우 우수 |
| 쿠버네티스 연동 | 가능 | 매우 자연스러움(Pod 지원) |
| Pod 개념 | 없음 | 있음 |
| Compose | Docker Compose | podman compose |
| OCI 표준 / 이미지 호환 | 지원 / OCI | 지원 / OCI |
| CLI | docker |
podman(거의 동일) |
| 생태계 | 가장 큼 | Red Hat 중심 |
표만 보면 차이가 흩어져 보이지만, 실제로는 세 개의 축 — daemonless, rootless, Pod — 으로 묶입니다.
그 전에 — containerd는 왜 이 비교에 안 끼나
여기서 이름 하나를 짚고 가야 합니다. Docker·Podman과 자주 같이 등장하는 containerd입니다. 결론부터 말하면, 셋은 같은 줄에 서 있지 않습니다. Docker와 Podman은 사람이 직접 명령을 내리는 상위 도구이고, containerd는 그 아래에서 실제로 컨테이너를 띄우고 관리하는 런타임 엔진입니다.
| 기술 | 한 줄 정의 | 서 있는 층 |
|---|---|---|
| Docker | 개발자가 가장 많이 쓰는 컨테이너 플랫폼(빌드·실행·배포를 한 도구로 감쌈) | 상위 플랫폼 |
| Podman | Docker와 거의 같은 CLI를 주면서 데몬이 없는(daemonless) 컨테이너 엔진 | 상위 엔진 |
| containerd | 실제 컨테이너를 실행·관리하는 런타임 엔진(상위 도구가 내부에서 호출) | 하위 런타임 |
그림으로 겹쳐 보면 이렇습니다.
[사람이 쓰는 도구] docker CLI podman CLI
│ │
▼ ▼
[관리 계층] dockerd conmon
│ │
▼ ▼
[런타임 관리 엔진] containerd (없음)
│ │
▼ ▼
[OCI 런타임] runc crun / runc
핵심은 두 가지입니다.
- Docker는 containerd를 품고 있습니다.
docker run을 누르면 dockerd가 그 아래 containerd를 호출해서 컨테이너를 띄웁니다. 그러니 "Docker vs containerd"는 애초에 성립하지 않는 비교입니다 — 하나가 다른 하나를 부품으로 씁니다. - Podman은 containerd를 거치지 않습니다. 데몬도 containerd도 없이
conmon+crun/runc로 직접 띄웁니다. Podman에게 containerd는 "안 쓰는 다른 길"입니다.
그래서 실제로 층이 겹쳐 경쟁하는 건 Docker ↔ Podman(사람이 쓰는 상위 도구)과, 그보다 아래에서 containerd ↔ CRI-O(런타임 엔진)입니다. Docker와 containerd는 위아래로 붙어 있는 사이지 라이벌이 아닙니다.
쿠버네티스가 "도커를 버렸다"의 실체: 쿠버네티스는 예전에 dockershim이라는 어댑터로 dockerd를 거쳐 컨테이너를 띄웠는데, 이 어댑터를 걷어내고 containerd를 CRI로 직접 호출하도록 바꿨습니다. 즉 버린 건 상위 도구 Docker이고, 그 안에 들어 있던 런타임 containerd는 그대로 남아 일합니다. 이미지(OCI)는 손댈 필요가 없었습니다.
이 층 구분을 손에 쥐고 나면, 아래 세 축의 비교는 자연스럽게 "상위 도구 Docker와 Podman이 어떻게 다른가" 로 좁혀집니다.
축 1. 데몬(dockerd)이 없다
Docker는 CLI가 명령을 내리면, 그것을 항상 떠 있는 데몬 dockerd가 받아 실행합니다.
docker CLI
│
▼
dockerd ← 항상 떠 있는 데몬(root)
│
▼
containerd
│
▼
runc ← 실제로 컨테이너를 띄우는 OCI 런타임
Podman은 이 데몬을 걷어냈습니다. CLI가 컨테이너를 직접 띄웁니다.
podman CLI
│
▼
conmon ← 컨테이너 하나를 감시하는 가벼운 프로세스
│
▼
crun / runc ← 실제로 컨테이너를 띄우는 OCI 런타임
dockerd가 사라지면서 따라오는 것들:
- 메모리 상주 비용이 없습니다. 컨테이너를 안 쓰는 동안 떠 있는 데몬이 없습니다.
- 단일 장애점이 줍니다. 데몬 하나가 죽어서 그 아래 컨테이너 전체가 흔들리는 구도가 아닙니다. 컨테이너는 각자 자기
conmon아래에서 돕니다. - 부모 프로세스가 명확합니다.
bash → podman → container로 프로세스 계보가 이어져서, 리눅스의 프로세스 트리 관점과 결이 맞습니다.
축 2. rootless가 기본
Docker는 오랫동안 sudo docker run 형태가 사실상 표준이었습니다(현재는 rootless 모드를 지원하지만 별도 설정이 필요합니다). Podman은 그냥 podman run 이면 됩니다.
호스트 사용자 UID 1000
│ (user namespace 매핑)
▼
컨테이너 UID 0(root처럼 보임)
│
▼
실제로는 여전히 UID 1000의 권한
컨테이너 안에서는 root처럼 보여도, 호스트에서는 여전히 일반 사용자 권한입니다. 그래서:
- root 권한을 최소화할 수 있고,
- 컨테이너 탈출(escape) 공격이 성공해도 피해 범위가 일반 사용자 선에서 막힙니다.
- SELinux/AppArmor 같은 리눅스 보안 모듈과의 궁합도 좋습니다. 특히 Red Hat 계열에서는 SELinux + Podman 조합이 사실상 표준으로 쓰입니다.
축 3. Pod — 쿠버네티스와 같은 언어
Docker의 실행 단위는 컨테이너 하나입니다. Podman은 이름 그대로 Pod라는 단위를 지원합니다.
Pod
├── nginx
├── redis
└── sidecar
하나의 Pod 안에 든 컨테이너들은 네트워크(localhost)·IPC를 공유합니다. 이 구조가 바로 쿠버네티스의 Pod와 같습니다. 그래서 Podman은 쿠버네티스와 언어가 거의 겹칩니다.
podman kube generate → deployment.yaml 생성
podman kube play → YAML을 그대로 로컬에서 실행
로컬에서 Podman으로 만든 구성을 그대로 YAML로 뽑아 클러스터에 올리거나, 반대로 쿠버네티스 매니페스트를 로컬에서 돌려 볼 수 있습니다. 쿠버네티스를 배우기 위한 로컬 환경으로도 자연스럽습니다. (쿠버네티스의 Pod·Service 개념은 쿠버네티스 개념 시리즈에서 따로 다뤘습니다.)
여기에 systemd 궁합이 하나 더 붙습니다. podman generate systemd 로 컨테이너를 .service 유닛으로 뽑아내면(최신 Podman은 Quadlet 방식을 권장), systemctl enable 한 줄로 컨테이너를 시스템 서비스처럼 관리할 수 있습니다. 리눅스 서버에서는 꽤 큰 장점입니다.
그래도 Docker가 나은 부분
방향이 다를 뿐, Docker가 여전히 앞서는 지점도 분명합니다.
- 압도적인 생태계. 문서·예제·Stack Overflow·GitHub의 거의 모든 자료가 Docker 기준입니다. 막혔을 때 검색으로 풀리는 속도가 다릅니다.
- Docker Desktop. Windows·macOS 사용자에게는 설치와 GUI 관리가 편합니다.
- Compose 자료.
docker compose관련 예제가 압도적으로 많습니다. - CI/CD 기본값. GitHub Actions·GitLab·Jenkins 예제가 대부분 Docker입니다.
- 클라우드 도입 사례. AWS·Azure·GCP 문서의 예제도 Docker 기반이 훨씬 많습니다.
즉 "새로 배우는 비용"과 "막혔을 때 빠져나오는 비용"은 아직 Docker 쪽이 쌉니다.
언제 Podman을 고르면 좋을까
정리해 보면, 아래에 해당할수록 Podman이 결에 맞습니다.
- 리눅스 서버에서 상주 데몬 없이 컨테이너를 돌리고 싶을 때
- rootless로 보안을 한 겹 더 올리고 싶을 때
- K3s·OpenShift 등 쿠버네티스를 함께 쓸 계획일 때
- systemd 기반으로 컨테이너를 서비스처럼 관리하고 싶을 때
- Red Hat·Fedora·RHEL 계열 OS를 쓸 때
반대로 개발 초기 속도, 팀 온보딩, 풍부한 예제가 더 급하다면 Docker를 그대로 쓰는 게 합리적입니다. 둘 다 OCI 이미지를 공유하니, 이미지를 새로 만들 필요 없이 나중에 갈아탈 수도 있습니다.
곁다리 — Dockerd와 Linkerd는 무슨 관계일까?
찾다 보니 이름이 비슷해서 문득 궁금해졌습니다. dockerd와 Linkerd는 관계가 있을까요? 결론은 이름만 닮았을 뿐 완전히 다른 계층(layer)의 기술이었습니다.
- dockerd = 컨테이너를 실행하는 프로그램(도커 데몬).
- Linkerd = 이미 실행 중인 서비스들 사이의 네트워크를 관리하는 프로그램(서비스 메시).
한쪽은 컨테이너를 띄우는 아래층, 다른 쪽은 그렇게 뜬 서비스들이 서로 통신하는 위층을 다룹니다. Linkerd가 정확히 어디에 서 있는지는 관측 스택을 한 줄씩 정의한 글에서 서비스 메시로 따로 짚어 두었습니다.
정리
- Docker와 Podman의 갈림길은 "누가 컨테이너를 실행하는가" 한 줄입니다.
- Docker = dockerd 데몬이 실행. 개발자 경험·생태계가 강점.
- Podman = 데몬 없이 CLI가 직접 실행. daemonless·rootless·Pod 세 축으로 리눅스 표준·보안·쿠버네티스 친화성이 강점.
- containerd는 이 둘의 경쟁자가 아니라 아래층입니다. Docker는 그것을 품고 호출하고, Podman은 거치지 않으며, 쿠버네티스는 그것을 직접 부릅니다.
- 이미지(OCI)는 셋이 모두 공유하므로, 철학의 차이일 뿐 이사 비용은 크지 않습니다.
- 그리고
dockerd와Linkerd는 이름만 닮은 남남입니다.
답글 남기기