본문 바로가기
Infra/Docker

[Infra] Docker란?

by tableMinPark 2023. 8. 25.

리눅스 컨테이너 기반으로 한 오픈소스 가상화 플랫폼

 

도커는 리눅스 컨테이너에 리눅스 애플리케이션을 프로세스 격리 기술을 사용해 더 쉽게 실행하고 관리할 수 있게 도와주는 오픈소스 프로젝트입니다. 도커는 일반적으로 도커 엔진 혹은 도커에 관련된 모든 프로젝트를 말합니다.

 

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

 

Docker를 사용해야 하는 이유

1. 애플리케이션의 개발과 배포가 편리하다.

처음 서버를 할당받아 개발 환경을 구축할 때 운영체제, 컴파일러, 패키지 등 많은 설정을 해야 합니다. 또한 버전이 변경되고 업데이트될 때마다 설정들을 변경해야 하고, 변경하면서 문제가 발생하면 호스트 운영체제를 초기화해야 하는 경우도 발생합니다.

 

도커를 통해 컨테이너 위에서 개발 환경을 구축하면  문제가 발생했을 때 호스트 운영체제에는 아무런 영향을 주지 않기 때문에 안정적으로 구축이 가능합니다. 또한 구축한 개발 환경을 그대로 도커 이미지로 만들고, 배포 서버로 옮겨서 컨테이너로 실행함으로써 개발 환경과 동일한 배포 환경을 빠르게 구축할 수 있습니다.

 

2. 여러 애플리케이션의 독립성과 확장성을 높일 수 있다.

모놀리식 아키텍처의 경우, 모든 프로세스가 결합되고 단일 서비스로 실행되는 형태로 하나의 애플리케이션 실행으로 서비스 구축이 가능합니다. 하지만 마이크로 서비스 아키텍처(MSA, Micro Service Architecture)의 경우 각 프로세스가 분리되고 독립적인 서비스로 실행되는 형태로 여러 개의 애플리케이션의 실행을 통해 서비스를 구축해야 합니다.

 

모놀로식 아키텍처의 경우에도 도커를 활용할 수 있지만, MSA에서는 도커 활용도가 높아집니다. MSA의 각 서비스들을 개별 컨테이너를 통해 독립된 환경으로 구축할 수 있습니다. 또한 컨테이너는 수 초 내로 생성 및 시작이 가능하기 때문에 장애가 발생했을 때 빠르게 재시작이 가능하며, 각 서비스 별로 실행 로그를 확인하는 것과 같이 개별 모니터링이 가능합니다.

 

가상 머신 VS 도커 컨테이너

가상 머신 구조와 도커 컨테이너 구조

기존의 가상화 기술인 가상 머신은 하이퍼바이저(Hypervisor)를 이용해 여러 개의 운영체제를 하나의 호스트에서 생성해서 사용하는 방식이었습니다. 이러한 여러 개의 운영체제는 게스트 운영체제(Guest OS)라고 하고,  하이퍼바이저에 의해 생성되고 관리됩니다. 게스트 운영체제는 완전히 독립된 공간과 시스템 자원을 할당받아 사용합니다. 

가상 머신은 호스트 운영체제와 완벽하게 독립된 운영체제를 생성할 수 있다는 장점이 있지만, 일반 호스트에 비해 성능 손실이 있고 수 기가바이트에 달하는 가상 머신 이미지를 애플리케이션으로 배포하기에는 부담스러운 단점이 있습니다.

 

반면에 도커 컨테이너는 가상화된 공간을 생성하기 위해 리눅스 자체 기능인 chroot, 네임스페이스, cgroup을 사용함으로써 프로세스 단위의 격리 환경을 만들기 때문에 성능 손실이 거의 없습니다. 생성할 컨테이너에 필요한 커널을 호스트 운영체제와 공유해서 사용하고, 컨테이너 안에는 애플리케이션을 구동하기 위한 라이브러리 및 실행 파일만 존재하여 컨테이너를 이미지로 만들었을 때 이미지 용량 또한 가상 머신에 비해 매우 작습니다.

도커 컨테이너는 이미지로 만들어 배포하는 시간이 가상 머신에 비해 빠르고 자원 소비 또한 적습니다. 또한 가상화된 공간을 사용할 때 성능 손실도 거의 없다는 장점이 있습니다. 하지만 리눅스 환경에서만 구축할 수 있다는 단점이 있습니다.

 


도커 파일(Dockerfile)

도커 파일은 도커 이미지를 생성하기 위한 설정 파일입니다. 파일 내 작성된 코드로 도커 이미지가 만들어집니다.

1. 기본적인 문법

구문 설명
# 코멘트(주석)
FROM 베이스 이미지(Docker Image) 지정
MAINTAINER 이미지를 생성한 사람의 이름 및 정보
LABEL Key-Value 형식으로 작성된 메타 데이터
RUN 컨테이너 빌드를 위한 실행 명령
COPY 컨테이너 빌드 시 호스트 파일 또는 디렉토리를 복사
ADD 컨테이너 빌드 시 호스트의 파일, 디렉토리, 압축 파일, URL을 통한 파일을 추가
WORKDIR 컨테이너 빌드 시 명령이 실행될 작업 디렉토리
ENV 환경 변수(컨테이너 실행 시에 사용하는 변수)
USER 명령 및 컨테이너 실행 시 적용할 유저(기본 값은 root)
VOLUME 컨테이너 내의 특정 디렉토리를 로컬 경로에 마운트
EXPOSE 컨테이너 실행 시 외부에서 사용할 포트 지정
CMD 컨테이너 실행 시 실행할 서비스 및 스크립트 지정(사용자 입력 파라미터에 따라 다르게 작동)
ENTRYPOINT 컨테이너 실행 시 실행할 서비스 및 스크립트 지정(항상 실행)
ARG 변수(도커 파일 빌드 시에 사용하는 변수)
💡 COPY와 ADD의 차이점
COPY는 호스트 환경의 파일 또는 디렉터리를 도커 이미지 안으로 복사할 수 있습니다. ADD는 COPY의 기능을 지원하고 동시에 URL을 통해 원격지의 파일을 도커 이미지로 복사할 수 있습니다. 또한 로컬의 압축 파일을 도커 이미지의 특정 디렉터리에 추출할 수 있습니다.
따라서 로컬에 있는 압축 파일을 도커 이미지의 특정 경로에 추출하는 경우와 원격지의 파일을 도커 이미지로 복사하는 경우에는 ADD를 사용하고, 단순히 로컬 파일 또는 디렉터리를 도커 이미지로 복사하는 경우에는 COPY를 사용하는 것이 적절합니다.
💡 CMD와 ENTRYPOINT의 차이점
컨테이너 실행 시 CMD 명령은 파라미터 입력이 없을 경우 정의된 파라미터가 실행되지만, 상황에 따라 파라미터를 추가 입력시 입력된 파라미터가 우선순위를 갖습니다. 하지만 ENTRYPOINT의 경우 컨테이너가 실행 시 항상 실행이 되기 때문에 디폴트 실행 명령어를 사용할 때 유용합니다.
따라서 CMD는 사용자 파라미터 입력에 따라 변동이 있으며, ENTRYPOINT는 CMD와는 다르게 항상 실행됩니다.

 

2. Dockerfile 예시

# 베이스 이미지 (openjdk 11 이미지) 지정
FROM openjdk:11-jdk
# JAR_FILE이라는 변수를 지정하고 값 초기화
ARG JAR_FILE=./wanted/build/libs/api-0.0.1-SNAPSHOT.jar
# JAR_FILE 경로에 호스트의 app.jar 파일을 복사
COPY ${JAR_FILE} ./app.jar
# java 애플리케이션 실행
ENTRYPOINT ["java","-jar","/app.jar"]

 

도커 이미지(Docker Image)

도커 이미지는 소스 코드, 라이브러리, 종속성 도구 및 응용 프로그램을 실행하는데 필요한 기타 파일을 포함하는 불변 파일입니다. 이미지는 읽기 전용이므로 스냅샷이라고도 하며, 특정 시점의 애플리케이션과 가상 환경을 나타냅니다. 이러한 일관성은 도커의 가장 큰 특징 중 하나로 개발자가 안정적이고 동일한 조건에서 소프트웨어를 테스트할 수 있습니다. 

 

도커 이미지를 통해 컨테이너를 생성히며, 이때 쓰기 가능한 레이어가 도커 이미지 위에 추가됩니다. 이 레이어에 컨테이너 내부의 새로운 수정 사항들이 축적되고 해당 컨테이너를 이미지로 추출했을 때 현재 시점의 이미지, 즉 스냅샷을 찍을 수 있습니다.

기존 도커 이미지 위에 컨테이너 컨테이너 레이어가 생성되고 수정 사항들이 축적된다.

도커 컨테이너(Docker Container)

도커 컨테이너는 사용자가 기본 시스템에서 애플리케이션을 분리할 수 있는 가상화된 런타임 환경입니다. 컨테이너는 자율적이기 때문에 각 컨테이너 별로 격리가 되어 서로를 방해하지 않습니다.

 

하드웨어 수준에서 가상화가 이루어지는 가상 머신과는 달리 컨테이너는 애플리케이션 계층에서 가상화됩니다. 가상 머신과는 달리 하나의 머신을 활용하고 커널을 공유하는 구조로 프로세스를 실행하기 위한 운영체제를 가상화할 수 있습니다. 그렇기 때문에 컨테이너가 매우 가벼워져 리소스를 많이 사용하지 않을 수 있습니다.

 

도커 허브(Dockerhub)

 

Docker Hub Container Image Library | App Containerization

Deliver your business through Docker Hub Package and publish apps and plugins as containers in Docker Hub for easy download and deployment by millions of Docker users worldwide.

hub.docker.com

도커 허브는 도커에서 제공하는 기본 이미지 저장소로 ubuntu, centos, debian 등의 베이스 이미지와 python, java 등의 공식 이미지가 저장되어 있습니다. 회원가입을 통해 대용량 이미지를 저장, 다운로드 트래픽을 무료로 사용할 수 있지만 모든 이미지가 사용자들에게 공개되기 때문에 비공개를 원한다면 유료 서비스를 이용해야 합니다.

 

개발 단계에서 도커를 통해 개발 환경을 구축하여 사용하고 이후 이미지로 만들어 배포 서버로 옮겨야 할 때 도커 허브를 이용하면 간단하게 옮길 수 있습니다.

 

도커 네트워크(Docker Network)

도커 컨테이너는 격리된 환경에서 돌아가기 때문에 기본적으로 다른 컨테이너와의 통신이 불가능 하지만, 도커 네트워크를 통해 컨테이너 간 네트워킹을 할 수 있습니다. 

 

도커 네트워크에서 사용할 수 있는 네트워크 종류는 브리지(bridge), 호스트(host), 논(none)이 있습니다. 브리지는 하나의 호스트 컴퓨터 내에서 여러 컨테이너들이 서로 소통할 수 있도록 해주며 컨테이너는 연결된 브리지를 통해 외부와 통신할 수 있습니다. 호스트는 호스트와 동일한 네트워크에서 컨테이너를 돌리기 위해 사용합니다. 논은 말 그대로 아무런 네트워크를 쓰지 않을 때 사용합니다. 

 

도커를 설치하면 기본적으로 docker0 브리지가 생성되고, 컨테이너들은 해당 브리지를 통해 외부와 통신할 수 있습니다. 컨테이너를 시작할 때마다 도커 엔진이 자동으로 호스트에 veth(Virtual Ethernet)라는 네트워크 인터페이스를 생성합니다. veth는 docker0 브리지를 통해 호스트가 갖고 있는 eth0, eth1 등과 바인딩되어 외부와 통신할 수 있는 환경을 사용할 수 있다. 

도커 볼륨(Docker Volume)

도커 컨테이너에 쓰인 데이터는 기본적으로 컨테이너가 삭제될 때 사라지게 됩니다. 그래서 컨테이너에서 돌아가는 애플리케이션이 컨테이너의 생명주기와는 관계없이 데이터를 영속적으로 저장해야 합니다. 도커 볼륨을 통해 도커 내부에서 도커 엔진이 관리하는 볼륨을 생성하고, 볼륨이 데이터를 저장함으로써 데이터의 영속성을 보장할 수 있습니다.

 

바인드 마운트

도커 볼륨과 동일하게 컨테이너 내부에 데이터를 저장하는 것이 아닌 외부에 저장하여 데이터의 영속성을 보장할 수 있는 방법 중 하나입니다. 바인드 마운트는 호스트 파일 시스템의 특정 경로를 컨테이너로 바로 마운트 할 수 있는 기능입니다. 바인드 마운트는 컨테이너를 통해 변경된 부분도 호스트의 작업 디렉터리에도 반영이 되기 때문에 로컬에서 변경된 부분을 확인할 수 있습니다.

'Infra > Docker' 카테고리의 다른 글

[Infra] Ubuntu에 Docker 설치하기  (0) 2023.08.25
[Infra] Docker Compose란?  (0) 2023.08.25