Docker?

리눅스 컨테이너에 여러 기능을 추가함으로써 어플리케이션을 컨테이너로서 좀 더 쉽게 사용할 수 있게 만들어진 오픈소스 프로젝트.

Go 언어로 작성돼 있으며, 기존에 쓰이던 가상화 방법인 가상 머신과 달리 도커 컨테이너는 성능의 손실이 거의 없어서 차세대 클라우드 인프라 솔루션으로서 많은 개발자들에게 주목 받고 있다.

도커와 관련된 프로젝트는 Docker compose, Private Registry, Docker Hub, Docker for Desktop 등 여러 가지가 있지만 일반적으로 도커라고 하면 코거 엔진 혹은 도커에 관련된 모든 프로젝트를 의미한다.

Docker Engine?

도커 엔진은 컨테이너를 생성하고 관리하는 주체로서 도커엔진 자체로도 컨테이너를 제어할 수 있고 다양한 기능을 제공하는 도커의 주 프로젝트이다.

도커 생태계의 여러 프로젝트는 도커 엔진을 좀 더 효율적으로 사용하기 위한 것!

핵심은 도커 엔진이기 때문에 다른 프로젝트들을 능숙하게 다루기 위해서는 도커엔진을 우선적으로 잘 알아야한다.

가상 머신과 도커 컨테이너

기존의 가상화 기술은 하이퍼바이저를 이용해 여러 개의 운영체제를 하나의 호스트에서 생성해 사용하는 방식이였다. 이러한 여러개의 OS는 가상 머신이라는 단위로 구별된다.

하이퍼바이저에 의해 생성되고 관리되는 OS는 Guest OS라고 하며, 각 Guest OS는 다른 Guest OS와는 완전히 독립된 공간과 시스템 자원을 할당받아 사용한다.

이러한 방법은 대표적으로 VirtualBox, VMWare가 있다.

가상 머신의 구조 [https://www.docker.com/resources/what-container](https://www.docker.com/resources/what-container)

가상 머신의 구조 https://www.docker.com/resources/what-container

각종 시스템 자원을 가상화하고 독립된 공간을 생성하는 작업은 하이퍼바이저를 반드시 거치기 때문에 일반 호스트에 비해 성능 손실이 발생한다.. + 가상 머신은 Guest OS를 사용하기 위한 라이브러리, 커널 등을 전부 포함하기 때문에 배포하기 위해 이미지를 만들면 크기가 매우 커진다.

⇒ 완벽한 OS를 생성할 수 있는 장점, but 일반 호스트에 비해 성능 손실과 배포를 위한 크기가 부담스러움.

도커 컨테이너의 구조 [https://www.docker.com/resources/what-container](https://www.docker.com/resources/what-container)

도커 컨테이너의 구조 https://www.docker.com/resources/what-container

반면, 도커 컨테이너는 가상화된 공간을 생성하기 위해 리눅스의 자체 기능인 chroot, namespace, cgroup을 사용함으로써 프로세스 단위의 격리 환경을 만들기 때문에 성능 손실이 거의 없다.

컨테이너에 필요한 커널은 호스트의 커널을 공유해 사용하고, 컨테이너 안의 어플리케이션을 구동하는데 필요한 라이브러리 및 실행파일에만 존재하기 때문에 컨테이너를 이미지로 만들었을 때 이미지의 용량 또한 가상 머신에 비해 대폭 줄어든다.

⇒ 컨테이너를 이미지로 만들어 배포하는 시간이 가상 머신에 비해 빠르고, 성능 손실도 없다는 장점.

Docker를 사용해야하는 이유?

컨테이너는 OpenVZ, LXC, cri-o 등 몇가지가 존재하지만 도커가 컨테이너 생태계에서 표준으로 사용되고 있다.

따라서 쿠버네티스, 메소스와 같은 오픈소스 프로젝트에서도 도커를 기준으로 개발되고 있고, 많은 회사들이 서비스 개발 및 운영환경에서 도커 컨테이너를 도입하고 있다. 그렇다면 왜 그렇게 많은 회사에서 도커를 선택했을까?

1. 어플리케이션의 개발과 배포가 편리해짐

서버를 부팅할 때 실행되는 OS를 일반적으로 Host OS라고 한다. 도커 컨테이너는 호스트 OS 위에서 실행되는 격리된 공간이기 때문에 컨테이너 자체에 특별한 권한을 주지 않으면 컨테이너 내부에서 어떤 S/W를 설치하고 실행해도 Host OS에는 영향을 끼치지 않는다. ( 독립된 개발 환경을 보장 )

컨테이너 내부에서 여러 작업을 마치고 이를 운영 환경에 배포하려고 하면, 해당 컨테이너를 Docker Image라고 하는 일종의 패키지로 만들어 운영 서버에 전달하기만 하면 된다.

컨테이너에서 사용되던 운영서버에서 새롭게 패키지를 설치할 필요도 없으며, 각종 라이브러리 설치 등으로 인한 의존성을 걱정할 필요도 없다. 서비스를 개발했을때 사용했던 환경을 다른 서버에서도 컨테이너로서 똑같이 복제할 수 있기 때문에 개발/운영 환경의 통합이 가능해진다.

도커 이미지는 가상 머신의 이미지와 다르게 커널을 포함하지 않으므로 이미지 크기가 크지 않다. 그리고 도커 이미지 내용을 레이어 단위로 구성하기 때문에 중복 되는 레이어를 재사용할 수 있어 앱의 배포 속도가 매우 빠르다는 장점이 있다.

2. 독립성과 확장성

S/W의 여러 모듈이 상호작용하는 로직을 하나의 프로그램 내에서 구동시키는 방식을 Monolith 어플리케이션이라고 한다. 소규모 서비스에서는 괜찮지만 서비스의 기능이 복잡해지고 거대해질수록 S/W 자체의 확장성과 유연성이 줄어들게 된다.

이런 Monolith를 대체하기 위해 새롭게 Microservices 구조가 등장하였다.

마이크로서비스 구조는 여러 모듈을 독립된 형태로 구성하기 때문에 언어에 종속되지 않고 변화에 빠르게 대응 할 수 있으며, 각 모듈의 관리가 쉬어진다는 장점이 있다.

컨테이너는 수 초 내로 생성, 시작이 가능할 뿐만 아니라 여러 모듈에게 독립된 환경을 동시에 제공할 수 있기 때문에 마이크로서비스에서 가장 많이 사용되고 있는 가상화 기술이다.

예시로 웹 서비스는 DB 컨테이너와 웹 서버 컨테이너로 분리 할 수 있고, 웹 서비스에 부하가 발생할 시 마이크로서비스 구조의 웹 서버 컨테이너만 동적으로 늘려서 부하를 분산할 수 있다. 또한 웹 서버와 DB의 이미지 버전을 독립적으로 관리하기 때문에 유지 보수도 용이해진다.

이와 같은 컨테이너 기반의 마이크로서비스는 개발자가 그 구조를 직접 구현하기보다는 도커 스웜모드, 쿠버네티스 등의 컨테이너 오케스트레이션 플랫폼을 통해 사용하는 것이 일반적이다.

본 포스트는 용찬호님의 Getting Started with Docker/Kubernetes를 참고하여 작성하였습니다.