Deep Dive Docker

작성일: 2026. 04. 14.

수정일: 2026. 05. 10.

"격리하되 공유한다" 의존성 지옥 탈출의 시작

배경

도커가 해결하고자 한 문제들

환경의 불일치

  • 개발 환경(ubuntu 12.04 LTS, java7)과 운영 환경(Ubuntu 12.04 LTS, java6)의 차이로 인해 배포 때마다 예상치 못한 에러가 발생했고 라이브러리 버전 하나만 달라도 전체 시스템이 멈추는 것이 빈번했다

가상 머신의 비효율성

  • 이 문제를 해결하기 위해 기존에는 VMware나 VirtualBox같은 VM을 썻지만 VM은 아래와 같은 치명적인 성능 병목이 있었다
    • 무거운 리소스: OS 위에 또 다른 OS를 통째로 올려야 하므로 메모리와 CPU 소모가 극심함
    • 느린 속도: 부팅에만 몇 분씩 소모되어, 급변하는 트래픽에 유연하게 대응하기가 어려움

이 문제들을 어떻게 해결했는지 각 단계 별로 하나씩 알아보자

문제 재현

머리로만 이해해도 좋지만 도커가 없던 시절의 문제를 재현하여 사태의 심각성을 이해해보자

환경의 불일치 상황 재현

'데스크탑=서버'로 가정하고 '노트북=개발자PC'로 가정하여 도커가 없었던 시절의 개발자가 배포 시 겪는 현상을 재현해보았다. 변인 통제를 위해 모든 환경을 동일하게 세팅하고 라이브러리만 살짝 바꿔보기로 한다

구분 개발환경(노트북) 운영환경(데스크탑)
OS Ubuntu 22.04 Ubuntu 22.04
Python 3.14.04 3.8.20

*(참조)실제 터미널 화면

*자세한 구현 과정은 추후 포스팅 될 예정입니다(삽질을 정말 많이 했습니다 ㅠㅠ) 최신버전 가산기 test **이후로는 글의 가독성을 위해 코드 블럭으로 대체합니다

(developer Laptop)

	Python 3.14.4 (tags/v3.14.4:23116f9, Apr  7 2026, 14:10:54) [MSC v.1944 64 bit (AMD64)] on win32
	Type "help", "copyright", "credits" or "license" for more information.
	>>> def add_and_print(a, b):
	...     # ⚠️ 최신 Python인 3.14.04는 Python 3.9에서 도입된 '딕셔너리 병합' 기능을 사용
	...     # 서버(데스크탑)는 구버전(3.8)을 사용중이기에 '|' 기호를 이해하지 못해 '에러'를 낼 것으로 예상됨.
	...     data = {"n1": a} | {"n2": b}
	...     print(f"result: {data['n1'] + data['n2']}")
	...
	... num1 = int(input("num1: "))
	... num2 = int(input("num2: "))
	... add_and_print(num1, num2)
	...
	num1: 1
	num2: 3
	result: 4

(server Desktop)

	# venv 활성화 해서 python 버전 고정하기
	junseo@Junseo:~$ source legacy_env/bin/activate
	(legacy_env) junseo@Junseo:~$ python --version
	Python 3.8.20
	# 우리가 작성한 코드 돌려보기
	(legacy_env) junseo@Junseo:~$ python library_test.py
	num1: 1
	num2: 3
	Traceback (most recent call last):
	File "library_test.py", line 10, in <module>
		add_and_print(num1, num2)
	File "library_test.py", line 5, in add_and_print
		data = {"n1": a} | {"n2": b}
	TypeError: unsupported operand type(s) for |: 'dict' and 'dict'
	(legacy_env) junseo@Junseo:~$

실제로 코드를 돌려보니 상황은 더욱 어려웠다.

나는 python3.8.20이 '|'를 알아보지 못해서 Syntax Error를 띄울 것으로 예상했는데 Type Error가 떳다.

만약 syntax error였다면 문법 오류로 판단하고 바로 해당 문법을 점검했을 것이다. 그러나 python 3.8.20이 bit나 set을 합칠 때 쓰는 기호라서 문법 자체는 통과를 시킨 것이다.

막상 실행해보니 dict 2개를 합하라는 명령을 받아서 결과적으론 Type Error를 띄운 것으로 보인다.

docker가 없을 때의 문제를 이와 같이 간단하게 구현해보았다.

docker를 쓰지 않으면 의도치 않은 라이브러리 자동 업데이트 등의 예기치 못한 사유로 인해 코드가 먹통이 될 수도 있다.

  • 이제 docker의 필요성에 대해서 살펴봤으니 본격적으로 작동원리에 대해 탐구해보자.

1단계: 개념적 이해

"어디서든 똑같이 열리는 '마법의 배송 컨테이너'"

  • 개념: 예전에는 물건(프로그램)을 옮길 때, 어떤 건 트럭에 안 실리고, 어떤 건 기차에 안 실려서 난리였다. 그러나 도커는 모든 프로그램과 프로그램이 돌아가는 데 필요한 재료들을 '표준 컨테이너'라는 박스에 통째로 담아서 해결했다
  • 이로 인해 "내 컴퓨터에선 되는데 왜 네 컴퓨터 에서는 안 돼?"가 많이 사라졌다
  • 컨테이너 안에 모든 환경(각종 라이브러리)을 넣어서 이 컨테이너만 있으면 윈도우든 맥이든 리눅스든 상관없이 항상 똑같이 작동하게 됐다

2단계: SW 계층의 이해

"심장을 공유하는 '아파트형 공장'"

  • 예전에는 가상머신을 사용했다. 가상머신은 집을 옮길 때 땅바닥(OS/커널)까지 통째로 파서 옮기는 거였다면 도커는 '아파트 한 호수'만 빌린다고 생각하면 된다. 아파트 주민들이 공동 현관이나 엘리베이터(커널)는 같이 쓰되, 자기 집 안에서는 독립적으로 사는 것과 같다
  • 도커 엔진은 이미지(설계도)를 보고 컨테이너(실제 집)을 순식간에 만들어낸다
  • 자바처럼 가상머신을 따로 돌리는 게 아니라 운영체제의 핵심 기능을 빌려 쓰는 것이기 때문에 훨씬 가볍고 빠르다

3단계: OS 계층의 이해

"투명 인간 취급하는 격리 수용소"

  • 네임스페이스: 도커는 메모리와 프로세스에 '마법 안경'을 씌운다. 이 안경을 쓴 컨테이너는 컴퓨터에 수백 개의 프로그램이 돌아가고 있어도 "어? 이 세상엔 나 혼자밖에 없네?" 라고 착각하게 된다
  • Cgroups(Control Groups): 이건 '용돈 관리'를 생각하면 된다. "너는 아무리 배가 고파도 메모리는 1GB만 먹어!"라고 물리적 자원 사용량을 OS 수준에서 제한한다
  • 레이어 파일 시스템: 마치 '투명한 비닐'을 여러장 겹쳐서 그림을 그리는 것과 같다. 아래쪽 비닐(OS 기본 파일)은 건드리지 않고 그 위에 필요한 부분만 새로 그려서(데이터 추가) 용량을 아끼는 저장방식을 사용한다

그렇다면 도커는 왜 Linux로 만들어 졌을까?

이를 알기 위해선 다른 OS들과 비교했을 때 Linux만이 가진 특징을 알아야한다.

아래 표는 대표적 OS인 windows와 비교한 것이다.

Linux Windows
작업철학 프로세스 중심 쓰레드 중심
커널시각 프로세스와 쓰레드를 거의 동일하게 취급 프로세스와 스레드를 엄격히 구분

여기서 도커의 핵심은 커널이 제공하는 프로세스 격리 기술을 극한으로 활용한 것이기 때문에 리눅스를 기반으로 만들어질 수 밖에 없었던 것이다.

*추후 프로세스와 쓰레드에 대한 자세한 내용이 추가될 경우 링크가 연결될 예정입니다

참고자료

기술지도

상위개념

Layer1(역사/맥락)

  • [[Container Sprawl]]

Layer2(아키텍처/구조)

  • [[Kubernetes]] | 컨테이너의 배치, 복구, 확장 오케스트레이션 | 컨테이너 관리 자동화 문제를 해결
  • [[Docker Compose]] | 여러 개의 컨테이너로 구성된 애플리케이션을 YAML 설정 파일로 관리 | ㅇㅇ

Layer3(철학/추상화)

  • [[Cloud-Native Architecture]]

하위개념

Layer1(역사/맥락)

  • [[VM]] | 성능, 자원 최적화 |

Layer2(아키텍처/구조)

  • [[Linux Namespace]] | 프로세스별로 파일, 네트워크, 유저 등을 격리하는 커널 기술
  • [[Control Groups]] | 특정 프로세스의 자원량을 제한하는 커널 기술
  • [[Union File System]] | 여러 디렉토리를 하나의 통합 뷰로 보여주는 파일 시스템

Layer3(철학/추상화)

  • [[OS level Virtualization]] | 하드웨어가 아닌 운영체제 커널을 공유하며 프로세스를 격리하는 경량 가상화 원칙
  • [[Immutability]] | 실행환경을 이미지화하여 어디서든 변하지 않는 상태로 실행한다는 설계 철학