Docker Clustering 키노트

May 6, 2016



Daou Tech에서 진행한 Docker 클러스터링 세미나에 대한 발표 텍스트입니다. 프리젠테이션 내 회사 자료가 포함되어있어 프리젠테이션은 공개하지 않으며, 다음 텍스트 또한 일부 내용이 제외되어 있습니다.

Docker Review

지난번 Docker 세미나를 못 들으신 분을 위해 간단히 Docker에 대해 리뷰를 해보겠습니다. 왼쪽의 Virtual Machine은 오라클의 Virtual Box나 VMware 등의 하이퍼바이저를 이용하여 가상 머신을 만드는 가상화 방법입니다. 이렇게 생성한 가상 머신에 OS를 설치하고 애플리케이션을 설치합니다. 흔히 사용하는 가상화 방법이기에익숙하지만 OS 설치하고 IP 셋팅하고 너무 귀찮죠. 애플리케이션 하나만을 굴린다고 머신 가상화를 해야하고 게스트 OS까지 돌려야하기 때문에 리소스 낭비도 있고 느리다느 얘기를 드렸습니다.

반면, 오른쪽의 컨테이너 가상화는 OS 위에 Docker Engine을 설치하고, 호스트 OS와 별개의 환경을 담을 수 있는 컨테이너를 생성합니다. 컨테이너 내에는 애플리케이션과 그 애플리케이션을 위한 라이브러리만 담을 수 있어서, 가상 머신보다는 아무래도 가볍죠. 가볍기 때문에 컨테이너를 이미지화해서 어딘가로 배포하기 쉽고, 무엇보다Docker는 배포와 관련된 API 및 Repository(registry)가 표준화 되어있기 때문에 개발, 빌드, 테스트, 배포까지의 프로세스를 구축할 수 있다는 얘기를 드렸습니다.

리뷰는 여기까지만하고 Docker에 대한 기본적인 내용은 이전 세미나 자료를 참고해주시길 바랍니다.

Docker Image

본격적으로 Docker 클러스터링에 들어가기 앞서, Docker 이미지에 대해서 좀 생각해볼 필요가 있습니다. Docker 이미지는 매 커밋마다 컨테이너로 실행했을 때 생성한 데이터가 이미지에 추가되는데, 여기서는 Status A라고 표시했습니다. daou0527 이미지로 컨테이너를 실행시키고, daou0627로 커밋하면 1달간의 증분 데이터가 이미지에 추가될 것입니다.

그런데 Status A가 유저의 메일 박스를 담고있는 /maildata 데이터라면 daou0527 이미지는 5월 27일까지의 메일들만 있고 daou0627은 6월 27일까지의 메일들이 커밋되어 있을 것입니다. 아무튼 그렇게 잘 운영하다가 6월 27일 이후의 TMI가 뭔가 이상해서노란색 화살표처럼 5월 27일 이미지로 롤백하고자 할 때 그 사이의 1달간의 메일들은 바이바이해야 합니다.

즉, Status A는 이미지가 변한다해도 영속성을 가져야하는 Persistence 데이터이죠. 이런 데이터가 이미지에 들어있으면 안됩니다.

Data Volume

Docker는 이러한 Persistence 데이터를 위해 Data Volume이라는 것을 지원하는데,그림과 같이 Data Volume은 이미지에 포함되지 않는 영역입니다. 데이터 볼륨은 이미지로부터 컨테이너를 생성할 때 만들어지는데 물론 그냥 생성되지는 않고, Dockerfile에 VOLUME 다음에 컨테이너 내의 경로를 작성해주고 빌드한 뒤, 컨테이너를 생성해주면 됩니다.

그러면 컨테이너를 생성할 때 VOLUME에 대한 경로가컨테이너 밖의 호스트 디렉토리로 맵핑되고 컨테이너 안이 아닌, 컨테이너 밖의 호스트 디렉토리에 데이터를 쌓게 됩니다. 물론 컨테이너 입장에서는 /maildata가 호스트 디렉토리인지 아닌지는 모르며, 뭐 알 필요도 없겠죠.

기본적으로 호스트 디렉토리에 마운트되게끔 사용하는데, 데이터 볼륨용으로 별개의 컨테이너를 만들어서 그 컨테이너에 데이터를 쌓을 수도 있고 볼륨 플러그인을 사용하면 GFS나 NFS, AWS의 EBS 스토리지에 데이터를 쌓을 수 있습니다.

주의할 점은 데이터 볼륨은 커밋에 포함되는 영역이 아니라는 점입니다. tmi:1.0 이미지로 만든 컨테이너에 데이터를 쌓아서 1.1로 커밋한다해도, VOLUME으로 지정한 /maildata의 데이터는 커밋되지 않습니다. 이걸 깜빡하고 registry에 푸쉬했다, 백업 됐다! 라고 생각하면 안되는 것이죠. 데이터 볼륨은 커밋되지 않는다. 반드시 명심하셔야 합니다.

Docker Clustering

이제 본격적으로 Docker 클러스터에 대해 얘기를 해보죠. Docker 클러스터링이 거창한 것은 아니고, 여러개의 Docker 호스트들을 논리적인 그룹으로 묶는 것입니다. 호스트별로 ssh 들어가서 명령어 때리거나 REST 콜하는 것보다,이렇게 클러스터로 묶은 그룹이알아서 컨테이너를 생성해주는 것이 더 편하겠죠.

만약 여기서 사용자가 늘어나서 TMS가 더 필요하다라고 했을때, 클러스터 API 콜하면 클러스터가 알아서 리소스가 남는 호스트에 TMS 컨테이너를 생성시킬 것입니다. 이것을 자동화시키면 결국 Cross-Host Auto Scaling이 되는 것이겠죠.

Data Volume tied to Single Server

Docker 클러스터에서 몇가지 고려할 점 중 하나는 이전에 살펴본 데이터 볼륨입니다.데이터 볼륨은 기본적으로 Host에 종속적입니다. 하나의 TMS 이미지로 1번 호스트에서 TMS 컨테이너를 생성하고, 2번 호스트에도 TMS를 만든다면 2개의 TMS 컨테이너는 서로 다른 데이터 볼륨을 다루게 됩니다.

우리의 전통적인 방법으로, 앞단에서 유저별로 고유한 호스트를 지정하고 프록시한다면 문제는 없겠으나 만약 1번 호스트가 장애를 일으켰을 때, 1번 호스트에 지정된 유저들은 장애가 복구되기 전까지는 서비스를 받을 수 없습니다. 이 말은 곧 클러스터 내의 일부 장애가 클러스터 밖의 서비스에 장애를 준다는 의미이기 때문에반쪽짜리 클러스터링이 되고 맙니다.

따라서 호스트에 종속적인 데이터 볼륨을 가지기 보다는, Shrared나 Replica, Copy on Write를 지원하는 파일 시스템이 필요합니다. Docker는 로컬 외의 볼륨 마운팅을 지원하지 않기 때문에 추가적인 볼륨 플러그인을 사용하여 GFS나 NFS, EBS 등에 데이터 볼륨을 마운트시켜야 합니다.

Plaforms

이러한 Docker 클러스터링을 구축하는 방법으로 몇가지 오픈소스를 사용할 수 있는데, Docker Swarm은 Docker에서 배포하는 네이티브 클러스터링 툴입니다. Docker Swarm으로 클러스터링을 구성하면, 기존에 사용하던 Docker API와 크게 다를 것없이 클러스터링을 사용할 수 있습니다. 그러나 클러스터링 API가 부실해서 Cross-Host 오토 스케일 등은 알아서 개발해주어야 합니다.

Rancher은 커뮤니티에서 최근 각광받고있는 오픈소스인데, 각 호스트에 Agent용 컨테이너를 올려서 Management 컨테이너와의 통신으로 클러스터링을 구축합니다. 그래서 그냥 Manage 컨테이너와 Agent 컨테이너만 올리면 클러스터링 구성이 끝납니다. 그리고 Docker Swarm에 비해 Cross-Host 컨테이너 관리나 네트워크, 로드 밸런서 등이 구현되어있고 특히 웹 UI를 제공하고 있어서 컨테이너 생성이나 관리가 편리합니다. 저는 Rancher를 쓰고 나서부터는 이미지 빌드를 제외하고는 웹에서 거의 모든 것을 처리하고 있습니다.

그 다음으로 Volume 플러그인인데, Flocker라는 오픈소스가 거의 독보적인 것 같습니다. 아마존의 EBS나 오픈스택의 Cinder, EMC, VMware, Dell 등 벤더사의 스토리지를 지원하기 때문에 스냅샷이나 백업/복구 등 벤더사가 지원하는 기능을 추가적으로 사용할 수 있습니다.

Convoy는 Rancher의 하위 프로젝트인데, Rancher를 사용하고 EBS, GFS, NFS/VFS 정도의 스토리지만 사용한다면 충분히 괜찮은 플러그인인 것 같습니다.