콘텐츠로 바로가기

Containerization & Docker Mechanics

애플리케이션과 그 실행 환경을 표준화된 단위로 묶는 가상화 기술과, 운영체제 수준에서 격리된 공간을 만드는 컨테이너 물리학을 다루는 학습 노드입니다.

Article
M

Me

hyunyoun's Blog

system-architecture-distributed-systemssystem-architecturedistributed-systemsmicroservicescontainerscontainerizationdocker-mechanicslearning10 min read

1. Overview

컨테이너화와 도커 역학(Containerization & Docker Mechanics)은 "내 노트북에서는 잘 되는데요?"라는 개발자의 변명을 영원히 박살 내고, OS부터 애플리케이션 코드까지 통째로 얼려서(Image) 지구상 어디든 똑같이 복제해 내는 현대 인프라의 표준 배송 규격을 해부합니다.

학습자는 무거운 하드웨어를 통째로 가상화하던 **가상 머신(Virtual Machine, Hypervisor)**의 비효율을 깨닫고, 리눅스 커널(Kernel)을 공유하면서 프로세스만 감옥(Namespace)에 가두는 **컨테이너(Container)**의 극단적인 가벼움을 뜯어봅니다. 나아가 Dockerfile을 통해 인프라 구축을 한 줄 한 줄의 코드(IaC)로 선언하고, 수천 개의 이미지를 효율적으로 겹쳐(Layer) 빌드 속도를 기하급수적으로 끌어올리는 **도커 이미지 레이어 아키텍처(Union File System)**를 장악합니다. 마지막으로, 컨테이너가 파괴되면 내부 데이터도 영원히 날아가는 휘발성(Ephemeral)의 한계를 깨고 볼륨(Volume) 마운트를 통해 생명력을 연장하는 인프라 튜닝 역량을 확보합니다.

2. Scope & Boundaries

In-Scope

  • Virtual Machine vs Container: Hypervisor(OS 가상화)와 Linux Container(프로세스 격리)의 물리적 차이.
  • Linux Kernel Features: Namespaces(자원 격리), cgroups(자원 할당 제한).
  • Docker Architecture: Docker Daemon, Client, Registry, Image, Container.
  • Image Layering (UnionFS): 캐싱을 활용한 Dockerfile 최적화, Multi-stage Build (이미지 다이어트).

Out-of-Scope

  • Kubernetes 기반 100개 컨테이너 자동 관리: \rightarrow 07-06-03 Kubernetes & Cluster Orchestration 영역으로 위임 (본 문서는 단일 컨테이너 혹은 Docker-Compose 수준에 집중).
  • CI/CD 파이프라인 자동 배포: \rightarrow 09-02 CI/CD & DevOps 영역.

Boundaries

  • Container는 미니 리눅스가 아니다: 초보자들은 도커 컨테이너 안에 SSH로 접속해서 apt-get install을 치고 설정을 바꿉니다. 이는 가상 머신(VM) 시절의 낡은 사고방식입니다. 컨테이너는 불변(Immutable)해야 하며 언제든 죽이고 새로 띄울 수 있는 '일회용 소모품(Disposable)'입니다. 변경 사항이 있다면 컨테이너 안에서 수정할 것이 아니라, Dockerfile을 고쳐서 완전히 새로운 이미지를 빌드해야 한다는(Immutable Infrastructure) 선을 명확히 긋습니다.

3. Counterexample

  • 10GB짜리 괴물 이미지: Dockerfile을 대충 짰습니다. 우분투 풀 버전을 베이스로 깔고, 빌드 도구(gcc)와 수많은 패키지를 설치한 뒤 소스코드를 컴파일했습니다. 최종 도커 이미지가 5GB가 되었습니다. 배포할 때마다 서버가 5GB를 다운로드하느라 배포 시간이 30분씩 걸립니다. 컴파일에 쓴 도구(gcc)는 버리고 최종 실행 파일(Binary)만 쏙 빼서 50MB짜리 알파인(Alpine) 이미지로 만드는 Multi-stage Build 기술을 모르는 자원의 학살입니다.
  • 데이터 휘발의 공포 (Ephemeral Death): 도커 컨테이너 안에 MySQL을 띄웠습니다. 유저 데이터가 착실히 쌓이고 있습니다. 어느 날 docker stopdocker rm으로 컨테이너를 지우고 새 버전으로 업데이트했습니다. 유저 데이터가 흔적도 없이 증발했습니다. 컨테이너의 파일 시스템은 컨테이너와 운명을 함께한다는 불변의 법칙을 무시하고, 호스트 OS의 디스크를 연결하는 볼륨(Volume) 마운트를 빼먹은 초보적인 대참사입니다.

4. Prerequisites

  • 리눅스 OS 기초 (Basic): 프로세스와 파일 시스템 계층 구조. (03-01 OS Core)
  • 가상화 개념 (Basic): 하드웨어 가상화와 OS. (03-02 Networking Basics)

5. Learning Map

Sequence Core Cluster Objective & Description Evidence (BoK)
1 VM vs Container 무거운 OS 전체를 띄우는 VM의 사슬을 끊고, 커널은 빌려 쓰면서 프로세스만 눈속임(격리)하는 컨테이너의 가벼움을 쥡니다. P1
2 The Magic of Namespaces 1번 프로세스(init)조차 격리시켜, 컨테이너 안에서는 자기가 서버의 유일한 주인인 줄 착각하게 만드는 리눅스 커널의 환술을 해부합니다. P5
3 Dockerfile & UnionFS RUN, COPY 한 줄마다 얇은 비닐(Layer)이 생성되고 겹쳐져, 빌드 속도와 용량을 미친 듯이 최적화하는 이미지 아키텍처를 뜯어봅니다. Industry
4 Immutability & Multi-stage 한 번 만든 이미지는 절대 변하지 않는다는 불변성 철학과, 쓰레기를 버리고 알맹이만 빼내는 다단계 빌드(Multi-stage)의 미학을 장악합니다. Industry

6. Learning Topics

Basic

Core Topic 01: 무거운 OS를 벗어던지다 (VM vs Container)

  • Why to Learn: 애플리케이션 하나 띄우겠다고 2GB짜리 OS 10개를 부팅하던 구시대 가상 머신(VM)의 비효율을 깨고, 단 1초 만에 켜지는 컨테이너의 구조적 승리를 이해하기 위함입니다.
  • What to Learn:
    • Concepts: Hypervisor, Guest OS, Container Engine (Docker), Host OS Kernel Sharing, Ephemeral (휘발성).
    • Skills: VM과 Container의 아키텍처 다이어그램 비교 및 부팅 속도(Overhead)의 물리적 차이 도출.
  • How to Learn:
    • 1단계: VM의 딜레마: 집(물리 서버) 안에 방 3개를 만듭니다. VM은 각 방마다 화장실, 주방, 보일러(OS)를 전부 따로 설치합니다. 무겁고 비쌉니다.
    • 2단계: 컨테이너의 공용화: 컨테이너는 주방과 보일러(리눅스 커널)를 하나만 두고, 각 방에는 칸막이(격리)만 칩니다. 애플리케이션 입장에서는 자기 방만 보이니까 독립적이라고 느끼지만, 실제 하드웨어 제어는 공용 커널이 다 해주는 극강의 효율을 해부합니다.
  • Implement: 도커 컨테이너 부팅 속도 시뮬레이션. 터미널에서 time docker run ubuntu echo "Hello"를 실행하면 1초도 안 걸려서 끝남. OS 부팅 과정(Init, Systemd)이 아예 생략되고 오직 echo 프로세스 하나만 실행됨을 터미널 로그로 증명.

Core Topic 02: 리눅스 커널의 환술, 격리와 통제 (Namespaces & cgroups)

  • Why to Learn: "도커는 어떻게 프로세스들을 완벽히 분리하는가?"에 대한 답이 결국 도커의 마법이 아니라 리눅스 커널의 기본 기능(Namespace, cgroup)을 포장한 것임을 꿰뚫기 위함입니다.
  • What to Learn:
    • Concepts: Linux Namespace (PID, NET, MNT - 논리적 격리), Control Groups (cgroups - 물리적 자원 제한).
    • Skills: 특정 컨테이너가 호스트 CPU를 100%100\% 잡아먹는 현상을 막기 위한 리소스 쿼터(Quota) 할당.
  • How to Learn:
    • 1단계: Namespace (보이지 않는 벽): 호스트 서버에는 1,000개의 프로세스가 돌고 있습니다. 도커가 컨테이너를 띄우면, 그 컨테이너 안의 프로세스에게 PID Namespace라는 안경을 씌웁니다. 이 프로세스는 자기가 "PID 1번(대장)"인 줄 알고, 다른 999개의 프로세스를 아예 보지(View) 못하는 착각의 감옥을 해부합니다.
    • 2단계: cgroups (물리적 목줄): A 컨테이너가 버그에 걸려 메모리를 무한대로 씁니다. 호스트 OS가 뻗기 전에 리눅스 cgroup이 작동하여 "너는 RAM 500MB까지만 써!"라며 가차 없이 OOM(Out of Memory)으로 컨테이너를 죽여버리는 자원 통제 기전을 뜯어봅니다.
  • Implement: CPU 강제 제한 데모. docker run --cpus=".5" ubuntu stress --cpu 1 실행. 호스트 OS에서 htop으로 확인하면, 컨테이너 안의 stress 프로세스가 아무리 CPU를 100%100\% 쓰려고 발악해도, 실제 호스트 CPU 코어 하나 기준으로는 정확히 50%50\%만 점유하는 cgroup의 통제력 렌더링.

Practical

Core Topic 03: 비닐을 겹쳐라, 도커 이미지 레이어 (Dockerfile & UnionFS)

  • Why to Learn: 무지성으로 Dockerfile을 짜면 코드를 한 줄만 고쳐도 전체 이미지를 다시 다운받아야 하는(캐시 무효화) 재앙을 막고, 캐시(Cache)를 극대화하는 빌드 최적화 역량을 장악하기 위함입니다.
  • What to Learn:
    • Concepts: Dockerfile 명령어 (FROM, RUN, COPY, CMD), Union File System (UnionFS), Image Layers, Layer Caching (레이어 캐싱).
    • Skills: 변경이 잦은 코드(Source)와 변경이 드문 의존성(npm install)의 순서를 배치하는 Dockerfile 캐싱 최적화 설계.
  • How to Learn:
    • 1단계: UnionFS (셀로판지 겹치기): 도커 이미지는 하나의 큰 파일이 아닙니다. FROM ubuntu (1번 비닐), RUN apt-get (2번 비닐), COPY . . (3번 비닐)처럼 투명한 셀로판지를 겹겹이 쌓아 올린 구조(Layer)입니다. 아래쪽 비닐은 누구나 공유해서 쓸 수 있어 디스크 용량을 획기적으로 아끼는 구조를 해부합니다.
    • 2단계: 캐싱의 저주: COPY . . (소스 코드 복사)를 먼저 하고 RUN npm install (라이브러리 설치)을 하면, 코드를 한 글자만 고쳐도 캐시가 깨져서 무거운 라이브러리를 매번 새로 설치해야 합니다. "자주 변하지 않는 것을 무조건 위에 둔다"는 Dockerfile 작성의 절대 법칙을 뜯어봅니다.
  • Implement: 안 좋은 Dockerfile vs 훌륭한 Dockerfile 빌드 속도 비교.
    • Bad: COPY . . \rightarrow RUN pip install -r req.txt
    • Good: COPY req.txt . \rightarrow RUN pip install -r req.txt \rightarrow COPY . . 소스 코드를 살짝 고친 뒤 두 번째 빌드(Re-build)를 돌렸을 때, Good 버전이 [CACHED]를 띄우며 1초 만에 빌드되는 기적을 터미널 로그로 증명.

Advanced

Core Topic 04: 불변의 인프라와 껍데기 벗기기 (Multi-stage & Volumes)

  • Why to Learn: 불변성(Immutable)을 지키기 위해 컨테이너 내부 데이터를 포기할 것인지, 영속성(Volume)을 위해 구멍을 뚫어줄 것인지 통제하고, 프로덕션 배포 이미지의 용량을 극한으로 깎아내리기 위함입니다.
  • What to Learn:
    • Concepts: Multi-stage Build (다단계 빌드), Docker Volumes (Bind mount, Named volume), Immutable Infrastructure (불변 인프라).
    • Skills: 빌드 도구와 런타임 환경을 분리하여 초경량(Alpine) 프로덕션 이미지를 추출하는 Multi-stage 작성.
  • How to Learn:
    • 1단계: Multi-stage Build (쓰레기 버리기): Go 언어로 코드를 짭니다. 빌드하려면 1GB짜리 golang 이미지가 필요합니다. 하지만 빌드가 끝나면 남는 main 실행 파일은 단 10MB입니다. 1단계(Builder)에서 1GB 이미지로 컴파일만 싹 하고, 2단계에서 깨끗한 5MB짜리 alpine 이미지에 실행 파일 10MB만 쓱 넘겨 담아 총 15MB짜리 프로덕션 이미지를 뽑아내는 다이어트 기법을 해부합니다.
    • 2단계: Volume (영속성의 구멍): 컨테이너는 불변해야 하므로 내부에서 쌓이는 DB 데이터는 컨테이너가 죽으면 날아갑니다. 이를 막기 위해 컨테이너의 /var/lib/mysql 디렉토리에 호스트 OS의 디스크를 연결(Mount)하여, 컨테이너를 지워도 데이터는 호스트에 안전하게 살아남는 볼륨의 역학을 뜯어봅니다.
  • Implement: Multi-stage Dockerfile 작성 및 Size 비교. AS builder 구문을 사용하여 자바 소스 코드를 maven 이미지에서 mvn package 로 컴파일하고, 아래에서 FROM openjdk:jre를 새로 열어 .jar 파일만 복사(COPY --from=builder)해 오는 데모. 기존 500MB 이미지와 최적화된 100MB 이미지의 크기(docker images) 콘솔 출력 비교.

7. Terminology

Term (EN / ko, abbr) 1문장 정의 단계(기본/권장/실무/심화) 역할/맥락 관련 개념 유사/대비/함께 사용 오해 포인트 Evidence(Primary/Secondary/Industry) Flags(core)
Containerization (컨테이너화) 애플리케이션이 돌아가는 데 필요한 코드, 런타임, 시스템 도구, 라이브러리를 하나의 상자(Image)로 묶어, 윈도우든 맥이든 리눅스 호스트든 어디서나 똑같이 실행되게 만드는 인프라 혁명입니다. 기본 애플리케이션 격리 및 배송 Docker Image / Dockerfile Virtual Machine (VM) 컨테이너는 그 자체로 완전한 OS가 아니며, 호스트 리눅스의 커널(심장)을 빌려 쓰는 껍데기에 불과함 P1:CS2023 core
Linux Namespace 리눅스 커널이 제공하는 기능으로, 프로세스마다 각자의 고유한 PID(프로세스 ID), 네트워크 IP, 마운트 지점을 부여하여 자기가 서버의 유일한 주인인 것처럼 눈속임하는 논리적 격리벽입니다. 권장 프로세스 격리 원리 cgroups / Docker Engine Chroot 도커가 만든 기술이 아니라, 원래 리눅스에 있던 기능을 도커가 예쁘게 포장해서 쓰기 쉽게 만든 것임 P5:SFIA core
Union File System (UnionFS) Dockerfile의 명령어 한 줄 한 줄을 독립적인 읽기 전용 레이어(Layer)로 만들고, 이를 차곡차곡 투명하게 겹쳐서 하나의 완성된 파일 시스템으로 보여주는 도커 이미지의 핵심 아키텍처입니다. 실무 이미지 레이어 캐싱 Image Caching Copy-on-Write (CoW) 하위 레이어의 파일을 상위 레이어에서 수정하면, 덮어쓰는(Copy-on-Write) 방식이므로 이미지 용량은 오히려 늘어남 Industry core
Multi-stage Build 컨테이너 이미지가 뚱뚱해지는 것을 막기 위해, 1단계 컨테이너에서 코드를 컴파일(빌드)하고, 2단계 텅 빈 경량 컨테이너로 '완성된 실행 파일'만 쏙 옮겨 담는 궁극의 다이어트 기법입니다. 심화 프로덕션 이미지 최적화 Alpine Linux / Dockerfile Builder Pattern 소스 코드 유출 방지와 공격 표면(Attack Surface) 최소화를 위해 보안 측면에서도 반드시 적용해야 함 Industry core

8. References

Primary

  • [P1] CS2023 - Software Engineering (SE) - Software Architecture and Containerization
  • [P5] SFIA - IT Infrastructure (ITOP) - Systems Installation and Removal

Secondary

  • [Docker Deep Dive] Nigel Poulton - Containers vs VMs, Images, and Architecture
  • [The Docker Book] James Turnbull - Building and Managing Images

Industry

  • [Docker Official Documentation] - Best practices for writing Dockerfiles
  • [Red Hat] - What is a Linux container? (Namespaces and cgroups)

9. Final Checklist

Primary

  • 하드웨어 하이퍼바이저 위에서 무거운 Guest OS를 여러 개 부팅하는 가상 머신(VM)과, 호스트 OS 커널 하나를 공유하며 프로세스만 격리하는 컨테이너(Container)의 성능 및 오버헤드 차이를 설명할 수 있는가?
  • 도커 컨테이너 안에서 돌아가는 프로세스들이 어떻게 호스트 서버의 다른 프로세스나 파일 시스템에 접근하지 못하는지, 리눅스 네임스페이스(Namespaces)의 역할을 증명할 수 있는가?

Secondary

  • 컨테이너가 무한 루프에 빠져 메모리 누수가 발생했을 때, 호스트 OS 전체가 뻗지 않고 해당 컨테이너만 메모리 초과(OOM)로 깔끔하게 죽여버리는 리눅스 컨트롤 그룹(cgroups)의 통제 역학을 해부할 수 있는가?
  • Dockerfile을 작성할 때, 소스 코드 복사(COPY . .) 명령어와 라이브러리 설치(RUN npm install) 명령어의 순서가 도커 이미지 레이어 캐싱(Layer Caching)과 빌드 속도에 미치는 치명적 영향을 논증할 수 있는가?

Industry

  • 프로덕션에 배포할 도커 이미지 용량을 1GB에서 50MB로 줄이고 보안 취약점(Attack Surface)을 최소화하기 위해, 멀티 스테이지 빌드(Multi-stage Build) 패턴과 경량화된 Alpine 이미지를 결합할 수 있는가?
  • 도커 컨테이너는 불변(Immutable)하고 언제든 삭제될 수 있는 휘발성(Ephemeral)을 가짐을 인지하고, 데이터베이스 컨테이너의 유저 데이터를 보호하기 위해 호스트 디스크를 마운트하는 도커 볼륨(Docker Volume) 아키텍처를 설계할 수 있는가?

System Architecture · Microservices & Containers

2 / 6