안경잡이개발자

728x90
반응형

도커(Docker)의 개요

나동빈


※ 도커의 개요 ※


  이번 시간에는 최근까지 소프트웨어 개발자들에게 계속 핫한 주제였던 도커(Docker)에 대해서 알아보도록 하겠습니다. 도커(Docker)리눅스 컨테이너를 기반으로 하여 특정한 서비스를 패키징하고 배포하는데 유용한 오픈소스 프로그램입니다.



  도커 공식 서비스는 위 사진과 같이 귀여운 고래 모양의 캐릭터를 메인 로고로서 사용하고 있습니다.


※ 도커를 사용해야 하는 이유 ※


  이번 글에서는 도커를 사용해야 하는 이유에 대해서만 제대로 이해하셔도 충분합니다. 기존에 다양한 형태로 개발을 하셨던 분들이라면 Maven, Gradle, FTP 등의 다양한 패키징 및 배포 도구를 사용해보신 적 있으실 거에요. 이러한 배포 도구들이 사용되었던 이유는, 특정한 소프트웨어를 개발한 이후에 배포하고자 할 때 해당 프로그램이 어디에선가 손쉽게 구동이 되도록 하기 위해서에요. 예를 들어 열심히 웹 개발을 했는데, 실제로 접속이 가능한 웹 서버에 배포를 하지 못한다면 누구도 그 서비스를 이용할 수 없겠죠?


  예를 들어 저는 이전에 JSP를 이용해서 웹 사이트를 개발하는 방법에 대해 소개한 적이 있었어요. 웹 사이트를 개발한 이후 마지막 단계는 배포 및 운영 단계입니다. 그럴 때는 카페 24나 AWS 등의 클라우드 서비스를 이용해 웹 서비스를 배포하는 것이 일반적이에요. 그런데, 일반적으로 이러한 '호스팅 서비스'는 우리의 로컬 컴퓨터와는 차이점이 존재해요. 특정한 서버 환경에 우리가 만든 웹 서비스를 맞추어서 배포해야 하므로 갖가지 설정이 필요하죠. 초기 상태에서 시작한다면 JVM을 설치해야 되고, 톰캣(Tomcat)도 필요하고, 등 할 게 많아요. 또 같은 리눅스라고 해서 괜찮은 것도 아니고, 리눅스 버전에 따라서도 설치 방법이 다르답니다.



  그래서 등장한 것이 바로 '컨테이너(Container)'의 개념이에요. 도커를 설치하면, 컨테이너에 '이미지(Image)'를 담아서 구동시키는 방식으로 손쉽게 배포할 수 있어요. 이러한 컨테이너를 어떻게 만들고, 활용할 지에 대해서는 미리 도커 소프트웨어가 정의를 해 놓고 있어서 도커를 사용하는 우리들은 단순히 이미 배포된 소프트웨어 이미지를 도커를 통해 컨테이너에 올리면 되요. 다시 말해서 우리는 도커만 설치를 하면 나머지는 알아서 설정이 이루어지는 겁니다. JVM, 톰캣 등을 따로따로 설치할 필요가 없으며 도커 하나만 있으면 이 친구가 알아서 해결해줘요.



  나중에 자세히 알아보겠지만, 위 그림과 같이 도커 파일(Docker File)이라는 것을 만들어서 '나는 어떠한 소프트웨어를 컨테이너에 담아서 구동시킬 것이다.'라는 것만 정확히 명시해주고 빌드(Build)를 해주면, 알아서 도커 이미지가 그에 맞게 생성이 됩니다. 그래서 그 이미지를 구동시키면 순식간에(웹 서버도 몇 초만에 뚝딱!) 도커 컨테이너 위에서 실행이 됩니다.


  물론 도커 이전에도 이러한 컨테이너(Container) 기반의 기술이 다수 존재했었어요. 하지만 도커의 고유한 창의적인 기능들과 편리함 때문에 현재 도커가 패키징, 배포 시장을 잠식하고 있는 상태랍니다. 도커는 말씀 드렸듯이 컨테이너(Container) 형태로 동작하는데, 기존에 VM(Virtual Machine) 서비스를 이용해 본 적이 있으신 분들이라면 다소 헷갈릴 수 있어요. 그래서 VM과 도커가 어떻게 다른 기술인지 확실히 이해할 필요가 있답니다.


※ VM(Virtual Machine)과 컨테이너(Container)는 무엇이 다를까 ※


  기본적으로 기존에 우리가 많이 사용하던 VM(가상 머신)과 컨테이너는 큰 차이가 있습니다. 가상 머신은 가상화 기능을 사용해 Guest OS라는 것을 만들어냅니다. 예를 들어 윈도우(Windows) 운영체제를 사용하는 사람이 칼리 리눅스를 새롭게 가상 머신 위에서 구동시킨다면, 윈도우는 Host OS이고 칼리 리눅스는 Guest OS입니다. 다시 말해 Guest OS와 Host OS는 사실상 완전히 별개로 존재할 수 있다는 점에서 서로 의존적이지 않습니다. 대신에 Guest OS의 I/O 기능이 사실상 Host OS를 거쳐서 이루어지기 때문에 속도가 느리다는 단점이 있습니다. 뿐만 아니라 Guest OS 자체가 완전히 새로운 운영체제로서 존재해야되기 때문에 아무리 가벼운 OS를 설치하려고 해도, 용량이 큽니다.



  반면에 컨테이너(Container)는 가상 머신 대신에 도커 엔진(Docker Engine) 위에서 동작한다는 특징이 있어요. 이렇게 해주면 별도의 Guest OS가 사용되지 않아서 성능적으로 매우 개선됩니다. 메모리 용량도 적게 차지하고요. 다만 기본적으로 사용하고 있는 운영체제와 도커의 컨테이너(Container)에 의존성이 존재합니다. 이로 인해 각종 보안 문제로 공격을 받은 적이 있었구요. 기본적으로 윈도우(Windows) 운영체제를 사용하고 있는 컴퓨터는, 도커 엔진 위에 올라가는 컨테이너도 윈도우 컨테이너(Windows Container)여야 합니다. (다행히도 최근에는 도커와 윈도우의 호환성이 매우 높아지고 있어서 사실상 리눅스 컨테이너와 윈도우 컨테이너의 구분이 모호해지고 있습니다.)


  도커는 Container라서 VM에 비해 이미지 파일의 크기가 작아 빠르게 이미지를 만들고 실행할 수 있다는 특징이 있습니다. 예를 들어 대표적인 리눅스 운영체제 배포판 중에서 알파인(Alpine)은 최소한의 기능만 들어가 있어서 5MB 가량으로 작게 구성되어 있습니다. 가상 머신 기술을 이용하는 경우 아무리 운영체제를 가볍게 설치하려고 해도 최소한 기가 바이트 단위인데, 이렇게 Container를 이용하면 그 크기가 200MB 전후로 줄어들 수 있어서 가히 초경량 배포 도구라고 할 수 있답니다.


※ Solomon Hykes의 도커(Docker) ※


  도커의 시작을 알린 사람은 Solomon Hykes로 2013년 PyCon에서 '리눅스 컨테이너의 미래'라는 제목으로 도커에 대해서 발표했습니다. 발표 내용은 유튜브(YouTube)에도 올라와 있어서 손쉽게 확인할 수 있습니다. (https://www.youtube.com/watch?v=wW9CAH9nSLs)



  보시면 솔로몬 씨가 'Hello World'라는 문장을 띄운 것을 알 수 있습니다. 도대체 Hello World를 띄운 것이 뭐가 그렇게 대단하다고 사람들이 이렇게 도커에 열광하는 걸까요? 그것은 'Hello World'가 새로운 운영체제 위에서 출력이 된 것이기 때문입니다. 이것은 엄청난 발전입니다. 아니, 몇 초 만에 별도의 운영체제를 생성한 뒤에 'Hello World'를 출력한 것이니까요. VM을 사용해보신 분들이라면 이게 얼마나 편리한 것인지 감이 오실 겁니다.


  리눅스 컨테이너(Linux Container)는 오래 전부터 개발되던 기술입니다. 그 역사만 10년이 넘었습니다. 하지만 리눅스 컨테이너를 개발하거나 활용하는 기술은 복잡하고 까다로웠습니다. 그래서 다양한 회사가 컨테이너 기술을 사용하고 있음에도 불구하고 일반 개발자들 사이까지 널리 퍼지지는 못했습니다. 그러한 배경에서 도커가 등장함에 따라 그 방향이 바뀌게 됩니다. 리눅스 컨테이너 기술을 기반으로 하되, 매우 편리한 인터페이스 및 명령어를 가지고 있어서 컨테이너 기술을 잘 모르는 개발자들도 손쉽게 도커를 이용해 컨테이너를 띄워볼 수 있게 된 것입니다.


※ 도커는 어떻게 만들어졌을까? ※


  도커는 기본적으로 도커 엔진(Docker Engine)에 의해 동작합니다. 도커 엔진의 핵심 로직은 Google의 Go 언어로 개발이 되어 있습니다. Go로 개발된 도커 엔진은 기존의 C언어로 개발된 모듈보다 더욱 빠르게 동작합니다. Go 프로그래밍 언어는 기본적으로 포인터 등의 기능을 지원하며 Garbage Collector나 클래스 등의 기능까지 지원하는 언어입니다. 최근에는 깃(Git) 서버도 Go 언어로 개발이 되고 있습니다. 실제로 그렇게 Go로 개발한 서버 모듈이 빠르게 동작하죠. Go로 개발된 소프트웨어 중에서 가장 잘 나가고 있는 것이 바로 도커(Docker)인 것입니다.


※ 도커 패러다임 ※


  도커는 변경 불가능한 인프라(Immutable Infrastructure)를 주요 패러다임으로 상정하고 있습니다. 기본적으로 특정한 소프트웨어가 자주 수정되는 경우 서비스 안정성에 여러 가지 문제가 발생할 수 있습니다. 특히 언제 어떠한 부분이 변경되었는지 등의 이력 관리를 제대로 하는 것이 매우 중요합니다. 그러한 배경에서 아예 변경 자체를 못하도록 하자고 해서 '변경 불가능한 인프라'의 개념이 나타나게 되었는데, 이것은 서버를 구축한 이후에는 변경이나 업데이트를 할 수 없도록 하는 것입니다.


  그렇다면 서버에 문제가 생겨서 업데이트를 해야 되는 경우는 어떻게 할까요? 그냥 삭제해버리는 겁니다!


  서버 패치 등은 지속적으로 이루어져야 하는데 '어떻게 한 번 서버를 구축하고 나서 업데이트를 안 할 수 있을까요?' 사실 이는 처음 들었을 때 이해하기 힘들 수도 있는데요. 도커를 쓰다보면 서버 자체를 들었다 놨다 하는 것이 익숙해지실 겁니다. 다시 말해, 서버를 업데이트를 해야 할 때는 새로운 도커 이미지 자체를 업데이트 해서 그냥 컨테이너에 올리는 겁니다. 기존에 돌아가던 컨테이너는 완전히 '제거' 해버리구요.


  도커에서는 그냥 이미지를 도커 위에 올리는 것 만으로도 배포가 끝나버립니다. '변경 불가능한(Immutable)' 이라는 의미는 그 자체로 '상태가 없는(Stateless)', '확장 가능한(Scalable)' 형태입니다. 도커로 돌아가는 소프트웨어 자체는 어떠한 데이터도 가지고 있으면 안 되고, 임시 파일 정도만 가지고 있는 상태에서 돌아가야 합니다. 사용자 계정 정보와 같은 실질적인 데이터들은 외부 스토리지로 빼 놓아야 하는 겁니다. 최근에 자주 언급되고 있는 마이크로 서비스(Micro Service)의 특징과 매우 닮아있습니다.


※ 리눅스 컨테이너 ※


  도커는 말했듯이 대표적인 컨테이너 기술입니다. 일반적으로 리눅스 컨테이너(LXC)리눅스상에서 여러 개의 격리된 리눅스 시스템을 동작시키기 위한 운영체제 단의 가상화 기술을 의미합니다. Warden, Libvirt가 그 대표적인 예시입니다. 리눅스 커널(Kernel) 위에 Libvirt가 돌아가며 그 위에 컨테이너가 올라가는 방식이지요. 그래서 이러한 LXC 기술에 대한 이해가 높으신 분은 사실 도커와 같은 기술을 자체적으로 개발할 수도 있는 겁니다. 구글이 발표한 자료에 따르면 매주 수십억 개의 컨테이너가 전 세계적으로 구동된다고 합니다. 또한 구글이 운영하는 모든 서비스는 컨테이너를 기반으로 돌아갑니다. 왜냐구요? 성능이 좋으니까요. 구글은 도커 이전에도 이미 이러한 리눅스 컨테이너 기술을 사용하고 있었고, 최근에는 도커 기반의 기술을 많이 활용하고 있답니다.


  앞에서도 언급했지만 도커 이전의 LXC 기술들은 기본적으로 오래 전부터 사용되고 있었으나 설정이 매우 복잡하고, 사용하기 어려워 널리 알려지지 않았던 것입니다. 도커가 출시되면서 10분도 채 소요되지 않는 시간에 대부분의 서비스를 구동시킬 수 있어서 실질적으로 대부분의 개발자가 이용할 수 있는 레벨까지 편리성을 제공하게 된 것입니다.

728x90
반응형