도커(Docker)란?

송선권·2024년 7월 25일

인프라 스터디

목록 보기
3/7
post-thumbnail

주제

도커의 개념과 구조에 대해 학습한다.

가상화 기술

가상화 기술이 발전하기 전까지는 하나의 서버에 하나의 애플리케이션만 구동할 수 있었다. 안정적이었지만 그만큼 남는 서버 자원이 방치되어 비효율적이었다. 이를 개선하기 위해 등장한 것이 가상화 기술이다.

VM (Virtual Machine)

가상화 기술은 물리적 하드웨어 자원을 논리적 자원으로 제공하여 각 프로세스에 할당한다. 가상화 기술 중에서도 하이퍼바이저 기반 가상화가 가장 많이 이용되었다. 하이퍼바이저는 논리적으로 분할된 공간에 VM이라는 독립된 가상 환경을 만들고 호스트 시스템에서 VM에 설치된 게스트 OS를 구동 및 모니터링하는 역할을 한다.

이 기술을 사용하면 이전보다 서버 자원을 효율적으로 사용할 수 있지만 각 프로세스를 구동하기 위한 OS들에 대해 매번 자원을 할당하고 부팅해줘야 하기 때문에 시간 및 자원 소모가 컸다.

VM은 some level of hardware와 kernel virtualization을 통해 게스트 OS를 실행하고, 게스트 kernel을 통해 virtual hw에 접근할 수 있다. 하지만 이 방법을 사용하려면 하드웨어 가상화까지 필요해 비용이 너무 높아진다.

Hypervisor

하이퍼바이저(가상 머신 모니터)는 하이퍼바이저 OS와 가상 머신 리소스를 분리하여 가상 머신의 생성과 관리를 지원한다.

TYPE-1 Hypervisor (Bare Metal)

Native, Bare Metal, Microkernelized Hypervisor로 불린다. 호스트의 하드웨어에서 직접 구동되어 게스트 OS를 관리한다. VM 리소스는 호스트 OS 대신 하이퍼바이저에 의해 하드웨어가 직접 예약되기에 TYPE-2에 비해 오버헤드가 적다. 엔터프라이즈 데이터 센터와 서버 기반 환경에서 주로 사용된다.

TYPE-2 Hypervisor (Hosted)

Hosted, Monolithic Hypervisior로 불린다. 호스트 OS에서 Software Layer 또는 Application으로서 구동된다. 이 방식은 호스트 OS에서 게스트 OS를 추상화하는 방식으로 동작하기에 설치 및 구성이 편리하다. VM 리소스는 호스트 OS에 따라 예약된 후 하드웨어에 대해 실행되기에 오버헤드가 발생할 수 있다. 개인 컴퓨터에서 여러 OS를 구동하려는 개인 사용자에게 적절하다.

특징 및 장점

  • 가상화된 CPU, Memory, Storage, Network Interface 등 할당된 자원을 가상 머신에 제공한다.
  • 실제 자원에 대한 VM 자원의 일정을 관리한다.
  • 하이퍼바이저가 VM의 작업을 요청하면 CPU가 VM의 요청을 받아 명령을 수행한다.
  • 가상 머신을 사용하면 여러 OS를 독립적으로 하나의 호스트 OS에서 실행할 수 있다.
  • 여러 가상 머신에서 같은 가상화 하드웨어 자원과 하이퍼바이저를 공유하여 사용할 수 있다.

단점

  • 프로세스 단위로 격리하는 경우, OS level조차 가상화할 파트가 많아 비용 소모가 크다고 느껴질 수 있다.
  • VM마다 고유한 OS(게스트 OS)가 필요하기 때문에 각각 별도의 자원(CPU, RAM 등)을 사용하여 많은 시간과 자원을 낭비하게 된다.
  • 완전한 운영체제가 올라가기 때문에 실행만으로도 대량의 메모리가 필요하다.
    - CPU: 프로세스 간 전환이 매우 빠르고 애플리케이션은 대부분의 시간동안 sleep 상태로 존재하기 때문에 여러 VM들이 CPU를 경쟁해도 큰 문제가 되지 않는다.
    - 메모리: CPU만큼 빠른 전환(자원 회수)이 이루어지지 않아 대량의 메모리가 필요하다. 따라서 가상화 시 적정 메모리를 산정하는 것이 중요하다.
  • 특정 OS는 라이센스가 필요하다.

컨테이너 기술 (Container)

컨테이너 기술은 호스트 OS 위에서 프로세스 단위 격리를 제공한다. 프로세스가 다른 시스템과 격리되어 실행된다는 점에서 VM과 하이레벨이 유사하지만 로우 레벨에서는 게스트 OS 존재 유무의 차이가 있다.

특징 및 장점

  • VM과 달리 완전한 OS(게스트 OS)가 필요하지 않고 모든 컨테이너가 호스트 OS를 공유한다.
  • 막대한 양의 시스템 리소스(CPU, RAM 등)를 절약할 수 있다.
  • 라이센스 비용을 절감할 수 있다.
  • OS 패치 및 유지보수의 오버헤드가 적다.

단점

  • VM에 비해 자원의 격리와 제한이 어렵다.
  • VM에 비해 스토리지 성능이 좋지 않다.
  • VM에 비해 네트워크 구성이 어렵다.
  • 컨테이너는 하나의 OS에서만 구동 가능하다.
    - 호스트 OS의 커널을 공유하기 때문에 컨테이너는 호스트와 동일한 OS를 사용해야 한다.
  • 컨테이너가 OS를 완전히 재현하지는 못하기 때문에 엄밀한 운영체제 동작이 필요하다면 VM을 사용하는 것이 낫다.

VM vs Container

  • 단일 OS에서 여러 애플리케이션을 실행하는 경우 컨테이너가 유리하다.
  • 서로 다른 OS에서 애플리케이션을 실행해야 하는 경우 VM이 필요하다.

Docker

도커는 리눅스 컨테이너 시스템 runC를 이용해 단일 OS 위에서 격리된 컴퓨팅 환경을 운영할 수 있도록 도와주는 애플리케이션 레벨 가상화 소프트웨어다.

사용 목적

  • 빠르고 일관된 애플리케이션 제공
    - 개발자가 표준화된 환경에서 작업할 수 있다.
  • 효율적인 배포
    - 응용 프로그램과 종속성을 컨테이너로 패키징하여 배포가 일관되도록 하며 환경에 관계없이 실행할 수 있다.
  • 확장성
    - 컨테이너화된 응용 프로그램을 쉽게 확장하고, 컨테이너를 추가하거나 제거하여 성능을 조정할 수 있다.
  • 격리된 환경
    - 각각의 도커 컨테이너는 격리된 환경에서 실행되어 독립적으로 동작하여 안정성과 보안성을 향상시킨다.
  • 개발 환경의 일관성
    - 개발 환경을 컨테이너로 추상화하여 개발자들이 동일한 환경에서 작업할 수 있도록 지원한다.

동작 원리

  • 도커 컨테이너는 호스트 OS의 커널을 공유한다.
    - 각 컨테이너에 리눅스 커널을 할당하여 프로세스를 실행시키고 컨테이너 간 격리를 구현한다.
    - 리눅스 커널의 Cgroup과 namespace 이용한다.
  • 호스트 시스템과 컨테이너가 하나의 커널을 공유하기 때문에 호스트 시스템에서 컨테이너 내부 프로세스를 확인할 수 있다.
    - 호스트 시스템에서 ps 명령어를 통해 컨테이너 내부에서 실행중인 프로세스를 확인할 수 있다.
  • 도커 엔진을 통해 실행 및 관리된다.
  • 도커는 리눅스 커널을 사용하기 때문에 호스트 시스템이 리눅스거나 리눅스 커널이 사용 가능한 OS여야 한다.
    - 도커 엔진은 리눅스 VM을 게스트 OS로 가지고 있기에 이 리눅스 커널을 컨테이너에 할당하여 각 컨테이너를 실행 및 격리시킬 수 있다.
    - 이 덕분에 호스트 OS가 리눅스가 아니어도 도커를 사용할 수 있다.

VM vs Docker


VM은 호스트 컴퓨터 위에 가상 운영체제를 실행하고, 각 운영체제는 자체 커널을 통해 독립적으로 동작한다. 각 VM은 완전히 격리되어 있어 영향을 주지 않지만 용량과 성능이 무겁고 오버헤드가 크다.

Docker Container는 호스트 운영체제 위에서 실행하고, 컨테이너 단위로 애플리케이션과 종속성을 패키징한다. 또한 호스트 OS의 커널을 공유하기 때문에 가볍고 빠르게 실행된다. 여러 컨테이너를 실행하는 경우 각 컨테이너는 격리되지만 공유 리소스를 사용하여 효율이 높다.

가상화의 목적에 따른 선택
완전한 격리와 다양한 운영체제의 실행 -> VM
애플리케이션의 패키징, 배포, 확장 -> Docker

Architecture

도커 아키텍처는 크게 3가지 부분으로 구성된다.

Client

  • Docker 명령어를 사용하여 컨테이너를 관리하고, 이미지를 빌드 및 다운로드할 수 있다.
  • Docker 명령어를 통해 Docker Host와 상호작용한다.

Docker Host (Docker Engine과 유사한 의미)

  • Docker Engine이 설치된 하드웨어 또는 가상머신
    - Docker Engine: 컨테이너를 관리하는 소프트웨어
    - Docker Host와 Docker Engine의 차이가 헷갈린다면 참고
  • Docker 컨테이너를 실행하는 데 사용되는 머신
  • Docker Daemon을 실행하여 컨테이너를 관리한다.
  • Client의 요청을 받아들여 컨테이너를 관리한다.
  • 호스트 OS의 리소스를 사용하여 컨테이너를 실행하고 관리한다.

Docker Registry

  • Docker 이미지를 저장하고 관리하는 중앙 집중식 저장소
  • 공식적인 도커 레지스트리인 Docker Hub를 통해 Docker 이미지를 공유, 검색, 다운로드할 수 있다.
  • 자신만의 독립적인 도커 레지스트리를 구축하여 이미지를 안전하게 저장하고 관리할 수 있다.

라이프사이클


위 그림은 Docker 컨테이너의 생성부터 종료까지의 다양한 단계와 상태를 보여준다.

컨테이너 라이프사이클 관련 명령어는 다음과 같다.

# 컨테이너 생성: 중지된 컨테이너 생성
# 로컬에 이미지가 없으면 자동으로 Docker Hub에서 다운로드
docker create --name <container-name> <image-name>

# 컨테이너 시작: 중지된(생성된) 컨테이너 시작
docker start <container-id/name>

# 컨테이너 실행: create + start. 컨테이너 생성 및 실행
# -it: 인터렉티브 모드(표준 입출력 사용). -d: 백그라운드 모드
docker run -it -d --name <container-name> <image-name> bash

# 컨테이너 일시정지
docker pause <container-id/name>

# 컨테이너 재개
docker unpause <container-id/name>

# 컨테이너 중지
docker stop <container-id/name>

# 컨테이너 재시작
docker restart <container-id/name>

# 컨테이너 종료
docker kill <container-id/name>

# 컨테이너 제거
docker rm <container-id/name>

자세한 설명은 여기를 참고하자

Dockerfile

도커 파일은 도커 이미지를 만들고 빌드하기 위한 텍스트 파일이다. 도커 이미지를 구성하는 데 필요한 모든 단계와 명령을 정의할 수 있다. 이를 사용하면 반복적이고 일관적인 컨테이너 이미지 빌드 프로세스를 자동화할 수 있다.

특징

  • 텍스트 기반이어서 버전 관리 시스템을 통해 관리하기 용이하다.
  • Docker 이미지를 구성하는 데 필요한 명령어를 포함한다.
    - 명령어는 순차 실행되며 각 명령어가 새로운 레이어를 이미지에 추가한다.
  • Dockerfile을 통해 생성된 이미지는 실행 환경에 상관없이 항상 동일한 결과를 생성한다.
  • Dockerfile은 재사용 가능하며 다른 Dcokerfile에 기반을 제공할 수 있다.
  • Dockerfile을 사용하면 이미지 빌드 과정을 자동화할 수 있다.

수행과정


1. 이미지 빌드 과정을 도커파일에 작성한다.
2. 도커엔진이 도커파일을 한 줄씩 읽어서 이미지를 빌드한다.
3. 빌드된 이미지를 실행하여 도커 컨테이너를 구성한다.

Image Layer

도커파일을 빌드하여 이미지를 생성할 때 명령어를 한 줄씩 읽어가며 이미지 레이어를 생성한다. 이후 각 레이어는 변경사항이 있는 경우에만 재빌드되도록 하여 빌드 속도를 향상시키고 중복 작업을 방지할 수 있다.(레이어 캐싱)

이미지 레이어의 캐싱 기준에 관한 자세한 내용은 여기를 참고하자.

Docker Compose

여러 컨테이너를 관리할 때, 단일 명령어 파일을 통해 생성, 관리, 배포를 수행할 수 있다.

Dockerfile을 사용하면 단일 컨테이너의 빌드 프로세스는 자동화할 수 있지만 다중 컨테이너의 경우 번거로워진다. 이 때 도커 컴포즈를 사용하면 다중 컨테이너의 빌드 자동화를 구성할 수 있어 애플리케이션의 배포 및 관리가 매우 수월해진다.

Docker Compose는 Dockerfile을 대체하는 도구가 아니라 Dockerfile과 함께 사용하는 도구다. 각 서비스의 구성을 위해 Dockerfile을 사용한다면 Docker Compose는 서비스 전반의 구성을 위해 사용한다. 즉, Docker Compose는 여러 Dockerfile을 관리하는 도구라고 이해할 수 있다.

참고 자료

도커 컨테이너, 가상화, 내부구조 (feat. VM vs Container)
Docker가 Image Layer를 구성하는 방법
Docker run, start, create 차이
Docker 이해하기 -1 : 기초 이론(아키텍처, 흐름, 주요 용어)
Docker 이해하기 -2 : 컨테이너 라이프 사이클 & CLI 이해하기
Docker 이해하기 -3 : Dockfile 이해하고 Nginx 구성 및 실행방법
Docker 이해하기 -4 : Docker Compose 이해하고 구성하기

0개의 댓글