서버의 성능을 적극적으로 활용하기 위해 하나의 서버에 여러 서비스를 구동하고 싶다. 하지만 기존의 프로젝트와 새로운 프로젝트가 서로 충돌할 우려가 있다. 이를 위해 서버의 성능을 나눠서 사용하는 가상화가 등장했다!
가상화를 통해 하나의 서버 자원을 나눠서 성능을 분산시키고, 분산된 서버들은 각각 독립적으로 수행할 수 있다. 또한, 여러 서비스들에게 유연하게 서버의 자원을 할당해줄 수 있다.
서버 가상화란 하나의 물리적 서버 호스트에서 여러 개의 서버 운영 체제를 게스트로 실행할 수 있게 해주는 소프트웨어 아키텍쳐이다.
하이퍼 바이저는 OS들에게 자원을 나누어주며 조율하고, OS들의 커널을 번역해서 하드웨어에게 전달하는 역할을 수행한다.
이러한 하이퍼바이저의 도움을 받아 여러 개의 운영체제를 하나의 호스트 OS에서 사용할 수 있게 되었다. 이렇게 생성된 여러 개의 운영체제는 가상 머신 단위로 구별된다.
하이퍼바이저에 의해 생성되고 관리되는 운영체제를 게스트 운영체제라고 부르며, 각각 독립적인 공간과 시스템 자원을 할당받아 사용한다.
가상화는 위와 같은 장점이 있지만 단점 또한 존재한다.
먼저 가상화 작업은 항상 하이퍼바이저를 거쳐야 하기 때문에 일반 호스트에 비해 성능 손실이 발생한다. 또한, 게스트 운영체제를 사용하기 위한 라이브러리, 커널 등을 전부 포함하기 때문에 용량이 커진다.
컨테이너는 기존의 시스템에 존재하는 프로세스를 해당 시스템에서 격리하여, 독자적인 시스템 환경을 구축하는 기술이다. 리눅스 커널이 제공하는 기능으로 이를 실현하였다.
컨테이너 안에는 애플리케이션을 구동하기 위한 라이브러리 및 실행 파일만 존재한다. 따라서 이미지로 만들었을 때 가상 머신에 비해 적은 용량이 요구되고, 이미지를 만들어 배포하는 시간도 빠르다.
Hypervisor를 이용해 가상화를 하지 않기 때문에, Hypervisor가 커널동작을 해석하는데 필요한 오버헤드가 발생하지 않아 빠르다는 장점도 있다.
도커 엔진이란 유저가 컨테이너를 쉽게 사용할 수 있게 하는 주체이다.
도커 엔진은 컨테이너의 라이프 사이클과 컨테이너 생성을 위한 이미지 관리, 컨테이너의 데이터 저장소 역할을 하는 볼륨의 관리, 컨테이너의 접속을 관리하기 위한 네트워크 관리 등의 기능을 제공한다.
도커는 위와 같이 클라이언트-서버 구조로 이루어져 있다. 사용자가 도커 클라이언트로 명령어를 보내면, 도커 클라이언트는 컨테이너를 빌드, 실행 및 배포하는 무거운 작업을 수행 하는 도커 데몬(dockerd)과 통신한다.
필요로 하는 컨테이너가 많아져서 서버를 증설해야 하는 경우가 발생할 수 있다. 이때 아래와 같은 문제들을 도커 스웜이 해결해준다.
도커 스웜은 여러 호스트에서 컨테이너들을 실행하고 연결할 수 있게 해준다.
여러 호스트에서 돌아가는 컨테이너들을 관리하고, 스케일링을 하거나, 고장이 있을 때 자동으로 새로운 컨테이너를 실행시키거나, 컨테이너 간의 네트워킹 로드밸런싱을 지원하는 등의 일을 한다.
도커 컴포즈는 여러 개의 컨테이너를 하나의 서비스로 정의하도록 도와준다.
docker-compose.yml
version: "3.9"
services:
mysql:
image: mysql:8.0.31
...
springboot:
image: spring-service:0.0
...
도커 컴포즈는 위와 같이 컨테이너 설정이 정의된 yml 파일을 읽고, 도커 엔진을 통해 컨테이너를 생성한다.
직접 네트워크를 생성하고, mysql과 springboot 컨테이너를 생성하는 방법도 있지만 번거롭기 때문에 도커 컴포즈를 사용한다.