Cloud Architect/Docker

Chapter 3. Docker의 심해 속으로.

"Everything about infra" 2025. 10. 30. 17:50

안녕하세요, 지난 챕터에서 컨테이너의 정의와 Docker에 대해서 간략하게 다뤄보았는데

요번에는 Docker에 대해 조금 더 Detail 하게 들여다 보려고 합니다.

 

01. Container 격리 기술

Docker container를 띄워놓고 안의 구조를 들여다 보았습니다.

  • 여기서 'bash' 명령어는 linux 안으로 들어간다는 의미입니다. (보통 linux의 Shell을 bash shell 이라고 하죠?!)
  • 즉, 컨테이너를 실행 시킨 후 바로 접근한다는 의미.
docker run -it --rm --name=ssunghwan ubuntu:14.04 /bin/bash

 

container 내부에 들어온 후에 'ls' 명령어를 쳤을 때 아래와 같이 출력이 된다.

 

우리가 흔히 아는 linux system의 디렉토리 구조와 굉장히 유사하다.

또한 자세히 보시면 루트 경로로 바로 접근이 된 것을 확인할 수 있다.

 

최상위 경로에 linux system과 유사한 디렉토리 구조 → LXC 기술중 하나인 chroot (change root directory).

이 의미는 독립적인 파일 시스템 즉, 독립성을 보장받는다는 의미이다!

 

추가적으로 hostname에서의 '6ab18376a90f'의 의미는 눈치 채셨다 싶이

우리가 cli로 container를 생성할때 container ID가 생기는데, 그 container ID가 hostname이 된다.


이번에는 'ps -ef' 명령을 통해서 프로세스를 한번 출력해보자.

PID 1은 시스템 부팅 시 가장 먼저 실행되는 프로세스이며, 컨테이너 내부에서는 PID 1이 메인 프로세스 역할!

  • 즉, Container는 하나의 프로세스를 중심으로 동작하는 경량 가상환경
  • PID 1이 /bin/bash인 이유는, docker run으로 container 생성 시 bash로 실행하였기 때문이다.

추가적으로 네트워크를 담당하는 'if config' 명령을 통해서 라우팅 정보를 출력해보자.

Docker는 Container마다 독립된 네트워크 스택을 제공하며, eth0 interface와 host의 docker0 브리지와 연결.

  • container eth0 (172.17.0.2) → host의 docker0 bridge (172.17.0.1)  → NAT를 통해 외부와 통신.
  • 즉, 컨테이너는 독립된 IP를 가지지만 실제로는 호스트와 커널을 공유한다!!

실제로 터미널을 하나 띄워서 Host의 라우팅 정보를 확인해보면 docker0의 대역과 일치한다.


📌 요약을 해보자.

위 내용처럼 Docker는 Container를 독립적으로 격리하기 위해 여러 Linux Namespace를 사용한다.

  • 프로세스의 루트 디렉토리를 격리 (가상의 루트 디렉토리 생성) : chroot
  • container ID가 hostname으로 부여 : UTS Namespace (hostname과 domain 격리)
  • container는 독립된 프로세스 (PID 1로 시작) : PID Namespace
  • container마다 독립된 네트워크 : Network Namespace

02. Docker Container Lifecycle

1. docker container는 'docker create' 명령을 통해 image의 snapshot으로 /var/lib/docker 영역에 생성된다.

docker create -it --name ssunghwan ubuntu:14.04 /bin/bash

아직 ubuntu:14.04 image를 통해 container를 생성만 했을뿐, 실행되지는 않는다.

/var/lib/docker 영역 어디에 저장이 되는지 확인해보자.

'inspect' 명령으로 확인해보면 어느 영역에 저장이 되는지 알 수 있다.

 

현재 UpperDir에서 확인한 경로에 컨테이너의 writable layer 스냅샷이 생성된 것이며,

이 쓰기가 가능한 동적 컨테이너를 실행시키기 위해 아래와 같이 'docker start' 명령을 실행하자!

 

2. docker start 명령은 읽고 쓰기가 가능한 Process 영역인 container layer를 생성하여 적 컨테이너를 구성한다.

반대로, 'docker stop' 명령은 생성된 container를 중지시킨다.

현재 contaier layer가 '/var/lib/docker/container' 영역 아래에 생성이 되어 있네요.

 

생성된 컨테이너를 중지 시킨다고 해도, writable layer의 스냅샷 등 모든 layer의 스냅샷은 유지된다.

(컨테이너를 다시 재실행할 수 있어야 되기 때문에)

 

3. 'docker rm' 명령은 생성된 snapshot를 삭제하며, 이를 통해 docker lifecycle을 알 수 있다.

(컨테이너 메타데이터 + 컨테이너 writable lyaer이 삭제된다)

  • 아까 존재하던 /containers 디렉토리에 container ID를 가지고 있던 메타데이터가 없어짐
  • /overlay2 디렉토리에 존재하던 writable layer 스냅샷이 삭제됨.

📌 요약을 해보자.

Container 메타데이터는 '/containers' 에 위치한다.

  • Docker는 컨테이너의 상태,설정,로그,네트워크 정보를 별도로 관리해야 한다.
  • 그래서 '/var/lib/docker/containers/<container-id> 아래에 여러 파일로 관리된다.
    • config.json , hostconfig.json , log파일 , hosts, resolv.conf 등등.

Image 레이어와 container writable layer는 '/overlay2'에 위치한다.

  • OverlayFS는 파일시스템 레이어를 합성하는 커널 기능이다.
  • 이미지 레이어는 불변이고, 컨테이너 writable layer는 변경 가능하다 (읽고, 쓰기 가능한 동적 레이어)
  • 이 둘은 OverlayFS 규칙에 따라 'diff/', 'lower', 'work/' 구조를 가지게 된다.
    • diff/ : 해당 레이어의 실제 파일
    • lower : 하위 레이어 목록 (텍스트 형태로 저장된다)
    • work/ : 커널 작업 디렉터리

즉, Docker는 위 구조를 그대로 사용하며 모든 Layer(image + writable)는 /overlay2에 저장된다.