도커란 무엇인가

Docker

Go언어로 작성된 리눅스 컨테이너을 기반으로 하는 오픈소스 가상화 플랫폼이다.

Container?

컨테이너는 운영체제 수준의 가상화 기술로, 호스트 OS의 커널을 공유하면서도 서로 격리된 프로세스 환경을 제공한다.

전통적인 가상화 방식인 VM(Virtual Machine)은 아래와 같은 구조다:

  • Host OS 위에 Hypervisor를 설치
  • Hypervisor 위에 Guest OS를 올려서 실행

이 방식은 완전한 분리라는 장점이 있지만, Guest OS 자체가 무겁고 리소스를 많이 차지하는 단점이 있다.

컨테이너 가상화의 구조는 다음과 같다:

  • Host OS위에 Container Enginer(e.g. Docker)를 설치
  • OS 커널을 공유하면서 컨테이너 단위로 격리된 환경 구성

하나의 OS 자원을 효율적으로 나누어 사용하는 구조라, 훨씬 가볍고 빠르며 리소스 낭비가 적다.

그래서 왜 이걸 서버 운영에 사용하는데?

  1. 실행 환경
    통일개발 환경과 실제 운영 환경은 대부분 분리되어 있는데, 이 과정에서 종종 의존성 문제 등으로 디버깅에 많은 시간이 소요되나. 하지만, 도커를 사용하면 개발 단계에서 만든 이미지를 그대로 배포 가능하므로 운영 환경과의 차이를 최소화 할 수 있다. (it works on my machine)
  2. 가볍다
    별도의 운영체제를 포함하지 않고, 어플리케이션과 필수 라이브러리만 포함하므로 이미지 용량이 작고, 실행 속도가 빠르다.
  3. 리소스 효율
    앞서 말했듯, 컨테이너는 필요한 자원만 사용하기 때문에, 동일한 자원으로 더 많은 인스턴스를 운용할 수 있다. 또한, 각 컨테이너의 리소스를 제한하거나 모니터링 하는 등의 기능도 제공하여 서버의 자원을 좀 더 유연하고 효율적으로 분배할 수 있다.

docker image의 구조와 layer

Docker image는 단순한 파일이 아니라, 여러 개의 layer로 이루어진 구조임.

Dockerfile에서 작성한 각 명령어(e.g. RUN, COPY, ADD)는 하나의 레이어를 생성하고, 생성된 레이어들은 읽기 전용으로, 이전의 레이어를 기반으로 쌓여있음.

FROM ubuntu:20.04 # Layer 1
RUN apt update # Layer 2
RUN apt install -y curl # Layer 3
COPY . /app # Layer 4

그래서 왜 Layer로 분리시켜놓는데?

  1. 캐시 재사용같은 Dockerfile을 다시 빌드하면, 변경되지 않은 명령어들은 이전 빌드의 레이어를 캐시로 사용함. → 빠른 빌드
  2. 저장 공간 절약같은 레이어를 여러 이미지에서 공유 가능함.
  3. 네트워크 전송 최적화이미지를 push/pull 할 때도 기존에 있는 레이어는 다시 받을 필요 없음.

Docker Layer 최적화

  • 불필요한 파일은 COPY 하지 말기
  • 이미지 사이즈 줄이려면 alpine 같은 경량 베이스 이미지 사용하기
  • 자주 변하지 않는 내용들은 위로 올리기
  • 가능한 한 RUN 명령어를 하나로 묶어서 레이어 수 줄이기
# 비효율적인 방법
RUN apt update
RUN apt install -y curl

# 더 나은 방법
RUN apt update && apt install -y curl

Docker Compose

여러 개의 컨테이너를 하나의 설정 파일로 정의하고, 한 번에 실행할 수 있도록 도와주는 도구

왜 Docker Compose를 사용해야 되는데?

Docker만으로도 멀티 컨테이너 환경을 만들 수 있지만, 서비스가 복잡해질수록 모든 설정을 관리하는데 한계가 있음. 마이크로서비스 환경 또는 다중 컨테이너 환경에서 필수적인 요소.

예를 들어, 웹 서비스를 배포한다고 한다면, 보통 하나의 컨테이너로 끝나지 않음. 웹 서비스를 만든다면,

  • React + Nginx (FE)
  • Node.js (BE)
  • PostgreSQL (DB)

이런 식으로 분리가 가능할 것이고, 각각을 따로 Dockerfile로 작성하고, 연결한다면, 유지보수가 어려움. 그렇기 때문에, 이런식으로 여러 컨테이너들을 하나의 yml 파일로 관리할 수 있게 해줌.

구성

  • version
    • Docker Compose 파일의 버전을 지정함. 일반적으로 가장 최신 버전인 3.8을 사용함
  • services
    • 실제로 실행할 컨테이너들을 정의함. Dockerfile이랑 비슷함.
  • volumes
    • 데이터를 컨테이너 외부에 저장하고 싶을 때 사용
  • networks
    • 컨테이너 간 통신을 위한 네트워크 설정. 같은 네트워크에 있는 컨테이너는 컨테이너 이름으로 서로 접근이 가능함.