# Docker 컨테이너 10년

> Clean Markdown view of GeekNews topic #27313. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=27313](https://news.hada.io/topic?id=27313)
- GeekNews Markdown: [https://news.hada.io/topic/27313.md](https://news.hada.io/topic/27313.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-03-08T23:33:34+09:00
- Updated: 2026-03-08T23:33:34+09:00
- Original source: [cacm.acm.org](https://cacm.acm.org/research/a-decade-of-docker-containers/)
- Points: 11
- Comments: 1

## Summary

Docker는 지난 10년간 **Linux 네임스페이스**를 기반으로 가상머신 없이 프로세스 격리를 구현하며, 애플리케이션 배포 방식을 근본적으로 바꿨습니다. 단순한 CLI 도구로 보이지만, 내부에는 수십 년간의 시스템 연구가 응축되어 있으며, macOS·Windows 환경에서는 **HyperKit**과 **LinuxKit**을 통해 사용자 공간에서 Linux를 실행하는 독창적 구조를 채택했습니다. 최근에는 ARM·RISC‑V 등 이기종 하드웨어와 AI 워크로드를 지원하며, GPU 의존성 관리와 TEE 통합 같은 새로운 과제를 중심으로 진화를 이어가고 있습니다.

## Topic Body

- 2013년 첫 출시 이후 개발자들의 애플리케이션 빌드·배포·실행 방식을 근본적으로 바꿔온 Docker의 **기술적 진화 과정**을 조명하는 ACM 논문으로, 단순한 CLI 뒤에 숨겨진 수십 년간의 시스템 연구를 정리  
- Linux **네임스페이스**를 활용해 가상머신 없이도 프로세스 격리를 달성하는 방식이 Docker의 핵심 기술적 기반이며, 2001년부터 점진적으로 추가된 7가지 네임스페이스 유형을 조합해 경량 컨테이너 구현  
- macOS와 Windows 지원을 위해 **라이브러리 가상머신 모니터(HyperKit)** 를 데스크톱 앱 내부에 내장하는 역발상 아키텍처를 채택, 기존 하이퍼바이저 방식 대신 사용자 프로세스 안에서 Linux를 실행  
- 현재는 **ARM·RISC-V** 등 이기종 하드웨어와 AI 워크로드를 지원하며, 클라우드·데스크톱·엣지 전반에서 **표준 개발 인프라**로 자리 잡음  
- AI 워크로드의 부상으로 **GPU 의존성 관리**가 새로운 과제로 부상했으며, CDI(Container Device Interface)를 통한 GPU 지원과 TEE(신뢰 실행 환경) 통합 등 Docker의 진화가 계속 진행 중  
  
---  
  
### 기술적 기원  
  
- 2000년대 초반에는 Linux 배포판에 수많은 의존성을 수동 설치하고 소프트웨어를 직접 컴파일·설정하는 것이 일반적이었으며, 2010년 클라우드 컴퓨팅 부상으로 이 과정이 더욱 복잡해짐  
- Docker는 개발자가 애플리케이션과 모든 의존성을 **파일시스템 이미지("컨테이너")** 로 패키징하여 Docker만 설치된 어떤 머신에서든 실행할 수 있도록 단순화  
- 가상머신과 달리 전체 운영체제 설치 없이 몇 개의 명령어만으로 실행 가능  
  
### 일반적인 워크플로  
  
- 개발자가 **Dockerfile**을 작성하면 셸 문법 기반의 단계별 빌드 과정을 정의  
  - Python 웹사이트 예시: `FROM python:3`으로 시작해 의존성 설치, 코드 복사, 포트 노출, 실행 명령까지 한 파일로 기술  
- `docker build`로 컨테이너 이미지를 생성하고 `docker push`로 **Docker Hub**에 푸시  
- `docker run -v data:/app/data -p 80:80`처럼 데이터 볼륨 마운트와 네트워크 포트 노출을 지정해 실행  
- 2013년 이후 CLI는 크게 확장되고 백엔드는 전면 재설계되었지만, Dockerfile 작성 → `docker build` → `docker run`의 **기본 워크플로는 일관되게 유지**  
- GitHub에서 공개 저장소 루트에 위치한 Dockerfile이 **340만 개 이상** 발견됨  
  
### 내부 동작 원리: Linux 네임스페이스  
  
- OS 커널은 프로세스 메모리를 격리하지만 파일시스템, 설정 파일, 동적 라이브러리 등 여러 시스템 리소스는 공유 상태  
  - 동일 머신에서 **상충하는 동적 라이브러리 요구사항**을 가진 여러 앱 설치가 매우 어려움  
  - 네트워크 포트 충돌 등 프로세스 간 **원치 않는 간섭** 발생 가능  
- 각 앱을 개별 **가상머신(VM)** 에서 실행하면 해결되지만, 중복 커널·파일시스템·캐시·브릿지 네트워크 등으로 매우 무거움  
  - 각 게스트 OS가 독립적으로 동작하기 때문에 스토리지·메모리 **중복 제거도 어려움**  
- 1978년 Unix v7의 `chroot()`가 별도 루트 파일시스템을 허용했지만, 다중 앱 파일시스템 합성은 미지원  
- **Nix**와 **Guix**는 앱별 디렉토리 재패키징 + 동적 링킹으로 해결하나, 독점 소프트웨어에는 적용 어렵고 네트워크 포트 충돌 문제는 해결 불가  
- Docker는 Linux **네임스페이스**를 선택: 각 프로세스가 파일·디렉토리 등 공유 리소스 접근 방식을 개별 제어 가능  
  - 예: 서로 다른 네임스페이스의 두 프로세스가 `/etc/passwd`를 각각 `/alice/etc/passwd`와 `/bob/etc/passwd`로 다르게 해석  
  - 리소스를 **열 때만** 네임스페이스가 적용되고, 이후 파일 디스크립터는 추가 오버헤드 없이 일반 커널 리소스로 동작  
- 네임스페이스 도입 연혁  
  - 2001년 Linux 2.5.2: **마운트 네임스페이스**  
  - 2006년 Linux 2.6.19: **IPC 네임스페이스**  
  - 2007년 Linux 2.6.24: **네트워크 스택 네임스페이스**  
  - 총 **7가지 네임스페이스 유형** 지원  
- Plan 9과 달리 네임스페이스가 처음부터 설계된 것이 아니라 **점진적으로 추가**되어 저수준이고 사용이 어려웠음  
- FreeBSD, Solaris의 유사 기능도 대중적 사용에 이르지 못함  
- 2013년 Docker의 핵심 기여: **VM의 무거운 격리**와 **OS 기본 요소의 사용 편의성** 사이에서 실용적 균형점 발견  
  
### Docker의 Linux 컨테이너 실행 구조  
  
- Docker는 **클라이언트-서버** 구조로, 호스트에서 실행되는 서버 데몬(`dockerd`)과 RESTful API를 통해 요청을 보내는 CLI 클라이언트로 구성  
- 2015년경 모놀리식 데몬을 분리하여 전문화된 컴포넌트로 재구성  
  - **BuildKit**: 파일시스템 이미지 조립  
  - **containerd**: 이미지를 실행 중인 컨테이너로 인스턴스화하고 네트워크·스토리지 리소스 관리  
  
### 컨테이너 이미지  
  
- `docker build` 호출 시 Dockerfile의 실행 파일과 데이터를 나타내는 **레이어드 파일시스템** 이미지 생성  
  - 최하위 레이어: Debian 또는 Alpine Linux 등 OS 배포판(또는 tar 아카이브로 수동 조립)  
  - 이후 레이어: Dockerfile의 개별 명령 실행 결과로 생긴 파일시스템 차이  
- **콘텐츠 주소 지정 스토리지** 시스템에 저장: 파일시스템 이미지의 해시를 키로 관리  
  - 효율적 중복 제거, 불변성 보장, 해시를 통한 변조 검증  
- 2016년 **Open Container Initiative(OCI)** 에서 이미지 포맷 표준화, 다수의 독립 구현체 존재  
- Linux 파일시스템 **overlayfs, btrfs, ZFS**를 활용해 copy-on-write 레이어를 효율적으로 스냅샷·클론  
- `stargz` 스토리지 스냅샷터를 통한 이미지 **지연 풀링(lazy-pulling)** 지원  
  
### 컨테이너 인스턴스  
  
- `docker run` 호출 시 OCI 이미지에서 네임스페이스로 격리된 프로세스("컨테이너")를 생성하기 위해 시스템 리소스 할당  
- `containerd`가 각 컨테이너에 필요한 네임스페이스를 동적으로 설정하며 수행하는 작업:  
  - 리소스 격리와 I/O 속도 제한을 위한 프로세스 **cgroups(제어 그룹)** 정의  
  - 컨테이너 내부 로컬 네트워크 포트를 호스트 인터페이스의 외부 노출 포트로 **재매핑**  
  - 영구적 앱 상태를 위해 호스트 파일시스템의 **뮤터블 스토리지 볼륨** 연결  
  - **PID 네임스페이스**로 컨테이너의 프로세스 트리 격리  
  - **사용자 네임스페이스**로 컨테이너 내 로컬 UID를 호스트의 다른 UID로 매핑 (예: 컨테이너 내 UID 1000 → 호스트에서 UID 12345 또는 23456)  
- 네임스페이스 구성에 약간의 오버헤드가 있으나 **전체 Linux VM 스폰보다 훨씬 낮으며**, 대부분 1초 미만  
- Linux 커널이 종료된 컨테이너를 일반 프로세스처럼 **가비지 컬렉션**  
  
### Linux을 넘어서: macOS와 Windows 지원  
  
- 클라이언트-서버 아키텍처 덕분에 CLI가 보안 네트워크 연결을 통해 원격 Docker 인스턴스에 명령 전송 가능  
- 2015년, Docker가 Linux 개발에서 널리 채택되었으나 **macOS/Windows 개발자들이 Linux 컨테이너를 실행할 수 없는 사용성 장벽** 직면  
  - 대다수 개발자는 macOS/Windows를 기본 개발 환경으로 사용하지만, Docker 파일시스템 이미지는 Linux 커널에서만 실행 가능  
  - 퍼블릭 클라우드의 부상으로 배포 환경은 Linux가 선호됨  
  
### Docker for Mac 애플리케이션 구축  
  
- 핵심 제약: Linux 버전 Docker에 익숙한 개발자에게 **추가 설정 없이 동작**하고, 동일한 Docker 이미지 실행 가능해야 함  
- 기존 방식(Linux을 데스크톱 OS 옆에 별도로 실행)을 **뒤집어**, 하이퍼바이저를 macOS/Windows 사용자 공간 앱 **내부에 내장**하고 그 안에서 Linux 실행  
  - **유니커널(unikernel)** 연구에서 영감: OS 컴포넌트를 더 큰 애플리케이션 내에 유연하게 내장 가능함을 입증  
- **HyperKit**: Intel CPU의 하드웨어 가상화 확장을 사용해 일반 사용자 프로세스에서 Linux 커널을 실행하는 **라이브러리 VMM**  
  - 내장 Linux 커널이 Docker 데몬을 실행하고, 이것이 컨테이너를 관리하며 일반 Docker 서버 엔드포인트 역할  
  - 모든 Linux 관리 세부 사항은 데스크톱 앱 내부에 숨김 → 데스크톱의 `docker build`와 `docker run`이 내장 Linux 인스턴스로 전달되어 **"그냥 동작"**  
- 이 접근법은 **Podman** 등 다른 컨테이너 시스템에도 채택되어 macOS/Windows에서 컨테이너 실행의 표준 방식으로 자리 잡음  
  
### LinuxKit: 내장형 커스텀 Linux 배포판  
  
- 독립 실행형이 아닌 **다른 앱의 컴포넌트로 내장**되도록 설계된 커스텀 Linux 배포판  
- 앱 시작 시간을 최소화하기 위해 Docker 컨테이너 실행에 필요한 최소 컴포넌트만 포함한 **커스텀 사용자 공간** 구축  
- 모든 단일 컴포넌트를 컨테이너 내부에서 실행하여 부팅 시 사용되는 루트 네임스페이스에는 **아무것도 실행하지 않음**  
- Docker 컨테이너가 사용하는 것과 동일한 **copy-on-write 파일시스템과 네트워크 네임스페이스**를 활용  
- LinuxKit + HyperKit 조합으로 **네이티브 macOS 프로세스와 거의 동일한 속도**로 Linux 프로세스 부팅 가능  
- 2016년 Docker for Mac 및 Windows 앱으로 출시  
  
### 네트워킹 문제와 SLIRP 해결책  
  
- 내장 Linux 컨테이너에서 macOS/Windows로의 네트워킹 연결이 예상외로 까다로운 문제  
- 기존의 **이더넷 브릿징 방식**은 복잡한 네트워크 관리가 필요하고, 기업 데스크톱의 **방화벽·바이러스 체커**가 잠재적 악성 트래픽으로 탐지하여 베타 사용자로부터 수천 건의 버그 리포트 발생  
- **SLIRP** 해결책: 1990년대 중반 **Palm Pilot PDA**를 인터넷에 연결하는 데 처음 사용된 도구  
  - 컨테이너의 TCP 핸드셰이크 시 이더넷 프레임이 공유 메모리를 통해 **virtio 프로토콜**로 호스트에 전송  
  - **MirageOS**의 유니커널 라이브러리를 활용해 Linux 네트워킹 요청을 macOS/Windows 네이티브 소켓 콜로 변환  
  - OCaml로 작성된 사용자 공간 TCP/IP 스택 **vpnkit**이 호스트 OS에서 수신하여 macOS `connect()` 시스콜 호출  
  - VPN 정책 관점에서 나가는 트래픽이 별도 머신이 아닌 **Docker 앱에서 발생한 것으로 인식**  
- 2016년 베타 테스트에서 vpnkit 배포 후 기업 사용자의 버그 리포트가 **99% 이상 감소**  
- SLIRP 접근법은 이후 **서버리스 클라우드** 분야에서도 채택, 오래된 다이얼업 네트워킹 기법이 새로운 컨테이너 관리 문제 해결에 활용  
  
### 인바운드 네트워크 트래픽 처리  
  
- Linux 컨테이너가 포트를 리슨할 때 CLI에서 명시적으로 요청하지 않으면 자동으로 인터넷에 노출되지 않음 (예: `docker run -p 80:80 nginx`)  
- 이상적인 사용자 경험: 컨테이너 포트가 데스크톱 IP에 직접 나타나 `http://localhost:8080`으로 브라우저에서 접근 가능  
  - VMware Fusion 같은 기존 데스크톱 가상화는 `localhost` 대신 **임시 중간 IP**를 노출  
- LinuxKit 커널에 커스텀 **eBPF 프로그램** 설치 → 데스크톱 호스트에 대응하는 리스닝 소켓 생성 트리거 → 포트 포워더 활성화  
- 결과: Mac에서 Linux 컨테이너 실행 시 **즉시 `localhost`로 접근 가능**, 네이티브 Linux 머신과 동일한 개발자 경험  
  
### 스토리지  
  
- 개발자는 코드를 로컬에서 편집하면서 컨테이너에서 코드와 테스트를 실행해야 함  
- Linux에서는 `docker run -v /host:/container`로 **바인드 마운트**를 통해 라이브 파일 접근  
- macOS와 Windows는 다른 커널이므로 바인드 마운트가 동작하지 않음  
  - Docker가 KVM 하이퍼바이저에서 유래한 **virtio-fs** 공유 메모리 프로토콜을 사용해 파일시스템 연산을 호스트로 전송(FUSE 요청 형식)  
  - 호스트가 이 요청을 수신하여 대응하는 `open`, `read`, `write` 시스콜 호출  
- 개발자의 코드와 데이터가 호스트 파일시스템에 유지되어 Apple **Time Capsule**이나 **Spotlight** 같은 백업·검색 도구에서 접근 가능  
  
### Windows Services for Linux (WSL)  
  
- 2017년 Microsoft가 **WSL** 출시: Windows에서 직접 Linux 앱 실행  
  - 첫 번째 버전은 가상화 대신 Linux 바이너리의 시스템 콜을 Windows 시스템 콜로 **동적 변환**하는 라이브러리 OS 방식  
  - 많은 앱에서 성공적이었으나, Docker 컨테이너 실행에는 **지원하는 시스템 콜이 부족**  
- 2018년 **WSL2** 출시: Docker for Mac과 유사하게 백그라운드에서 **전체 Linux VM 실행** 방식으로 재설계  
  - WSL2 Docker는 LinuxKit WSL 배포판 내에서 데몬과 사용자 컨테이너를 실행  
  - Windows 자체와 다른 Linux 배포판에서 Docker API와 네트워크 포트 포워딩 처리  
- Docker 컨테이너의 크로스 플랫폼 진화를 가능하게 한 핵심 아키텍처: 전통적으로 "**커널 전용 코드**"를 사용자 공간 라이브러리로 재활용하여 다른 앱에 내장하는 **라이브러리 OS 접근법**  
- 이 아키텍처의 성공은 **보이지 않으면서 편재**한다는 점에서 입증: 수백만 개발자가 매일 어떤 OS에서 실행 중인지 걱정 없이 Docker 사용  
  
### 새로운 개발자 워크플로: 다중 CPU 아키텍처  
  
- Docker 초기에는 클라우드 워크로드 대부분이 **Intel 아키텍처** 기반  
- 2018년 **Amazon Graviton ARM** 프로세서, 2020년 **Apple M1 ARM** CPU 출시로 상황 변화  
  - ARM에서 워크로드 실행 시 **비용 절감과 성능 향상** 가능  
- 동일 Docker 이미지 내에서 Intel, ARM, POWER, **RISC-V** 등 다중 CPU 아키텍처 지원 필요  
- 서버 측에서는 OCI 이미지 포맷을 **멀티아키텍처 매니페스트(multiarch manifests)** 로 확장  
- 단일 호스트에서 다중 CPU 아키텍처용 이미지 빌드를 위해 Linux의 `binfmt_misc` 기능 활용  
  - **QEMU**를 통해 ARM과 Intel 바이너리 간 투명 변환  
  - 주로 빌드 단계에서만 오버헤드 발생, 결과 멀티아키텍처 이미지는 어떤 호스트에서든 **네이티브 실행**  
- Apple이 **Rosetta**를 통해 CPU 명령어 세트 변환의 하드웨어·소프트웨어 지원 도입 → Docker 아키텍처에 쉽게 통합  
- 현재 Intel과 ARM 컨테이너를 **나란히 실행**하는 것이 일반적인 개발자 워크플로  
  
### 신뢰 실행 환경(TEE)을 통한 비밀 관리  
  
- 컨테이너 환경에서 비밀번호나 API 키 같은 **비밀(secrets) 관리**는 항상 도전 과제  
  - 파일시스템 이미지에 베이킹하지 않고 **동적으로 주입**해야 함  
- Docker는 **소켓 포워딩**을 지원해 로컬 도메인 소켓을 컨테이너에 마운트 가능  
  - Docker for Mac/Windows의 경우 Linux VM까지 소켓 포워딩  
  - `ssh-agent` 같은 키 관리 시스템을 키를 직접 노출하지 않고 컨테이너 내에서 사용 가능  
- 소켓 포워딩은 기본 보호 수준을 제공하지만, 커지는 소프트웨어 공급망 내 멀웨어에 대해 **더 많은 방어 계층** 필요  
- **하이퍼바이저 보호**를 컨테이너 런타임 내에 직접 적용하여 크로스 컨테이너 보호 수준 향상  
- **신뢰 실행 환경(TEE)**: 현대 CPU의 하드웨어 기능으로 **호스트 OS에서도 비밀 데이터를 보호**할 수 있는 "기밀 VM(confidential VMs)" 생성  
  - 앱, 커널, 하이퍼바이저 경계를 넘어 데이터 접근 제한 적용 가능  
  - 그러나 TEE 구성·사용은 OS 가상화와 유사한 **관리 복잡성** 존재  
- **Confidential Containers** 워킹 그룹이 TEE 내에서 실행되고 Docker로 관리되는 앱 개발 중  
  - Docker CLI가 데스크톱 로컬 TEE에서 호스트를 거쳐 원격 클라우드 TEE 환경까지 **암호화된 메시지 포워딩**  
  - 개발자가 현장에 가지 않고도 민감한 클라우드 환경에 인증 가능, 자격 증명은 **데스크톱 엔클레이브에 안전하게 저장**  
  
### AI 워크로드를 위한 GPGPU 지원  
  
- AI 워크로드의 부상으로 완전히 새로운 도전 과제 등장: 머신러닝 워크로드는 대부분 **GPU**에서 실행  
- 핵심 문제: GPU 워크로드는 **정확히 일치하는 커널 GPU 드라이버와 사용자 공간 라이브러리** 필요, 다수의 컨테이너가 단일 공유 커널에서 실행  
  - 두 앱이 동일 커널 GPU 드라이버의 **다른 버전**을 요구하면 Docker가 원래 해결하려던 것과 동일한 근본 충돌 발생  
- 2023년 3월부터 Docker가 **CDI(Container Device Interface)** 지원  
  - 컨테이너 시작 시점에 파일시스템 이미지를 커스터마이징  
  - GPU 장치 파일과 GPU 전용 동적 라이브러리를 **바인드 마운트**하고 `ld.so` 캐시 재생성  
- CDI는 특정 GPU 클래스·벤더 간 이미지 이식성을 보장하지만, 다른 OS·하드웨어 브랜드 간에는 **완전히 매끄럽지 않음**  
  - CDI가 추가하는 동적 라이브러리가 서로 다른 API를 정의하므로, 컨테이너의 전통적 인터페이스인 안정적 **Linux 시스템 콜 ABI**에 비견할 만한 것이 없음  
  - Nvidia GPU용 앱이 Apple M시리즈 CPU에서 실행되기 어려운 이유: GPU 가상화 지원이 다양한 하드웨어 간 **벡터 명령어를 변환할 만큼 성숙하지 않음**  
- 컨테이너 커뮤니티 및 GPU 제조사와 협력해 GPU 관련 의존성 관리의 **더 유연하고 안전한 방법** 개발 중  
- **이식 가능한 인터페이스** 이니셔티브가 합의에 수렴하기를 기대  
  
### 결론  
  
- Docker는 2013년 개발자가 더 쉽게 앱을 빌드·공유·실행하도록 돕겠다는 목표로 시작  
- 현재 표준 클라우드 및 데스크톱 개발 워크플로에 깊이 통합되어 전 세계 **수백만 개발자가 매일 사용**, 월간 **수십억 건의 요청** 처리  
- 상호운용을 위한 표준을 구축하는 **활발하고 다양한 오픈소스 커뮤니티** 유지가 일관된 목표  
  - **CNCF(Cloud Native Computing Foundation)** 가 여러 핵심 컴포넌트의 관리자 역할  
  - **Open Container Initiative(Linux Foundation 소속)** 가 이미지 포맷의 관리자  
- 오늘날 이들 요소의 다수 구현체가 활발하며, 클라우드·데스크톱·**자동차·모바일·우주선** 등 에지 환경에서 배포 증가  
- 2025년 기준 일반적인 개발자 워크플로는 지속적 테스트·배포, IDE 언어 서버, **에이전틱 코딩을 통한 AI 지원**을 통합  
- Docker 관점에서 핵심 "빌드 앤 런" 워크플로는 10년 전과 매우 유사하지만, **다양한 환경에서의 마찰을 줄이는 시스템 지원**이 대폭 강화  
- Docker를 개발자가 더 빠르게 코드를 배포하도록 돕는 **보이지 않는 동반자**로 만드는 것이 목표이며, 현대 AI 코딩 워크플로에 맞게 **확장 가능하도록 설계**

## Comments



### Comment 52622

- Author: neo
- Created: 2026-03-08T23:33:34+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=47289311) 
- 처음 Docker가 나왔을 때는 또 하나의 **‘혁신’** 이라는 말에 질려 있었음  
  반쯤 완성된 NoSQL, 무조건적인 마이크로서비스, 모든 함수 호출을 RPC로 바꾸는 흐름이 싫었음  
  하지만 지금은 단순함 덕분에 자주 사용하고 있음  
  다만 **다른 사람의 컨테이너**는 여전히 지옥 같음. 나는 최소한 단순하게 유지하려 하지만, 어떤 사람들은 너무 많은 걸 넣어버려서 본인도 배포 과정을 모르는 듯한 느낌을 받음  
  이제는 LLM 덕분에 개발자가 직접 보지도 않은 코드가 쏟아지는 시대가 된 것 같음
  - 새벽마다 DevOps 팀이 컨테이너 문제를 해결하려고 **끝없는 Zoom 콜**을 하는 걸 보며, 아무도 진짜로 무슨 일이 일어나는지 모른다는 확신이 생겼음

- 수많은 시도가 있었지만 결국 **Dockerfile**이 살아남은 이유는 유연성 때문임  
  기존 운영 방식처럼 파일을 복사하고 명령을 실행하는 구조가 익숙했기 때문임  
  보기엔 투박하지만, 이 단순한 유연함이 앞으로도 주류로 남을 것 같음
  - 언어 중립적인 빌드 도구가 없기 때문에 결국 언어별 패키지 매니저를 호출하는 임의 명령을 실행하게 됨  
    만약 모두가 Nix나 Bazel을 썼다면 `docker build`는 웃음거리가 되었을지도 모름
  - **재현 가능한 빌드**를 막는 장애물이 있음  
    서로 다른 빌드에서 해시가 달라지면 신뢰할 수 없기 때문에, 파일 수정 시간 같은 요소가 해시에 포함되는 한 완전한 일관성은 어려움
  - Docker registry 같은 중앙 저장소가 없는 게 대체 솔루션의 **병목 지점**임  
    개인적으로는 mkosi를 좋아하지만, 모두가 빈 OS 템플릿에서 시작하길 원하지는 않음
  - Nix는 Docker 컨테이너를 만드는 데 탁월함
  - registry와의 결합이 좀 더 강했으면 좋겠다고 느낌  
    대부분의 경우 public registry에서 pull하고 private registry로 push만 하기 때문에, 로컬 이미지는 거의 쓰이지 않음  
    약간 비효율적이지만 바꿀 만큼 불편하지는 않은 듯함

- Docker가 2013년 PyCon US Santa Clara에서 처음 공개된 걸 기억함  
  당시 [YouTube 발표 영상](https://youtu.be/1vui-LupKJI?t=1579)을 보면 역사적인 순간임  
  논문 출판 시점과 실제 발표 시점이 달라서 혼동이 있었던 듯하지만, 대략 13년 전 이야기임
  - 제목은 단순히 **‘시간을 거슬러 올라간다’** 는 의미로 붙인 것임  
    “Twelve years of Docker containers”보다 “A decade of Docker”가 더 자연스러웠음
  - 실제로는 2014년이 맞음  
    [HN의 초기 발표 글](https://news.ycombinator.com/item?id=5408002)을 기억함  
    당시 LXC나 Vagrant 같은 대안에 지쳐 있었는데 Docker는 정말 **구세주 같은 존재**였음

- Docker가 1990년대 **SLIRP**라는 다이얼업 도구를 재활용해 방화벽을 우회했다는 점이 흥미로움  
  - Podman도 한때 [slirp4netns](https://github.com/rootless-containers/slirp4netns)를 썼지만, 최근에는 [Pasta](https://passt.top/passt/about/#pasta-pack-a-subtle-tap-abstraction)로 전환했음  
  - SLIRP는 Palm Pilot용이 아니라, SLIP/PPP를 쓸 수 없던 **쉘 계정 사용자**들이 인터넷 연결을 흉내 내기 위해 만든 유틸리티였음  
    들어오는 연결은 안 됐지만, NAT의 전조 같은 개념이었음  
  - Palm Pilot용 도구를 방화벽 우회에 쓴 건 **미친 발상**이지만, 그런 절박함이 최고의 인프라 해킹을 만들어냄  
  - SLIRP는 ‘rootless’ 네트워크 네임스페이스를 위한 것으로, 루트 권한 없이 호스트 네트워크에 컨테이너를 붙이는 방식임

- Docker를 써보고 싶었지만, 쓸 때마다 필요한 기능이 빠져 있었음  
  아마도 흔치 않은 **기술 스택**을 사용해서 그런 듯함

- “내 컴퓨터에서는 잘 되는데”를 산업 표준으로 만든 게 Docker의 위대함임  
  이제는 그 컴퓨터 자체를 프로덕션에 **‘배송’** 하는 시대가 되었음
  - 공동 저자로서, Docker 이전에는 Xen을 다뤘는데, Docker가 **IT 문화 자체를 바꾼 사건**이었음  
    예전엔 배포가 거대한 절차였지만, 이제는 파일시스템을 바로 배포할 수 있게 되었음  
    지금의 **코딩 에이전트 혁신**도 그때와 비슷한 문화적 전환으로 느껴짐  
  - Docker는 빌드를 **반복 가능한 프로세스**로 캡처하게 만든 게 핵심임  
    10줄짜리 스크립트로 환경을 재현할 수 있다면 “머신을 배포한다”는 것도 나쁘지 않음  
  - Docker는 일종의 **극단적인 정적 링크**임  
    왜 이런 접근이 그렇게 매력적인지 스스로 물어볼 필요가 있음  
  - “노트북에서 잘 되네”가 이제 “노트북을 컨테이너로 만들어 파이프라인에 넣자”로 바뀐 것 같음  
    추상화가 항상 이기는 이유는, 근본적인 문제를 고치는 게 너무 어렵기 때문임  
  - 형편없는 컨테이너들이 제대로 된 **패키징 시스템** 대신 Dockerfile로 서비스 관리까지 하려는 걸 보면 지침

- 네트워킹은 잘 모르지만, Mac에서 컨테이너가 **별도의 IP 주소**를 가지게 하고 싶음  
  포트 매핑 없이 `container_ip:80`으로 접근하고 싶음  
  Linux에서는 가능했지만 Mac에서는 VM을 거쳐야 해서 복잡함  
  [WireGuard 기반 방법](https://github.com/chipmk/docker-mac-net-connect)을 써봤지만 Docker 업데이트 때마다 깨짐  
  공식적으로 지원되는 방법이 있으면 좋겠음
  - Docker 엔지니어로서, **Tailscale 확장**을 써보길 권함  
    [Tailscale Docker Extension](https://hub.docker.com/extensions/tailscale/docker-extension)이 설정을 자동으로 처리함  
    포트 매핑을 피하려는 이유가 동적 포트 때문이라면 `--net=host` 옵션과 Host Networking 설정을 켜보길 권함  
  - Mac은 없지만, 오픈소스 대안으로 **Colima 프로젝트**를 추천함

- 2013년은 Docker, Guix, NixOS가 모두 등장한 **패키징의 풍년**이었던 해였음  
  [관련 논문](https://anil.recoil.org/papers/2025-docker-icfp.pdf)을 쓰면서 이 사실을 발견함  
  이후 이렇게 여러 훌륭한 프로젝트가 한 해에 동시에 등장한 적이 있었는지 궁금함
  - hg와 git이 몇 주 간격으로 나왔고, fossil도 곧이어 등장했음  
  - 솔직히 Docker만이 진짜 대중화에 성공했다고 느낌  
    Guix나 Nix는 여전히 **소수 사용자층**에 머물러 있음

- ML과 AI가 모든 곳에 들어가면서 이미지 크기가 **기하급수적으로 커짐**  
  torch 하나만으로도 수 GB가 됨  
  예전의 30MB 이미지를 그리워함
  - TensorFlow를 **두 번 설치**한 이미지도 봤음  
    레이어 간 파일 공유가 안 돼서 낭비가 심함  
    그래서 파일 단위 dedupe를 지원하는 **대체 registry**를 직접 만들고 있음  
  - 나는 ISO 기반의 **불변 Alpine Linux** 위에 Ruby와 PHP 컨테이너 몇 개를 올려 사용 중인데, 전체가 750MB 정도임

- Docker가 기업용 보안 소프트웨어를 속이기 위해 **VPN처럼 위장**했다는 점이 정말 흥미로웠음  
  기술적 역사로서도 재미있는 사례임
