DevOps with Docker

SK planet 플랫폼 아키텍처팀에서 ‘Docker 인프라 구축’ 프로젝트를 담당하고 있는 황상철입니다. 여러분 Docker가 뭔지 아시나요? 저는 2014년 말부터 이 Docker라는 기술을 배우고 실무에 적용하기 위해 노력하고 있습니다. 이번 포스팅을 통해 제가 그동안 알게 된 Docker에 관한 내용을 전달하고자 합니다.

왜 Docker를 선택했는가

서비스를 개발할 때 배포는 중요합니다. 배포가 쉬워야 테스트도 자주하고 장애가 발생했을 때 빨리 복구할 수 있습니다. Docker 관련 업무를 맡기 전에는 배포 시스템을 개발하고 운영했습니다. 배포시스템에 대한 자세한 내용은 이전에 제가 작성 한 ‘JARVIS 배포해’ http://readme.skplanet.com/?p=7148 를 읽어 보세요. 배포시스템(이하 JARVIS)은 기존에 사용하던 빌드서버(Jenkins)를 이용해서 만든 빌드결과를 가상 서버에 배포해 주는식으로 동작합니다. 이 과정에서 필요한 작업들 – L4에서 서버를 제외, 기존 결과 백업 등- 을 자동화해 줍니다. 하지만 이 빌드 흐름 에서 중요한 부분이 빠져 있습니다. 그건 바로 배포될 서버를 즉시 만들 수  없다는 점입니다.

제가 JARVIS를 만들 당시 사내에는 AWS EC2 같이 필요할 때 만들어 바로 사용할 수 있는 클라우드 인프라가 없었습니다. 프로비저닝(Provisioning)이라는 용어 들어보셨나요? 서버에 설치할 소프트웨어 종류나 설정을 미리 정의해 놓고 새로운 서버 를 만들 때마다 이를 적용하여 반복적인 설치나 설정을 자동화 하는 것을 말합니다. 프로비저닝을 위한 솔루션에는 Chef, Puppet이 있습니다.

On-premise 컴퓨팅 인스턴스와 프로비저닝이 가능해지면 불필요한 서버사용을 줄이고 효율적인 인프라 운영이 가능합니다. 저는 Docker를 이 두 가지 조건을 만족하는 인프라를 만들 수 있는 해결책으로 봤습니다.

프라이빗 클라우드 구축을 위한 다른 솔루션도 있다고 반문할 수 있습니다. Cloud Foundary나 OpenStack이 그런 대안입니다. 하지만 이것들을 도입하려면 오픈소스라고 해도 학습하고 경험을 쌓는 데 많은 비용과 시간이 필요합니다. 그에 비해 Docker는 손쉽게 유사한 환경을 구축할 수 있을 거라 판단했습니다.

Docker는 무엇인가

사내 외에서 Docker에 대한 발표와 세미나를 진행하면서 사람들이 Docker를 잘 모른다는 사실에 많이 놀랍니다. Docker를 잘못 알고 있는 경우도 많아서 Docker를 WAS와 혼동하기도 합니다.

Docker는 리눅스 컨테이너 기술의 하나로 기존 VM의 단점 – 용량이 크다, VM을 만드는데 시간이 오래 걸린다.-을 해결하기 위해 등장했습니다. 다른 리눅스 컨테이너 기술에 비해 사용하기 쉽다는 장점을 가지고 있습니다. 2015년 6월에 열린 DockerCon2015에 발표된 자료에 따르면 Docker는 매해 수백 %씩 성장 했습니 다. GitHub내 Docker관련 프로젝트가 40,000개, 도커 클라이언트 구축을 위한 boot2docker는 3백5십만 다운로드를 기록했습니다.

Docker에 대한 더 많은 소개는 제가 사내에서 진행했던 발표를 참고하시기 바랍니다.

Docker 인프라 프로젝트 – d4

Docker 기반의 인프라를 만들겠다는 생각을 실행에 옮기기 위해 2014년 사내 기술경진대회에 ’Docker 기반 개발환경 구축’이라는 제목의 아이디어를 제안합니다. 이 아이디어는 신규 추진과제로 선정되었고 우여곡절 끝에 ’d4’라는 프로젝트로 발전했습니다. 6개월 간 준비 끝에 8월초 베타버전을 릴리즈 했고 현재 사내 확산을 진행하고 있습니다. d4가 Docker 컨테이너를 얼마나 쉽고 빠르게 제공하는지 데모로 확인하세요.

d4 beta 0.05 데모 http://youtu.be/0VnIChXNZVo

d4는 Docker를 잘 모르는 사람도 개발에 필요한 컨테이너를 만들어 사용하는데 어려움이 없도록 설계했습니다. 하지만 궁극적으로는 로컬환경과 상용까지 Docker 기반으로 구축이 되어야 자연스러운 CD(Continuous Delivery) 파이프라인이 구축된다고 생각합니다. 그럼 지금부터 저희가 d4를 개발하면서 고민했던 내용 몇 가지를 공유하겠습니다.

Docker Host 운영체제

Docker Host는 d4가 만드는 Docker 컨테이너가 위치하는 서버입니다. 기업에서는 보통 Centos를 많이 사용하지만 Docker 구동에 최적화된 OS는 CoreOS 입니 다. Docker에 특화된 리눅스 CoreOS는 몇 가지 특징에서 기존 OS와 차별화됩니다.

  • 최소화된 OS: 기존 리눅스에 비해 40%적은 메모리를 사용합니다.
  • 빠른 OS 업데이트: OS용 부트파티션을 2개 가지고 있어서 한쪽 파티션이 업데이트가 되면 나머지 파티션이 없데이트 됩니다. 만약 한쪽이 업데이트 중에 에러가 발생해도 기존 파티션으로 동작하고 롤백이 가능합니다.
  • Docker 구동에 최적화된 아키텍처: etcd, sysemd, fleet

CoreOS가 Docker에 특화되어 장점도 많지만 패키지 관리자가 없어서 일반적인 용도로 쓰기에는 불편합니다. 서버관리를 해본 사람이라면 패키지관리자가 없다는 게 얼마나 큰 불편인지 공감합니다.

저희는 CoreOS를 Docker Host 운영체제로 결정하고 서버 관리에 필요한 작업도 컨테이너로 만들어서 해결하고 있습니다.

d4 자체를 컨테이너 기반으로 개발

마이크로서비스(Microservice)라는 아키텍처 스타일이 유행하고 있습니다. 최근 에는 마이크로가 주는 어감 때문에 Cloud Native로 바꿔 부른다고 합니다.

d4가 컨테이너를 제공하는 서비스임에도 저희 개발팀은 컨테이너 기반으로 서비스 를 운영해본 경험이 없었습니다. 그래서 컨테이너를 기반으로 서비스를 개발할 때 어떤 이슈가 발생하는지 먼저 겪어보기 위해서 d4 자체도 마이크로서비스로 개발 하고 Docker 컨테이너로 운영하고 있습니다.

환경이 컨테이너 기반이 되면 이전에는 당연했던 게 당연하지 않게됩니다. 웬만한 설정은 모두 환경변수로 분리해야 하고 IP도 고정할 수 없습니다. 더 자세한 내용은 컨테이너 기반 앱이 준수해야 하는 원칙들을 정리해 놓은 The Twelve-Factor App http://12factor.net/ 을 참고하세요.

컨테이너 오케스트레이션

컨테이너가 몇개 안될 때는 큰 문제가 되지 않지만 컨테이너 개수가 수백 개, 수천 개 로 늘어나면 컨테이너를 관리하는 일도 큰일이 됩니다. 컨테이너 오케스트레이션을 위한 도구를 여럿 검토했습니다.

Shipyard는 완성도가 너무 떨어졌고 Panamax는 UI는 화려했으나 기업에서 컨테이너 오케스트레이션을 위한 용도로 개발한게 아니어서 불편했습니다. Helios는 CLI 기반이라는 점만 빼면 여러 가지 면에 d4와 잘 맞았지만 결정적으로 리소스 케쥴링 기능이 없다는게 문제였습니다. Kubernets는 저희가 검토할 당시 아직 베타여서 참고할 자료도 부족했고 물리 장비 3대가 고작인 상황에 꼭 필요할까 하는 의문이 들었습니다.

그래서 저희는 CoreOS가 제공하는 Fleet에 Helios의 Docker 클라이언트 라이브러리를 이용해 몇 가지 기능만 구현해서 사용했습니다.

2015년 8월 현재 Kubernets v1이 정식 발표되었습니다. 베타에는 없던 UI 콘솔 에 그 동안 저희가 고민만 하고 해결을 미루어 왔던 멀티 호스트간에 컨테이너 네트워킹 이슈를 고려한다면 Kubernetes도 좋은 대안이 될거 같습니다.

표준 이미지 관리

Docker는 github 처럼 Docker 이미지를 공유할수 있는 DockerHub 사이트가 있습니다. DockerHub에는 2015년8월7일 기준으로 공식이미지 100개, 공개 이미지 45,000개가 올라와 있습니다. https://hub.docker.com/account/signup/ 웬만한 이미지는 대부분 찾을 수 있습니다만 이 이미지를 별다른 검증 없이 사용할 수 없습니다. 사내망에 만들어진 컨테이너는 다른 서버에도 접근할 수 있어서 보안상 위험할 수도 있고 내부 서버로 사용하기 위해 반드시 설치해야 하는 SW도 설치되어야 했습니다.

이를 위해 사내에 Registry 서버를 설치했고 사내 표준 Docker 이미지는 Dockerhub에 있는 공식 이미지를 기반으로 따로 만들었습니다. 이미지를 만드는 데 필요한 Dockerfile은 내부 git 레파지터리에서 관리합니다. 아직은 그런 사례가 없지만 필요한 Docker 이미지를 만들 때 참고할 수 있도록 Dockerfile이 들어있는 git 레파지터리는 public으로 사내 공개했습니다. Docker 이미지를 만들어 사내 Registry에 push 하는 작업도 Jenkins를 이용해 자동화했습니다. 향후 Dockerfile 에 대한 전면적인 수정이 일어난다 해도 빌드만 다시 실행하면 모든 이미지를 새로 빌드해서 Registry에 넣을 수 있습니다.

사내 Registry를 운영하면서 어려웠던 부분이 Registry 안정성입니다. 현재 Docker Registry는 v1과 v2로 나뉘어졌습니다. 파이썬으로 개발된 v1(https://github.com/docker/docker-registry)은 Depreciated  된 상황이며 v2(https://docs.docker.com/registry/)를 golang으로 다시 개발하고 있습니다. v1에 비해 v2가 속도도 빠르고 안정성도 좋지만 v2에서는 Registry에 들어있는 이미지 검색을 지원하지 않습니다. v1을 쓰자니 안정성이 떨어지고 v2를 쓰자니 검색 이 지원 안되는 상황에서 저희는 v1으로 일단 운영하면서 Registry에 push 할 때 에러가 발생하는 상황을 확인하여 해당 이미지만 지우는 형태로 운영 중입니다. 향후 v2에서 이미지 검색에 대한 대안이 마련되면 v2로 이관하려 합니다.

결론

지금까지 왜 Docker 기반의 개발 인프라를 만들게 되었는지, 그렇게 해서 만들어진 d4 시스템에 대한 내용을 간략하게 소개해 드렸습니다. d4는 이제 막 베타를 릴리즈한 수준이라 아직 그 효과나 활용도를 말할 수 없는 단계입니다. 하지만 이미 여러 글로벌 기업들이 컨테이너를 이용해 상용 서비스를 운영하고 있다고 발표했습니다. 구글은 10년간 컨테이너 기반으로 자신들의 주요 서비스를 운영해 왔고 그 경험의 결정체가 Kubernetes라고 발표했습니다.

Docker라는 로켓은 앞으로 클라우드 인프라에서 더욱 중요한 역할을 차지할 것입 니다. 개발과 운영이 하나같이 운영되는 DevOps 환경이 Docker로 인해 더 빨리 다가올 거라 믿습니다. 읽어주셔서 고맙습니다.

공유하기