도커 컨테이너 10년
GeekNews (AI)
|
|
📰 뉴스
#docker
#가상화
#linux
#도커
#소프트웨어 개발
#컨테이너
#프로세스 격리
#하드웨어/반도체
원문 출처: GeekNews (AI) · Genesis Park에서 요약 및 분석
요약
도커(Docker) 는 애플리케이션 스택을 손쉽게 조립하고(docker build), 실행 파일과 데이터를 빠르게 배포하며(docker push), 여러 애플리케이션을 격리된 환경에서 동시에 실행할 수 있게 하는 개발 도구임 2013년 첫 출시 이후
본문
- 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
Genesis Park 편집팀이 AI를 활용하여 작성한 분석입니다. 원문은 출처 링크를 통해 확인할 수 있습니다.
공유