[책 리뷰] 그림으로 배우는 도커 - 스즈키 료

정현우·2025년 4월 25일
7

Book and Post Review

목록 보기
11/11
post-thumbnail

[ "한빛미디어 서평단 <나는리뷰어다> 활동을 위해서 책을 협찬 받아 작성된 서평입니다." ]

그림으로 배우는 도커

스즈키 료: 별명은 호게 상. 어쩌다 들어간 대학의 정보통신 계열 학과에서 프로그래밍을 접한 후 정보통신 분야에 빠져들었다. 2012년 모 전자 메이커 대기업에 취직해서 백엔드 엔지니어로서 ISP 서비스 개발에 종사했다. 2021년 미라이토디자인으로 이직, 현재는 Zenn(엔지니어 정보 공유 커뮤니티)에 투고하거나 회사 유튜브 채널에 진지한 동영상이나 그렇지 못한 동영상을 공개하고 있다(?)고 한다. (자료를 이 이상으로 찾지 못했다..)

🔥 책 예제 소스 // 구글 도서, 책 미리 보기 // 한빛 책 링크

리뷰

『그림으로 배우는 도커』 는 총 7부로 구성되어 있으며, 1부부터 5부까지는 도커의 기본 개념과 명령어, Dockerfile 작성법까지 점진적으로 설명하고, 6부에서는 실무에 가까운 컨테이너 활용 및 복합 이미지 구축을 다루며, 7부에서는 실제 운영 환경에서 마주치는 디버깅, 트러블슈팅, 그리고 환경 구성 노하우까지 전반적으로 포괄하고 있다.

이 책의 가장 큰 장점은 단연 "그림" 이다!!(책 이름 값이 쩔어요~)

단순한 시각 보조 수준을 넘어, 도커의 내부 동작과 추상적 개념들을 직관적으로 이해하게 해주는 데 압도적으로 효과적이다. 도커를 처음 접했던 시절, 유튜브 영상 하나 와 여기저기 흩어진 문서들로 간신히 image 하나를 만들어보고 감탄했던 기억이 있다. 외장하드에 우분투를 넣고 들고 다니며 겨우 컨테이너 하나 띄워봤던 그 어설픈 시작과 비교하면, 이 책은 입문자에게 너무나 친절하고, 중급자에게는 뼈대가 정리되는 경험을 선사한다.

특히 이 책은 '당장 도커를 다뤄야 하는 사람' 에게 실질적인 도움이 되는 책 이다. 시스템의 깊은 구조나 리눅스 커널 수준에서 컨테이너의 작동 원리를 파고들기보다는, 도커를 어떻게 사용할 수 있는지를 실습 중심으로 풀어낸다. container, image, Dockerfile, 그리고 docker compose 까지, "순차적" 으로 기능을 확장해 나가며 자연스럽게 독자가 불편함을 느끼고 그 불편함을 해결하는 흐름으로 구성되어 있다.

5부까지의 실습 은 각각의 도커 명령어를 하나하나 직접 실행하면서 기본기를 다지고, 이후 Dockerfile 을 중심으로 필요한 설정을 직접 추가해가며 컨테이너를 구성한다. 이 과정을 통해 단순 실행에서 끝나는 것이 아니라 '왜 이렇게 구성해야 하는가' 를 되짚게 되고, 최종적으로는 웹 메일함 프로젝트를 compose 파일 하나로 통합 실행하면서 도커를 실무에 도입할 수 있는 감각을 얻게 된다.

(출처: https://gngsn.tistory.com/129)

다만 이 책은 도커의 작동 원리 자체를 깊이 있게 이해하고자 하는 독자에게는 분명 아쉬움이 남는다. 예를 들어 리눅스 커널의 cgroupnamespace가 어떻게 자원 격리와 프로세스 분리를 구현하는지, overlay filesystem이 어떻게 이미지 레이어를 효율적으로 구성하고 병합하는지에 대한 구조적 설명은 거의 등장하지 않는다.

또한 컨테이너의 PID 네임스페이스와 유저 네임스페이스, 네트워크 브리징 방식 등 도커의 겉모습이 아닌 '안쪽 구조'를 궁금해하는 독자라면, 이 책의 실습 위주 구성은 다소 단조롭게 느껴질 수 있다. 실습 중심의 빠른 흐름은 입문자에게는 유익하지만, 개념과 구조를 충분히 곱씹으며 이해하고 싶은 독자에게는 설명이 생략되거나, 추상적인 레이어에서 멈춘다는 점이 아쉽다.

개념적 깊이보다는 실용적 완성도가 돋보이는 책이며, 현업 개발자라면 책장 한켠에 두고 필요할 때마다 꺼내보게 될, 그런 실전형 책인 것 같다.


목차별 리뷰

1부 가상화와 도커 기본 지식

(1장 ~ 4장)

가상화란, 소프트웨어로 하드웨어 자원을 추상화하여 마치 물리적인 머신처럼 보이도록 하는 기술이다. 이를 통해 하나의 물리 머신에서 여러 개의 가상 머신(VM)을 운용할 수 있고, 각각의 VM은 자체 OS 및 서비스를 운영하므로 충돌 없이 다중 서비스를 구축하는 데에 유리하다.

가상화의 방식은 크게 세 가지로 나뉜다.

  1. 호스트형 가상화: 호스트 OS 위에 가상화 소프트웨어(VirtualBox 등)를 설치해 게스트 OS를 가동한다. 이 구조는 하드웨어 접근 시 반드시 호스트 OS를 경유해야 하므로 성능 저하가 발생할 수 있다.
  2. 하이퍼바이저형 가상화: 하드웨어 위에 직접 하이퍼바이저를 설치하고 그 위에 게스트 OS들이 가동되는 구조이다. 별도의 호스트 OS가 존재하지 않아 성능 면에서 유리하다.
  3. 컨테이너형 가상화: 도커와 같은 도구로 애플리케이션을 컨테이너 단위로 격리한다. 게스트 OS가 없으며, 커널은 호스트와 공유한다. 즉, 커널 수준의 격리를 통해 VM보다 가볍고 빠른 환경 제공이 가능하다.

컨테이너형은 리눅스 커널에 의존하기 때문에, 리눅스 기반이 아닌 환경에서는 리눅스 커널을 별도로 사용해야 한다. 또한 호스트 머신의 CPU 아키텍처(예: amd64, arm64)는 컨테이너의 실행에도 영향을 미친다. 예를 들어 애플 실리콘(macOS/arm64)에서는 해당 아키텍처를 지원하는 이미지를 사용해야 한다.

도커 구성 요소

도커의 핵심 구성은 다음 세 가지이다.

  1. 도커 데몬(dockerd): 백그라운드에서 동작하며 이미지 빌드, 컨테이너 생성 및 관리를 담당. (실제 도커 핵심 엔진 로직)
  2. 도커 CLI: 사용자가 명령어를 입력하는 인터페이스
  3. 도커 API: CLI나 다른 도구가 데몬과 통신할 수 있도록 하는 API

이러한 구조 덕분에 CLI나 GUI(도커 데스크탑 등)는 결국 API를 호출하는 방식으로 동일한 기능을 수행한다.

CLI 클라이언트를 위한 명령어 모음세트가 결국 docker compose (.yaml) 과 같다고 이해하면 된다.

도커 허브(Docker Hub)는 도커 이미지의 저장소로, GitHub처럼 버전 관리가 가능하고, 동시에 패키지 매니저와 같은 역할도 수행한다. 사용자는 이를 통해 공식 이미지나 개인 이미지 저장 및 배포가 가능하다.

컨테이너 및 이미지 규격은 OCI(Open Container Initiative) 라는 비영리 단체에서 정의하고 있으며, 이는 도커 외에도 Podman 등 다양한 도구들이 이 표준을 따르게 해준다.

도커는 리눅스의 핵심 기능을 조합하여 컨테이너를 구현하고 있으며, 그 핵심은 다음 세 가지이다.

  1. namespace: PID, mount, network 등 시스템 자원을 격리
  2. cgroups: 자원(CPU, memory 등) 사용 제한
  3. chroot: 루트 디렉토리 변경으로 파일 시스템 격리

이로 인해 각 컨테이너는 독립된 PID 1(최상위 프로세스)을 가지며, 이는 호스트와 충돌하지 않는다. 컨테이너 내부에서 ps 명령어를 입력하면 자신의 PID 1만 보이는 것도 이 때문이다.

더 depth 있는 커널에 대한 정보는 https://amsekharkernel.blogspot.com/2016/11/what-is-linux-namespace-cgroups.html 와 Linux Kernel Documentation 의 https://docs.kernel.org/admin-guide/namespaces/index.html, https://docs.kernel.org/admin-guide/cgroup-v2.html 를 추천한다.

이미지

이미지는 컨테이너 실행에 필요한 실행 파일, 라이브러리, 설정 등을 여러 개의 레이어(layer) 로 구성한다. 각 레이어는 tar 아카이브 파일이며, 불변 속성을 갖는다. 여러 이미지가 공통 레이어를 공유할 수 있어 저장 공간 및 네트워크 사용을 최적화할 수 있다.

Dockerfile 은 이미지를 만들기 위한 설정 파일로, 새로운 레이어를 추가하는 역할을 한다.

도커 명령어 기초 지식

초기에는 모든 명령어가 docker 접두사를 사용했지만, 명령어가 너무 많아지면서 v1.13 이후부터 docker container, docker image, docker network 등으로 분기되었다. 이로 인해 명령어 체계가 좀 더 직관적으로 구성되었다.

docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]

특히 4.6장 명령어 치트 시트, 정리가 진짜 잘 되어 있다. sub 명령어 묶음과 containerstatus 에 따라서 flow chart 처럼 정리된 것을 보고 해당 장표 찢어서 어디 벽에 붙여 놓을까 했다. ㅎ

2부 도커 컨테이너 활용법

(5장 ~ 11장)

컨테이너는 PID1과 함께 탄생하고 죽는다

도커 컨테이너 내부에서 실행되는 첫 번째 프로세스는 Linux 시스템 상의 PID1에 해당하며, 이 프로세스가 종료되면 컨테이너 자체가 종료된다.

이는 컨테이너가 본질적으로 하나의 단일 프로세스를 중심으로 동작하는 경량 VM이라는 점을 극명하게 보여주는 설계다. 그래서 컨테이너 정지는 곧 PID1 프로세스의 종료를 의미하고, 그 이후 컨테이너는 stop 명령으로 정지시키거나 rm 명령으로 삭제하는 방식으로 관리된다. (필자는 stop 상태 그대로 둔 적이 딱히 없다고 한다! 물론 나도...)

앞으로 명령어의 상세한 내용은 도커레퍼런스 를 적극 참조하자!

실행(run)과 제거(rm)는 컨테이너 조작의 기본

docker container run ubuntu whoami 처럼 이미지를 기반으로 한 번만 실행하고 끝내는 방식도 가능하다.

(그림 설명이 진짜.. 너무 친절하다!!!)

이때 whoami 는 명령어 이후 인자는 모두 ARG...로 처리된다. 실행 후 자동 삭제는 --rm 옵션으로 가능하다. (--name 과 --rm 이 조합이 좋음)

--name 으로 컨테이너 이름을 지정하면 관리가 쉬워진다. docker run --rm --name test ubuntu echo hello 같은 조합은 일회성 테스트에 유용하다.

대화형 셸 실행을 위한 옵션

--interactive --tty, 줄여서 -it

  • --interactive 는 컨테이너의 표준 입력(stdin) 을 열어둔 상태로 유지하여, 사용자가 입력을 계속 보낼 수 있도록 하는 것
  • --tty 는 가상 터미널(TTY) 을 할당한다. 즉, 컨테이너에서 실행되는 프로세스가 터미널인 것처럼 동작할 수 있게 하는 것이다!

docker container run -it --rm python python3 형태로 Python REPL 을 바로 열 수 있다. bash 셸을 실행할 경우 docker run -it ubuntu bash 와 같이 활용이 가능하다.

포트 매핑으로 웹서버 외부 공개

  • docker container run --publish 8080:80 nginx 와 같이 --publish 또는 -p 옵션으로 호스트와 컨테이너 간의 포트 바인딩이 가능하다.
  • 이는 웹 개발이나 테스트 시 로컬에서 접속할 수 있는 환경을 만들 때 기본적인 패턴이다!

DB 서버는 환경 변수 세팅이 필수

MySQL 을 예로 들면 아래와 같이 "필수 환경 변수 값" 들이 있다.

docker container run \
--name db \
--rm \
--env MYSQL_ROOT_PASSWORD=secret \
--publish 3306:3306 \
mysql

대부분의 공식 이미지들은 필수 환경 변수들이 명시되어 있으며, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD 등 추가적인 설정도 가능하다.

도커 허브에 공식 이미지마다 환경 변수 문서가 잘 정리되어 있다!

백그라운드 실행은 detach

--detach 또는 -d 옵션으로 실행하면 컨테이너는 백그라운드에서 실행되고, 사용자 셸은 즉시 반환된다. (사실 이거 detach 가 아니라 daemon 인 줄 알았다.. attach 가 있고, 이 행위와 반대의 detach 개념이라는 점..!) -> 정확하게는 "표준 입출력을 분리" 하는 옵션이다.

docker run -d ... 는 nginx, mysql 같이 지속적으로 동작해야 하는 서버성 컨테이너에 필수적인 실행 방식이다.

컨테이너 출력 확인 logs

docker container logs [OPTIONS] CONTAINER, --follow (-f) 옵션과 함께 사용하면 실시간 로그 확인이 가능하다.

실행 중인 컨테이너에서 명령어 실행

  1. docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]
  2. docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]

docker container exec -it db bash, exec 는 기존에 가동 중인 컨테이너의 내부에서 별도의 프로세스를 실행하는 방식이다.

이미 실행 중인 컨테이너에 접속해서 새로운 명령어를 실행할 수 있는 방법이 exec 이다. run 은 새로운 컨테이너를 만드는 것이고, exec 은 기존에 살아 있는 컨테이너에 명령을 추가로 집어넣는 것이다.

예를 들어 docker container exec -it db bash 와 같은 명령어는 마치 SSH 를 사용하는 것처럼 컨테이너 내부에 진입하는 효과를 준다. 하지만 이는 프로세스 단위의 실행일 뿐, 실제 SSH 가 아니며, VM 과는 다르게 컨테이너는 전체 운영체제를 제공하지 않기 때문에 혼동하면 안 된다! (이는 "호스팅형 가상화" 와 "컨테이너형 가상화" 차이를 알아야 한다는 것이다!)

3부 도커 이미지 활용법

(12장 ~ 15장)

이미지의 기본 내용

도커 이미지는 여러 레이어(layer)로 구성되어 있으며, 최상단의 쓰기 가능 레이어(writable layer) 외에는 모두 읽기 전용(read-only layer)이다. 이미지를 구성하는 각 레이어는 설치나 설정 등 시스템 상태의 변화를 담고 있으며, 최종적으로 컨테이너를 만들 때 이 레이어들 위에 쓰기 가능한 레이어가 덧붙여진다.

  • 메타데이터(metadata)는 이미지 전체의 속성으로 환경 변수, 기본 실행 명령 등을 포함한다.
  • 이미지 명명 방식은 [HOST[:PORT_NUMBER]/][NAMESPACE/]REPOSITORY[:TAG] 형태다.
    • HOST 생략 시 기본값은 docker.io
    • NAMESPACE 생략 시 library 사용 (공식 이미지)
    • TAG 생략 시 latest가 기본값이나, 이는 이미지의 최신 상태가 예기치 않게 변경될 수 있으므로 주의가 필요하다.

도커 이미지 관련 주요 명령어는 docker image --help를 통해 확인 가능하며, --help 옵션을 적극적으로 사용하는게 많은 도움이 된다!

❯ docker image --help
Usage:  docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Download an image from a registry
  push        Upload an image to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.

이미지 기본 조작

  1. docker image ls [OPTIONS] [REPOSITORY[:TAG]] : 호스트 머신에 존재하는 이미지 목록을 확인
  2. docker image pull [OPTIONS] NAME[:TAG|@DIGEST] : 외부 레지스트리에서 이미지 다운로드, docker container run 명령어에서도 자동 수행된다!
  3. docker image inspect [OPTIONS] IMAGE [IMAGE...] : 이미지의 상세 메타데이터를 JSON 형식으로 출력
  • 특히 RepoTags, Config.Env, Config.Cmd 항목을 확인하면 유용하다!

이미지 조작 명령어는 디버깅과 환경 구성 시의 핵심 도구이며, JSON으로 나오는 상세 정보를 통해 이미지 구성과 환경 변수, 실행 커맨드를 사전에 파악할 수 있다.

vi를 설치한 우분투 이미지를 작성하고 공유하기

  1. docker container run --name myubuntu --interactive --tty ubuntu:22.04 bash
  2. apt update & apt install vim & which vi -> 그냥 ubuntu 이미지에서 which vi 하면 존재하지 않는다!, 이 순서로 myubuntu 에 vim 을 설치하는 것!
  3. 컨테이너에서 이미지 작성, docker container commit [OPTIONS] CONTAINER [REPOSITORY:[TAG]] 을 통해 이미지를 새로 만들어 보자!
❯ docker container commit myubuntu vi-ubuntu:commit
sha256:2204542f690c950e74aef2c8d2af737b1f9edb06d3edbb6eb1294a92e718ff62

❯ docker image ls vi-ubuntu
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
vi-ubuntu    commit    2204542f690c   10 seconds ago   185MB

❯ docker container run --rm vi-ubuntu:commit which vi
/usr/bin/vi

commit 은 컨테이너에서 이미지를 만들지만, 만들어진 이미지는 git 관리 또는 파일 저장소 업로드 불가능하다. 그래서 export 를 활용한다.

이러면 tar 아카이브 파일로 추출이 가능하며, 이후 tar 를 기반으로 image 처럼 읽어 올 수 있다! 그럼 두 명령어는 어떤 차이가 있을까?!

container 중심 말고 당연히 "IMAGE" 중심으로 tar 아카이브파일을 만들고 불러오는 것도 가능하다.

docker image save [OPTIONS] IMAGE [IMAGE...] (다수 이미지 지정 가능하다는 의미) 로 이미지를 tar 아카이브 파일로 작성 가능하며, load 명령어로 다시 이미지화 가능하다! 왜씀? 이미지 백업, 이관 & 이동에 활용!

4부 도커파일 활용법

(16장 ~ 19장)

위에서 살펴본 "tar" 파일 중심으로는 이미지 내용을 알 수 없다. 그렇다고 모르는 tar 를 합쳐서, 하나 하나의 layer 로 활용해서 쓰기에도 쉽지 않고 버전관리도 어렵다. 하지만 도커의 "이미지" 자체를 만들일은 굉장히 많다. 그때 도커파일(Dockerfile)을 사용해야 한다.

Dockerfile 은 컨테이너 환경을 코드로 명확하게 정의하고, 반복 가능한 이미지를 만들 수 있게 해주는 강력한 도구다. 기존엔 컨테이너를 만들고 설정하고 저장하는 흐름이 container run → exec → commit 으로 다소 수동적이었다면, 도커파일은 그 과정을 완전히 코드화할 수 있게 해준다.

특히 이미지를 tar로 만들면 내부 내용이 추상화되어 파악하기 어렵기 때문에, 어떤 이미지든 그 빌드 과정을 명시적으로 남길 수 있는 도커파일은 매우 중요하다.

명령어설명예시
FROM베이스 이미지 지정FROM ubuntu:22.04
ARG빌드 시점 변수ARG VERSION=1.0
ENV환경 변수 설정ENV NODE_ENV=production
LABEL이미지 메타데이터LABEL maintainer="you@example.com"
WORKDIR작업 디렉토리 설정WORKDIR /app
COPY로컬 파일 복사COPY . /app
ADD파일 복사, URL 다운로드, 압축 해제ADD https://example.com/file.tar.gz /app/
RUN빌드 시 명령어 실행RUN apt-get update && apt-get install -y curl
CMD기본 실행 명령어CMD ["npm", "start"]
ENTRYPOINT컨테이너 실행 명령어ENTRYPOINT ["python3", "app.py"]
EXPOSE수신 대기 포트EXPOSE 8080
VOLUME볼륨 마운트 디렉토리VOLUME ["/data"]
USER실행 사용자/UID 설정USER appuser
HEALTHCHECK상태 확인 명령어HEALTHCHECK CMD curl --fail http://localhost:8080
SHELL기본 셸 지정SHELL ["/bin/bash", "-c"]
ONBUILD파생 이미지용 명령어ONBUILD COPY . /app/src

이 도커파일 명령어들은 이미지가 만들어지는 과정을 '계층별로' 기록하는 역할을 한다. RUN 같은 명령은 실행 결과가 새로운 이미지 레이어로 저장되고, ENV, LABEL, EXPOSE 같은 명령은 이미지의 메타데이터로 저장된다. 도커 이미지가 결국 읽기 전용 레이어들의 조합이고, 도커파일은 그 조합의 '조리법'인 셈이다.

특히 FROM은 도커 이미지의 연쇄 구조를 만들어낸다. 하나의 이미지가 다른 이미지의 기반이 되고, 그 위에 또 다른 이미지가 올라가는 구조인데, 이건 마치 Git의 커밋 히스토리를 타고 올라가듯이 도커 이미지의 뿌리까지 따라갈 수 있다는 뜻이다. 도커 허브에서 이미지를 봤을 때, 어떤 베이스 이미지에서 파생되었는지 확인하는 것도 가능하다.

실습 예시 요약

  1. vi가 가능한 우분투 이미지

    • FROM ubuntu
    • RUN apt-get update && apt-get install -y vim
    • 단순하지만, 이미지 생성 과정을 명확히 기록할 수 있어 재현성과 이식성이 높아짐
  2. 시간대 설정 및 로그 출력이 설정된 MySQL 이미지

    • FROM mysql:latest
    • ENV TZ=Asia/Seoul
    • COPY ./my.cnf /etc/mysql/conf.d/
    • RUN echo "설정된 시간대와 로그 출력을 위한 설정 포함"
    • 운영 환경에 필요한 세밀한 설정을 담을 수 있음
  3. 간단한 파이썬 웹 서버 이미지

    • FROM python:3.11
    • COPY ./app.py /app/app.py
    • CMD ["python", "/app/app.py"]
    • 단일 파일 기반의 웹 서비스도 도커를 통해 바로 배포 가능한 형태로 구성

5부 ~ 7부, 직접 보면 더 도움이 될 부분들

5부 고급 도커 컨테이너 활용법

5부에서는 도커를 단순한 실행 도구가 아니라, 서비스 환경을 제어하는 방법으로 확장하는 과정을 보여준다. 핵심은 두 가지다: 볼륨네트워크.

  1. 볼륨: 컨테이너는 기본적으로 휘발성인데, volume 기능을 통해 데이터를 유지할 수 있다. volume create, --mount 옵션을 사용해 데이터를 보존하고, 컨테이너 재시작 시에도 동일한 상태를 유지하게 된다.
    • 바인드 마운트를 활용하면 호스트 머신의 디렉토리와 컨테이너 내부를 동기화할 수 있어, 로컬에서 코드나 설정 파일을 수정하면 바로 컨테이너에 반영된다. 실습에서는 루비 컨테이너에 로컬 스크립트를 실행하거나, MySQL 데이터의 지속성을 확보하는 방식으로 이를 체득하게 된다.
    • --volume--mount 의 커멘트 차이, 특히 볼륨 마운트와 바인드 마운트를 차이에 집중하는게 아주 좋았다. 개인적으로 mount 는 거의 써본적이 전무하다.
  1. 네트워크: docker network create, --network 옵션을 사용해 여러 컨테이너 간의 통신을 설정할 수 있다. 기본 브릿지 네트워크 외에 독립 네트워크를 정의하고, PHP 컨테이너와 MySQL 컨테이너가 서로 통신할 수 있게 연결하는 구조는 실제 서비스 구성에서 매우 자주 활용된다.

전체적으로 실습 위주이며, 단순한 실행 단계를 넘어서, 컨테이너 간의 협업을 이해하게 해준다. 이 과정은 일종의 "도커로 시스템 아키텍처를 설계하는 감각"을 키우는 데 도움된다.

아래는 개인적인 사견 및 정리

각 컨테이너는 network namespace 안에 있고(서로 격리된 네트워크 공간) 컨테이너마다 veth pair (virtual ethernet pair) 를 생성해서, 하나는 컨테이너 내부에, 다른 하나는 도커 브릿지 네트워크(docker0) 에 연결한다. 그래서 컨테이너 내부 통신 흐름은 아래와 같은 느낌이다.

[컨테이너1] veth0 <--> [브릿지 docker0] <--> veth1 [컨테이너2]

볼륨은 VFS 구조 하에 컨테이너의 mount namespace를 활용해 호스트 디렉토리 또는 독립된 볼륨을 연결하며, 핵심은 mount() syscall을 통해 실제 경로가 연결된다는 점이다.

6부 웹서비스 개발 환경 구축

6부는 개발자가 자주 마주치는 스택 구성 (PHP, MySQL, Mailpit 등)을 도커파일 기반으로 직접 만들어보고, docker compose 로 통합하는 구조를 다룬다. 핵심은 다음과 같다.

  • Dockerfile을 단계적으로 구성: 각 서비스별로 Dockerfile을 만들고, COPY, RUN, ENV 등을 활용해 설정값과 초기 상태를 명확히 한다.
  • 개별 컨테이너로 실습한 내용을 Compose로 통합:
    compose.yaml을 통해 의존성을 명시하고, 이름, 네트워크, 볼륨까지 정리한 하나의 선언적 환경 정의 파일로 완성된다.

이 과정에서 중요한 포인트는 "각 컨테이너가 배타적으로 동작하는 게 아니라, 서로 보완하며 작동한다"는 개념이다. 웹 서버가 DB를 참조하고, 메일 서버가 로그를 수신하는 방식은 서비스 간의 연결성과 설정의 유연함을 도커로 어떻게 구성할 수 있는지를 체감할 수 있다.

특히 compose.yaml로 정리할 때의 구조화된 쾌감은 단순한 실습을 넘어선 실전 감각으로 이어진다.

7부 운영 시 주의할 점과 트러블슈팅

7부는 도커를 현업에서 운영단에서 활용하는 시선을 제공한다.

  • 유료 플랜, 도커 계정과 같은 정책적 변화
  • 애플 실리콘 맥에서 ISA 호환 이슈 대응
  • 환경 변수와 .dockerignore, 여러 compose.yaml 파일 결합 활용
  • 디버깅: docker inspect, logs, exec 등을 통해 문제 상황을 좁혀가는 방식

이 파트는 기술적인 팁 외에도, 운영 중 마주칠 수 있는 현실적인 문제들을 예방하고 해결하는 방법론이 담겨 있다. 도커를 쓰면서 언젠가 반드시 맞닥뜨릴 상황들 — 퍼포먼스 문제, 아키텍처 호환성, 계정/정책 변화 등 — 에 대한 대비가 된다.

7부는 실습보다도, 읽으면서 ‘현실 감각’을 얻는 장이다. 개인적으로 이 책에서 가장 유익했던 챕터이기도 하며, 도커를 단순히 실행 도구가 아닌 서비스 운영 플랫폼으로 인식하게 되는 계기였다.

profile
🔥 도메인 중심의 개발, 깊이의 가치를 이해하고 “문제 해결의 본질” 에 몰두하는 software/product 개발자, 정현우 입니다.

0개의 댓글