핵심 정리
# 이미지를 내려받아 컨테이너로 실행
docker run -d -p 8080:80 nginx:alpine
# 실행 중인 컨테이너 확인
docker ps
# 로그 확인
docker logs <container-id>구조 이해
어떤 Docker 입문 개념을 먼저 떠올리면 되나
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| 실행 환경을 통째로 재현하고 싶다 | 이미지 + 컨테이너 |
| VM과 컨테이너 차이가 궁금하다 | 커널 공유와 격리 방식 |
| 왜 이미지가 빠르게 배포되는지 알고 싶다 | 레이어 공유 |
| Docker만의 형식인지 궁금하다 | OCI 표준 |
컨테이너가 VM과 다른 점 — 커널을 공유하고 네임스페이스와 cgroup으로 격리한다
VM은 하이퍼바이저 위에 게스트 OS 전체를 올려 격리합니다. 컨테이너는 호스트 OS 커널을 공유하면서, 리눅스 네임스페이스(PID, 네트워크, 마운트 등)로 프로세스를 격리하고 cgroup으로 CPU·메모리 사용량을 제한합니다. 게스트 OS가 없으니 부팅 시간이 없고, 오버헤드가 훨씬 작습니다. 컨테이너는 결국 격리된 리눅스 프로세스입니다.
VM: 하드웨어 → 하이퍼바이저 → 게스트 OS → 앱
컨테이너: 하드웨어 → 호스트 OS 커널 → [네임스페이스+cgroup] → 앱이미지 레이어 구조와 Union FS — 레이어를 공유해 디스크와 전송량을 아낀다
Docker 이미지는 읽기 전용 레이어를 쌓아 만들어집니다. FROM node:22-alpine을 기반으로 의존성을 설치하고 소스를 복사하면 각 단계가 별도 레이어가 됩니다. 여러 이미지가 같은 베이스 레이어를 공유할 수 있어, 디스크 사용량과 네트워크 전송량이 줄어듭니다. 컨테이너 실행 시에는 읽기-쓰기 레이어가 그 위에 추가됩니다.
# 이미지 레이어 확인
docker history nginx:alpine
# 레이어 공유 확인 (같은 베이스를 쓰는 이미지는 레이어를 재사용)
docker imagesOCI 표준과 Docker의 관계 — Docker가 만든 규격이 업계 표준이 됐다
OCI(Open Container Initiative)는 컨테이너 이미지 포맷과 런타임을 표준화한 사양입니다. Docker가 초기에 정립한 컨테이너 개념이 OCI 표준으로 자리잡으면서, 이제는 containerd, Podman, Kubernetes 등 다양한 도구가 같은 이미지 포맷을 사용합니다. Docker로 빌드한 이미지는 OCI 호환 런타임 어디서나 실행할 수 있습니다.
# Docker 이미지를 OCI 포맷으로 저장
docker save nginx:alpine | gzip > nginx.tar.gz
# OCI 호환 런타임(예: nerdctl, podman)에서도 동작
podman run nginx:alpine컨테이너와 패키지 설치는 해결하는 문제가 다르다
컨테이너는 "호스트에 직접 설치하지 않고도 실행 환경 전체를 묶어 재현한다"는 데 강점이 있습니다. 패키지 매니저로 호스트에 직접 설치하는 방식은 빠를 수 있지만, 팀원 OS 차이와 라이브러리 버전 충돌을 그대로 안고 갑니다. 개발 환경을 통일하고 싶으면 컨테이너가 더 맞고, 호스트와 긴밀히 통합된 도구를 가볍게 쓰는 정도면 로컬 설치가 더 단순할 수 있습니다.
# 호스트에 직접 설치
brew install postgres
# 환경을 통째로 묶어 실행
docker run -d --name db -e POSTGRES_PASSWORD=dev postgres:17체크포인트
| 상황 | 적합한 선택 |
|---|---|
| 개발 환경 일관성이 필요할 때 | 컨테이너로 의존성 격리 |
| 팀원마다 OS/환경이 다를 때 | Docker 이미지로 환경 표준화 |
| 완전한 OS 격리가 필요할 때 | VM (컨테이너는 커널을 공유함) |
| 빠른 시작과 낮은 오버헤드 | 컨테이너 |
| Windows 앱을 리눅스에서 실행 | 불가 (커널 공유이므로 OS 호환 필요) |
주의할 점
컨테이너는 커널을 공유하므로 VM 수준의 완전한 격리가 아니다. 컨테이너 탈출 취약점이 발견되면 호스트 커널에 영향을 줄 수 있다. 신뢰할 수 없는 코드를 실행하는 환경이나 강한 보안 격리가 필요한 상황에서는 gVisor, Kata Containers 같은 샌드박스 런타임을 검토해야 한다.
docker run my-script
# 호스트에 curl, CA 인증서, 쉘 도구가 이미 있다는 가정으로 이미지 없이 실행하려는 경우컨테이너를 "그냥 프로세스 한 개만 따로 돌리는 것"으로 보면 필요한 런타임 파일과 라이브러리를 빼먹기 쉽습니다. 실제 배포용 컨테이너는 앱뿐 아니라 앱이 기대하는 실행 환경까지 이미지에 포함해야 합니다.
참고 링크
2 sources