이전 글에서 도커의 탄생 배경과 기능, 구성 요소에 대해 간단하게 작성했지만, 좀 더 자세한 정리를 위해 추가 글을 작성한다.
도커는 크게 다음 세 가지 주요 구성 요소로 이루어져 있다.
👉 전체적인 흐름 : 사용자가 도커 클라이언트에서 명령어를 입력하면
-> 도커 호스트의 도커 데몬이 명령어를 처리 -> 도커 호스트에 이미지가 존재하지 않는다면 도커 레지스트리에서 가져오고 -> 컨테이너를 실행
도커 이미지는 컨테이너를 생성하기 위한 실행 가능한 패키지. 하나의 이미지에는 어플리케이션 실행에 필요한 코드, 라이브러리, 설정 파일, 종속성 등이 모두 포함되어 있어, 어떤 환경에서도 동일한 실행 결과를 보장.
도커 이미지는 여러 개의 레이어로 구성되어 있어, 중복 저장을 줄이고, 변경된 부분만 다시 빌드하여 스토리지와 빌드 성능을 최적화한다.
이미지 구성 요소
Dockerfile
이라는 빌드 스크립트를 기반으로 생성된다. Dockerfile
의 각 명령어는 하나의 레이어로 변환되어 이미지가 아래에서 위로 쌓인다.# 베이스 이미지 설정
FROM openjdk:17
# 컨테이너 내 작업 디렉터리 설정
WORKDIR /app
# jar 파일의 이름을 변경해서 워킹 디렉터리에 복사
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} memo-app.jar
# 컨테이너 실행 시 수행할 기본 명령어 정의
ENTRYPOINT ["java", "-jar", "/memo-app.jar"]
도커는 빌드 시 이전 레이어가 바뀌지 않으면 아래 레이어를 재사용한다.
예를 들어, COPY
단계에서 jar
파일이 변경되면, 그 이후 단계도 모두 다시 실행됨 따라서 가능한 한 변경이 잦은 명령은 아래쪽에 배치하는 것이 효율적이다.
도커에서 컨테이너란 도커 이미지를 실행한 인스턴스. 이미지를 기반으로 실제 어플리케이션을 실행하는 환경이며, 다음과 같은 특징을 가짐.
run
, stop
, start
, restart
, rm
등컨테이너는 격리된 환경에서 실행되지만, 대부분의 어플리케이션은 네트워크를 통해 서로 통신해야 한다.
도커는 이를 위해 컨테이너 간 통신, 호스트와의 통신, 외부 네트워크 연결을 가능하게 하는 가상 네트워크를 제공한다.
도커는 컨테이너를 실행할 때, 호스트의 네트워크 인터페이스를 활용해 내부적으로 가상의 네트워크 인터페이스와 브리지를 구성한다.
흐름 예시 : 외부 요청 -> eth0
-> docker0
-> veth
-> 컨테이너 내부 네트워크
도커는 여러 가지 네트워크 방식(드라이버)을 제공하며, 사용 목적에 따라 선택할 수 있다.
bridge
-p
옵션으로 포트 매핑이 필요docker run -d --name web1 -- network bridge -p 8080:80 nginx
host
none
명시적으로 네트워크를 설정하지 않으면 기본값 브리지 네트워크가 사용된다. 하지만 복잡한 컨테이너 구성에서는 사용자 정의 네트워크가 필요하다.
docker network create my-network
docker run -d --name backend --network my-net my-backend-image
docker run -d --name frontend --network my-net my-frontend-image
컨테이너는 삭제되면 컨테이너 내부에 존재하는 파일도 함께 사라진다. 도커 컨테이너 내부에서 사용되거나 생성되는 데이터를 컨테이너 실행 여부와 상관없이 유지할 수 있는 방법으로 등장한 것이 바로 도커 스토리지이다. 이를 활용하면 컨테이너 외부에도 데이터를 저장할 수 있어 데이터의 영속성을 보장할 수 있다.
Bind Mount
: 호스트의 특정 디렉터리를 컨테이너에 그대로 연결하는 방식
docker run -v /my/host/path:/data my-image
# /my/host/path : 도커 호스트의 실제 디렉터리
# /data : 컨테이너 내부에서 접근하는 경로
Volume
: 도커가 자체적으로 볼륨을 생성하고 관리하는 방식
# 먼저 볼륨 생성
docker volume create my-volume
# 컨테이너 실행 시 볼륨 마운트
docker run -v my-volume:/data my-image
/var/lib/docker/volumes/
아래에 저장된다.tmpfs
docker run --tmpfs /app/tmp:rw,size=100m my-image
# 컨테이너 내부의 /app/tmp 경로에 대해 tmpfs를 마운트
이상으로 도커에 대한 글을 마치겠다. 이번 글을 작성하면서 잠시 잊어버렸던 도커에 대해 다시 떠올리고 정리할 수 있었다. 다음 글에서는 컨테이너 오케스트레이션 도구인 쿠버네티스에 대해 알아볼 것이다.