시작하기 전에 이 글을 한 번 확인 부탁드립니다.
도커(Docker)
란 리눅스 컨테이너에 여러 기능을 추가하여 애플리케이션을 컨테이너로서 좀 더 쉽게 사용할 수 있도록 만들어진 오픈소스이다.
Go언어
로 작성되어 있으며, 2013년 3월 첫 릴리즈가 발표된 이후 지금까지 꾸준히 개발중이며, 기존에 쓰이던 VM(Virtual Machine)
과는 달리, 성능의 손실이 거의 없어 차세대 클라우드 인프라 솔루션으로 많은 개발자에게 주목을 받는다.
도커와 관련된 프로젝트로는 도커 컴포즈(Docker Compose)
, 레지스트리(Private Registry)
, 도커 허브(Docker Hub)
, Docker for Desktop
등 여러가지가 존재한다.
일반적으로 도커라고 하면 도커 엔진(Docker Engine)
혹은 도커에 관련된 모든 프로젝트를 의미한다.
보통 도커 엔진이라는 의미로 많이 쓰이는데, 컨테이너를 생성하고 관리하는 주체로서 이 자체로도 컨테이너를 제어할 수 있고 다양한 기능을 제공하는 것이 도커의 주 프로젝트이다.
도커 엔진
은 여러 프로젝트틀을 좀 더 효율적으로 사용하기 위한 핵심이다.
도커 엔진을 사용하는 방법을 익히는 것은 도커와 관련된 모든 프로젝트를 능숙히 다루기 위한 첫걸음 이라고 봐도 무방하다.
기존의 가상화 기술은 하이퍼바이저
를 이용해 여러 개의 운영 체제를 하나의 호스트
에서 생성해 사용하는 방식
이러한 여러 운영체제는 VM이라는 단위로 구분되고, 각 VM에는 우분투(Ubuntu)
, Cent OS
등 여러 운영체제가 설치되어 사용된다.
하이퍼바이저에 의해 생성되고 관리되는 운영체제는 게스트 운영체제(Guest OS)
라고 하며, 각 게스트 운영체제는 다른 게스트 운영체제와는 완전히 독립된 공간와 시스템 자원을 할당받아 사용한다.
이러한 가상화 방식을 사용할 수 있는 대표적인 가상화 툴로 VirtualBox
, VMware
등이 존재한다.
Infrastructure는 Server로 생각하면 될 것 같다.
왼쪽이 가상 머신, 오른쪽이 도커 컨테이너 구조이다.
출처 : Docker와 VM
각종 시스템 자원을 가상화하고 독립된 공간에 생성하는 작업은 하이퍼바이저를 반드시 거치기 때문에 일반 호스트에 비해 성능의 손실이 발생한다.
그뿐만 아니라 VM은 게스트 운영체제를 사용하기 위한 라이브러리, 커널 등을 전부 포함하기 때문에 가상 머신을 배포하기 위한 이미지로 만들었을 때 이미지의 크기 또한 커진다.
VM은 완벽한 운영체제를 생성할 수 있다는 장점은 있지만 일반 호스트에 비해 성능 손실이 있으며, 수 기가바이트에 달하는 가상 머신 이미지를 애플리케이션으로 배포하기는 부담스럽다는 단점이 있다.
이에 비해 도커 컨테이너는 가상화된 공간을 생성하기 때문에 리눅스의 자체 기능인 chroot
, 네임스페이스(namespace)
, cgroup
을 사용함으로써 프로세스 단위의 격리 환경을 만들어 성능 손실이 거의 없다.
컨테이너에 필요한 커널은 호스트의 커널을 공유해 사용하고, 컨테이너 안에는 애플리케이션을 구동하는 데 필요한 라이브러리 및 실행 파일만 존재하기 때문에 컨테이너를 이미지로 만들었을 때 이미지의 용량 또한 VM에 비해 대폭 줄어든다.
따라서 컨테이너를 이미지로 만들어 배포하는 시간이 VM에 비해 빠르며, 가상화된 공간을 사용할 때의 성능 손실도 거의 없다는 장점이 있다.
컨테이너는 OpenVZ
, LXC
, cri-o
등 몇 가지 존재하지만, 특히 그중에서도 도커는 컨테이너 생태계에서 사실상 표준으로서 사용되고 있다.
쿠버네티스, 메소스와 같은 오픈소스로 프로젝트에서도 도커를 기준으로 개발되고 있으며 이에 발맞춰 점점 더 많은 회사들이 서비스 개발 및 운영 환경에 도커 컨테이너를 도입중이다.
회사에서 도커를 선택한 이유와 도커를 시작해야 하는 이유는 다음과 같다.
서버를 부팅할 때 실행되는 운영체제를 일반적으로 호스트 OS
라고 부르며, 도커 컨테이너는 호스트 OS 위에서 실행되는 격리된 공간이다.
컨테이너 자체에 특별한 권한을 주지 않는 한 컨테이너 내부에서 수많은 소프트웨어를 설치하고 설정 파일을 수정해도 호스트 OS에는 영향을 끼치지 않는다.
즉, 독립된 개발 환경을 보장받을 수 있다는 의미가 된다.
컨테이너 내부에서 여러 작업을 마친 뒤 이를 운영 환경에 배포하려고 한다면, 해당 컨테이너를 도커 이미지
라고 하는 일종의 패키지로 만들어 운영 서버에 전달하기만 하면 된다.
컨테이너에서 사용되던 운영 서버에서 새롭게 패키지를 설치할 필요도 없으며, 각종 라이브러리 설치 등으로 인한 의존성을 걱정할 필요도 없다.
서버스를 개발했을 때 사용했던 환경은 다른 서버에서도 컨테이너로서 똑같이 복제할 수 있기 때문에 개발/운영
환경의 통합이 가능해진다.
게다가 도커 이미지는 VM의 이미지와 달리 커널을 포함하고 있지 않기 때문에 이미지 크기가 그다지 크지 않는다.
도커는 이미지 내용을 레이어 단위로 구성하며, 중복되는 레이어를 재사용할 수 있어서 애플리케이션의 배포 속도가 매우 빨라진다는 장점이 있다.
소프트웨어의 여러 모듈이 상호 작용하는 로직을 하나의 프로그램 내에서 구동시키는 방식을 모놀리스(Monolith)
애플리케이션이라고 한다.
소규모 서비스에는 이 방식이 어울릴지도 모르지만, 서비스의 기능이 복잡해지고 거대해질수록 소프트웨어 자체의 확장성과 유연성이 줄어든다는 단점이 있다.
이러한 모놀리스 방식을 대체하기 위해 최근 새롭게 떠오른 개념이 바로 마이크로서비스(Microservices)
구조이다.
마이크로서비스 구조는 여러 모듈의 독립된 형태로 구성하기 때문에 언어에 종속되지 않고 변화에 빠르게 대응할 수 있으며, 각 모듈의 관리가 쉬워진다는 장점이 있다.
컨테이너는 수 초 내로 생성, 시작이 가능할 뿐만 아니라 여러 모듈에게 독립된 환경을 동시에 제공할 수 있기 때문에 마이크로서비스 구조에서 가장 많이 사용되고 있는 가상화 기술이다.
예를 들어 웹 서비스는 데이터베이스 컨테이너와 웹 서버 컨테이너로 분리할 수 있고, 웹 서비스에 부하가 발생할 시 마이크로서비스 구조의 웹 서버 컨테이너만을 동적으로 늘려서 부하를 분산할 수 있다.
또한 웹 서버와 데이터베이스의 이미지 버전을 독립적으로 관리하기 때문에 유지 보수도 용이해진다.
이와 같은 컨테이너 기반의 마이크로서비스는 개발자가 그 구조를 직접 구현하기 보다는 도커 스웜 모드
, 쿠버네티스
등의 컨테이너 오케스트레이션 플랫폼을 통해서 사용하는 것이 일반적이다.
이 외에도 도커 컨테이너를 사용하는 이유는 프로젝트 자체의 성숙도나 확장성, 편의성 등이 있지만, 이를 이해하기 위해서는 도커를 직접 사용해보는 것이 가장 좋다.
- 애플리케이션을 컨테이너로서 좀 더 쉽게 사용할 수 있도록 만들어진 오픈소스
- Go언어로 작성돼었으며, 2013년 3월 첫 릴리즈 이후 지금까지 꾸준히 개발중
- 도커 엔진은 여러 프로젝트를 좀 더 효율적으로 하기 위한 핵심
- 기존의 가상화 기술은 하이퍼바이저를 사용해 여러 운영체제를 하나의 호스트에서 생성해 사용하는 방식
- 각종 시스템 자원을 가상화하고 독립된 공간에 생성하는 작업은 하이퍼바이저를 반드시 거치게 되어있어서 일반 호스트에 비해 성능 손실이 발생
- 뿐만 아니라 VM을 배포하기 위한 이미지로 만들었을 때의 이미지 크기도 커지게 됨
- 도커는 리눅스 자체의 기능을 사용함으로써 프로세스 단위의 격리 환경을 만들어 성능 손실이 거의 없음
- 호스트의 커널을 공유해 사용하고, 구동하는 데 필요한 라이브러리 및 실행파일만 존재하므로 이미지로 만들었을 때 용량 또한 VM에 비해 줄어듦
- 컨테이너 생태계에서 사실상 표준으로 쓰이는 추세
- 쿠버네티스, 메소스와 같은 오픈소스로 프로젝트에서 도커를 기준으로 개발중
- 이에 따라 더 많은 회사들이 서비스 개발 및 운영 환경에 도커를 도입중
- 도커 컨테이너는 호스트 OS 위에서 실행되는 격리된 공간으로 여러 소프트웨어를 설치하거나 수정해도 호스트 OS에 영향을 주지 않음
- 운영 환경에 배포하기 위해서 도커 이미지를 생성하여 운영 서버에 전달하는 것으로 끝나며, 개발/운영 환경 통합이 가능
- 도커 이미지는 VM의 이미지와는 달리 커널을 포함하지 않아 용량이 크지 않음
- 이미지의 내용이 레이어 단위로 구성되어 중복되는 레이어를 재사용할 수 있어 애플리케이션의 배포 속도가 빨라짐
- 상호 작용하는 소포트웨어의 여러 모듈을 하나의 프로그램 내에서 구동하는 방식을 모놀리스 애플리케이션이라고 하는데, 이는 서비스의 기능이 복잡해지고 거대해질수록 소프트웨어의 확장성과 유연성이 줄어든다는 단점이 존재
- 이러한 방식을 대체하기 위한 방식으로 마이크로서비스 구조가 떠오름
- 마이크로서비스 구조는 여러 모듈의 독립된 형태로 구성하기에 언어에 종속되지 않고 변화에 빠르게 적응할 수 있으며 관리가 쉬워짐
- 도커 컨테이너가 이러한 구조로 되어 있으며, 도커 스웜이나 쿠버네티스 등의 컨테이너 오케스트레이션 플랫폼을 제공하여 간편함