Docker 구조 정리 - CLI, Daemon, Container의 실제 형태 기반 이해

hoho·2025년 6월 17일

아래는 Docker CLI, dockerd, container의 개념을 실제 형태 기반으로 벨로그 문서 형식에 맞춰 정리한 예시입니다.

Docker는 "도커 명령어 → 도커 데몬 → 컨테이너" 순으로 동작하는 구조입니다. 이 문서에서는 비유 없이 실제 파일 위치, 프로세스 흐름, 내부 구성 기준으로 도커의 핵심 구성요소를 정리합니다.

1. Docker CLI (docker)

요약

  • /usr/bin/docker 같은 경로에 위치한 Go로 작성된 바이너리 실행파일
  • 사용자가 터미널에 입력하는 모든 docker 명령어의 진입점

예시

docker build -t myimage .
docker run -it myimage
docker ps
docker push myrepo/myimage

-> 이 명령어들은 모두 Docker CLI를 통해 실행되는 것입니다.

동작 방식

  • 터미널에 명령을 입력함:
docker build -t myimage .
  1. /usr/bin/docker라는 CLI 실행 파일이 실행됨
    → 내부에는 수많은 서브 명령어 처리 코드가 들어 있음

  2. CLI는 입력된 명령어를 해석(파싱)함
    → 이 경우엔 "build", 옵션 "-t", 태그 이름, 현재 디렉토리 . 등을 해석함

  3. 이 내용을 Docker Daemon(dockerd)에게 요청
    → 내부적으로는 HTTP 기반의 REST API 요청을 /var/run/docker.sock에 보냄

  4. Docker Daemon이 이를 받아서 이미지 빌드를 수행하고, 결과를 CLI에 반환

  5. CLI가 결과를 사용자에게 보여줌

예시

$ which docker
/usr/bin/docker

$ docker run -it ubuntu
# 내부적으로 dockerd 에 POST /containers/create + /start 요청

참고: Docker CLI는 결국 REST API 클라이언트

  • Docker CLI가 요청하는 내용은 다음처럼 실제 HTTP 요청으로 볼 수 있습니다:
  • 그래서 docker CLI 없이도, REST API를 직접 호출하면 도커 데몬과 통신할 수 있습니다. (복잡해서 실무에선 잘 안 씀)
POST /build HTTP/1.1
Host: docker
Content-Type: application/x-tar
...

2. Docker Daemon (dockerd)

요약

  • /usr/bin/dockerd 같은 경로에 위치한, Go로 작성된 백그라운드 실행 데몬
  • 컨테이너 생성, 이미지 빌드, 네트워크 설정 등 모든 실행 로직을 담당
  • 내부적으로 여러 모듈이 있음 (이미지 관리, 볼륨, 네트워크, 로그, API 등)
$ ps aux | grep dockerd
root     1234  0.5  2.3 /usr/bin/dockerd --host=unix:///var/run/docker.sock

-> 이처럼 dockerd는 백그라운드에서 실행 중인 프로세스로 떠 있습니다.

내부 구성 요약(구조적으로는 이렇게 생김)

[dockerd 실행]
   ├── REST API 서버 (/containers/json 등)
   ├── 이미지 관리자
   ├── 컨테이너 관리자
   ├── 네트워크 관리자 (bridge, overlay 등)
   ├── 볼륨 관리자
   └── 플러그인 및 이벤트 핸들러

동작 구조

docker CLI (REST 요청)
       ↓
[ /usr/bin/dockerd ]
       ↓
containerd → runc → 실제 컨테이너 생성

관련 경로

  • 설정: /etc/docker/daemon.json
  • 시스템 서비스: /lib/systemd/system/docker.service
  • 로그 확인:
$ journalctl -u docker.service

docker.sock은 뭐냐?

  • dockerd는 명령을 REST API 형태로 받습니다.
  • CLI와 Daemon은 /var/run/docker.sock 이라는 파일(Unix 소켓)을 통해 통신합니다.
# 예시
curl --unix-socket /var/run/docker.sock http://localhost/containers/json

→ 위 명령은 CLI 없이 Daemon에 직접 "컨테이너 리스트 주세요"라고 요청하는 것입니다.

3. Container (컨테이너)

요약

  • 컨테이너는 Linux 커널 위에서 namespace와 cgroup으로 격리된 프로세스입니다
  • 실행 시 실제로는 하나의 리눅스 프로세스이며, 독립된 환경처럼 동작

동작 방식

  • dockerdcontainerd → runc를 호출해 컨테이너 실행
  • 컨테이너는 overlayfs로 구성된 파일시스템 위에서 동작
  • 호스트의 리소스를 공유하지만, namespace를 통해 격리

실제 위치 예시

/var/lib/docker/
├── containers/
│   └── <container-id>/
│       ├── config.v2.json
│       ├── hostconfig.json
│       └── container.log
├── overlay2/
│   └── <layer-id>/
│       └── merged/   ← 컨테이너 내부 루트 파일시스템

실행 확인

$ docker run -it ubuntu
$ ps -ef | grep ubuntu
# 실제로는 sleep, bash 등의 프로세스 하나가 namespace 안에서 격리되어 동작

$ lsns
# PID namespace 등 확인 가능

전체 흐름 요약

[사용자] 터미널에 입력
  └─▶ docker run ubuntu
        └─▶ /usr/bin/docker (CLI)
              └─▶ dockerd (Daemon, 백그라운드)
                    └─▶ containerd + runc
                          └─▶ namespace + cgroup으로 격리된 프로세스 (컨테이너)

관련 기술

기술설명
namespace프로세스, 네트워크, 파일시스템 등을 격리
cgroup자원(CPU, memory 등) 사용 제한 및 관리
overlayfs여러 계층을 합쳐 컨테이너 파일시스템 구성
containerd, runccontainer 생성/실행을 위한 low-level 런타임

참고

0개의 댓글