Docker
Build once, run anywhere.
— 도커의 전설적인 슬로건이자 컨테이너 기술의 핵심 가치를 가장 완벽히 축약한 구절.
인프라 환경 구축에 소모되던 개발자들의 수억 개의 밤샘 시간을 '도커 이미지 딸깍' 하나로 단축해 준 현대 DevOps 혁명의 절대 군주. 하지만 로컬에 쌓인 쓸모없는 도커 이미지와 볼륨 찌꺼기들 때문에 어느새 하드 드라이브 용량 부족 에러를 내뿜는 용량 강도
1. 개요
Docker는 리눅스 컨테이너 기술(LXC)을 기반으로 하여 응용 프로그램을 실행에 필요한 모든 의존성(라이브러리, 환경 설정 등)과 함께 하나의 패키지로 묶어 배포하고 실행하는 가상화 플랫폼이다. 2013년 솔로몬 하이크가 PyCon에서 최초로 선보인 이래, 인프라 배포의 패러다임을 뿌리째 송두리째 뒤흔들었다.
이전의 무거운 가상 머신(VM)과 달리 호스트 운영체제의 커널을 공유하는 컨테이너(Container) 기반의 가상화를 도입함으로써, 실행 속도가 극단적으로 빠르고 가벼워졌다. 현대 소프트웨어 개발에서 개발, 테스트, 운영 서버 간의 환경 일치성을 보장해 주는 사실상의 표준 생태계로 자리 잡았다.(...)
2. 가상 머신(VM) vs Docker 컨테이너: 왜 도커인가?
2.1. 무거운 게스트 OS를 걷어내다
기존의 가상 머신(VM, 예: VirtualBox, VMware)은 호스트 OS 위에 하이퍼바이저를 올리고, 그 위에 독립된 게스트 OS(Guest OS)를 통째로 올리는 방식이었다. 이로 인해 사소한 웹 서버 하나를 구동하려 해도 기가바이트 단위의 OS 용량과 엄청난 부팅 오버헤드, 그리고 메모리 낭비를 감수해야 했다.
반면, Docker는 호스트 OS의 리눅스 커널 기능을 공유하면서 프로세스를 논리적으로 격리(Namespace, Cgroups)하는 방식을 사용한다. 게스트 OS가 존재하지 않기 때문에 도커 컨테이너는 실행 속도가 밀리초(ms) 단위로 극단적으로 빠르며, 메모리 사용량도 최소화된다. 이 가벼움 덕분에 하나의 서버에 수십, 수백 개의 컨테이너를 가볍게 띄워 구동하는 마이크로서비스(MSA) 아키텍처가 비로소 현실 세계에 무사히 연착륙할 수 있었다.(...)
2.2. 이미지와 컨테이너의 환상적인 복제 시스템
도커 생태계는 크게 이미지(Image)와 컨테이너(Container)로 양분된다.
- 도커 이미지: 실행 파일, 라이브러리, 환경 변수 등을 꽁꽁 얼려둔 정적인 '스냅샷' 혹은 클래스. 이 스냅샷은 읽기 전용(Read-only) 레이어들이 차곡차곡 쌓인 구조(UFS)로 이루어져 있다.
- 도커 컨테이너: 이미지를 런타임에 실행하여 살아 움직이게 만든 실체(Instance). 읽기 전용 이미지 레이어 위에 아주 얇은 '컨테이너 쓰기 레이어'를 덧붙여 작동시킨다. 덕분에 동일한 이미지 하나에서 독립된 컨테이너 수만 개를 1초 만에 즉석 복제해 구동할 수 있다.
3. 실무의 지옥: 네트워크, 볼륨, 그리고 이미지 다이어트
3.1. 데이터가 흔적도 없이 사라지는 마법 (볼륨 마운트)
초보 개발자들이 도커를 사용할 때 가장 많이 치르는 값비싼 대가가 바로 데이터 소실이다. 도커 컨테이너 내부에서 작성되거나 수정된 파일은 컨테이너가 삭제(rm)되는 순간 흔적도 없이 공중분해 된다. 컨테이너는 본질적으로 '한 번 쓰고 버리는 일회용 컵'과 같기 때문이다.
이를 해결하기 위해 호스트 서버의 디렉토리를 컨테이너 내부에 물리적으로 연결하는 볼륨 마운트(Volume/Bind Mount) 설정이 필수적이다. 이 볼륨 설정을 빠뜨린 채 데이터베이스 컨테이너를 무심코 재부팅하거나 지웠다가 밤샘 작업물이 몽땅 유실되어 회사 복도에서 오열하는 주니어 개발자들의 피와 땀은 오늘도 도커 생태계를 촉촉이 적시고 있다.1
3.2. 컨테이너끼리 대화가 안 돼요 (도커 네트워크)
분명 로컬에서는 웹 서버와 데이터베이스가 잘 통신했는데, 도커 컨테이너로 각각 띄우니 서로를 찾지 못하고 Connection Refused 에러를 사정없이 뱉어내는 상황 역시 단골 대환장 파티이다. 도커는 기본적으로 컨테이너마다 독립된 가상 IP 대역을 할당하는 격리된 네트워크 환경을 구축하기 때문이다. 이를 해결하기 위해 도커 브리지(Bridge) 네트워크를 생성해 같은 대역으로 묶어주거나, Docker Compose라는 다중 컨테이너 정의 도구를 사용하여 docker-compose.yml 파일 하나로 네트워크와 컨테이너 의존 관계를 일목요연하게 설계하는 고난도의 학습이 강제된다.2
4. 도커 관련 밈 및 드립
4.1. 내 컴퓨터에서는 잘 되는데요? (It works on my machine)
개발자의 역사상 가장 유구한 변명인 '내 컴퓨터에서는 분명 버그 없이 잘 굴러갔는데 배포 서버에 올리니까 왜 안 되죠?'를 완전히 박멸한 도커의 구세주적 면모를 찬양하는 밈이다. 도커의 해결책은 심플하다: '그럼 니 컴퓨터(도커 이미지) 자체를 고객사 서버에 그대로 배포하자!' 이 철학은 배포 환경 파편화라는 끔찍한 괴물을 물리쳐 개발 부서와 운영 부서(Ops)의 휴전 및 우정 결성에 혁혁한 기여를 했다.
4.2. 하드 드라이브 살인마 도커 (Docker system prune)
도커 이미지를 빌드하고 실행하는 과정에서 생기는 각종 구형 레이어, 정지된 컨테이너, 미사용 볼륨 등은 도커 엔진 깊숙한 곳에 캐시로 끊임없이 누적된다. 이를 주기적으로 청소해주지 않으면 몇 달 만에 도커가 기십, 기백 기가바이트의 하드 용량을 통째로 점거해 버린다. 결국 디스크 공간이 꽉 차서 빌드가 먹통이 될 때마다 개발자들은 서둘러 구글에 '도커 용량 확보'를 쳐본 후 docker system prune -a --volumes라는 하드 클리닝 명령어를 사정없이 때려 박으며 용량이 수십 기가씩 즉석에서 회복되는 짜릿한 쾌감을 맛보곤 한다.
5. 여담
- 도커 마스코트 모비 독(Moby Dock): 도커의 파란색 고래 위에 컨테이너 박스들이 층층이 실려 있는 영롱한 마스코트 캐릭터의 이름은 소설 허먼 멜빌의 모비딕에서 이름을 딴 '모비 독(Moby Dock)'이다. 고래 위에 실려 있는 박스는 화물 운송의 혁명을 이끈 표준 컨테이너 박스로, 소프트웨어 배포 규격을 표준화했다는 자부심 가득한 오마주이다.
- 파이콘에서의 5분 대격변: 도커가 세상에 처음 공개된 것은 2013년 파이콘(PyCon) 컨퍼런스의 'Lightning Talk(5분짜리 단기 발표)' 세션이었다. 솔로몬 하이크가 단 5분 동안 컨테이너가 순식간에 구동되고 빌드되는 시연을 마치자, 강연장에 있던 모든 인프라 엔지니어들이 기립 박수를 치며 충격과 열광의 도가니에 빠져들었다. 인류의 개발 역사를 바꾼 5분이었다.
- 쿠버네티스(Kubernetes)라는 최종 보스: 도커 컨테이너를 수십 개 수준을 넘어 수만 개 단위로 굴리기 시작하자, 컨테이너들의 자동 배포, 롤백, 스케일링을 관리해 줄 오케스트레이션 도구인 구글의 '쿠버네티스'가 대세로 등장했다. 쿠버네티스의 기괴하게 높은 진입장벽과 난해한 YAML 설정 뭉치들을 본 개발자들은 '도커는 그저 유치원 수준의 몸풀기였을 뿐이다'라며 대성통곡의 길로 접어들었다.