사실 Docker라는 개념에 대해 어렴풋이 알고는 있었다. 하지만 개인프로젝트를 진행하는 입장에서 vercel이나 github에서 직접 배포하지 굳이 귀찮게 그런걸 왜 쓰지? 이런 생각이 강했다.
하지만 진행했던 개인프로젝트가 시간이 흘러 개인 컴퓨터의 환경이 바뀌자 개인 프로젝트들도 제대로 구동이 안되기 시작했고 그 때 나는 Docker의 필요성을 느끼게 되었다.
컨테이너
도커를 이해하기 위해선 컨테이너와 이미지라는 개념을 이해해야한다. 도커는 흔히 컨테이너 기반의 오픈소스 가상화 플랫폼이라고 불린다. 컨테이너라는 것을 떠올리면 여러가지 제품을 배에 실을 수 있게 도와주는 화물 수송용 박스를 떠올릴 것이다.
서버에서이야기하는 컨테이너도 이와 비슷한데 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해준다.
구글의 경우 구글의 모든 서비스들이 컨테이너로 동작하고 매주 20억 개의 컨테이너가 구동 한다고 한다.
컨테이너는 격리된 공간에서 프로세스가 동작하는 기술이다. 가상화 기술이지만 기존의 방식과는 차이가 있다.
기존의 가상화 방식은 OS를 가상화 하였다. 우리에게 익숙한 VMware나 VirtualBox 같은 가상머신은 호스트 OS위에 게스트 OS 전체를 가상화 하여 사용하는 방식이다.
이 방식은 리눅스에서 윈도우를 실행한다던가 윈도우에서 리눅스를 실행할 수 있고 비교적 사용법이 간단하지만 누겁고 느려서 운영환경에선 사용할 수 없었다.
이러한 상황을 개선하기 위해 CPU 가상화 기술을 적용한 커널 기반의 가상화 머신이라던가 반가상화 방식이 등장하게 된다. 여전히 게스트 OS가 필요하긴 했지만 전체 OS를 가상화 하는 방식은 아니였기 때문에 호스트형 가상화 방식에 비해 성능이 향상 되었다.
개선되긴 했어도 여전히 성능에 문제가 있었기 때문에 이를 개선하기 위해 프로세스를 격리 하는 방식이 등장한다.
리눅스에서는 이 방식을 리눅스 컨테이너라고 단순히 프로세스를 격리시키기 때문에 가겹고 빠르게 동작한다. CPU나 메모리는 딱 프로세스가 필요한 만큼만 추가로 사용하고 성능적으로도 거의 손실이 없다.
이미지
앞서 얘기한 도커의 가장 중요한 개념 중 하나인 이미지라는 개념이다.
이미지는 컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않는다. 이미지가 실행 한 상태가 컨테이너라고 볼 수있고, 추가되거나 변하는 값은 컨테이너에 저장이 된다. 같은 이미지에서 여러개의 컨테이너를 생성 할 수 있고, 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있다.
말그대로 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 의존성 파일을 컴파일하고 이것저것 설치할 필요가 없다. 이제 새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운받고 컨테이너를 생성만 하면 된다. 한 서버에 여러개의 컨테이너를 실행할 수 있고, 수십, 수백, 수천대의 서버도 문제없다.
레이어
도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 보통 용량이 수백메가MB에 이른다. 처음 이미지를 다운받을 땐 크게 부담이 안되지만 기존 이미지에 파일 하나 추가했다고 수백메가를 다시 다운받는다면 매우 비효율적일 수 밖에 없다.
도커는 이런 문제를 해결하기 위해 레이어layer라는 개념을 사용하고 유니온 파일 시스템을 이용하여 여러개의 레이어를 하나의 파일시스템으로 사용할 수 있게 해준다. 이미지는 여러개의 읽기 전용read only 레이어로 구성되고 파일이 추가되거나 수정되면 새로운 레이어가 생성된다.
만약 X 라는 이미지가 a + b + c 의 집합이라면 a 이미지를 베이스로 만든 x' 이미지는 a + b + c + d 여기서 x'의 소스를 수정했다면 d만 받으면 된다는 것이다.
항상 미루고 미루던 Docker에 대한 개념에 대해 공부해보았다. 현재 Docker 설치까진 해놓은 상태인데 아마 실사용은 현재 하고 있는 프로젝트를 어느정도 마무리하고 배포단계에 들어가면 사용해보지 않을까한다.