여는 글

지난 포스팅에선 컨테이너(Container)에 대해 이해하는 시간을 가졌습니다. 이번 포스팅에서는 Docker를 통해 컨테이너 동작 원리를 이해해보도록 하겠습니다.

컨테이너(Container)를 실행할 때 발생하는 일.

일반적으로 Docker를 Linux에 설치하고 나면 docker CLI 도구를 사용하여 docker명령을 실행합니다. 만약 docker run이라는 명령어를 입력하면 다음 [그림1.1]과 같은 과정이 일어납니다.

docker-container drawio * 그림 1.1

Linux VM에서 컨테이너(Container)를 실행하는 명령어를 입력한다고 했을 때 CLI 도구는 Docker daemon에 API 요청을 보냅니다. Docker daemon은 컨테이너로 실행하고자 하는 imagelocal(VM) image cache에 있는지 확인하고, 만약 없다면 ‘Docker Hub Registry’에서 가져옵니다.

image를 컴퓨터에 다운로드한 후 Docker daemon은 해당 이미지를 컨테이너를 실행합니다.

이미지 생성 과정

앞선 목차에서 image라는 용어를 거듭 사용하였는데요. ‘Docker Image’는 컨테이너(Container)를 실행하는데 필요한 모든 파일과 설정 정보를 담고 있는 경량화된, 독립적인 ‘실행 가능한 소프트웨어 패키지’입니다. 각 이미지는 필요한 실행 파일, 라이브러리, 환경변수 등을 포함하고 있어서, 어떤 환경에서든 동일하게 컨테이너를 실행할 수 있도록 해줍니다.

image는 ‘Dockerfile’이라는 스크립트를 통해 생성할 수 있습니다. ‘Dockerfile’은 컨테이너가 실행될 때 필요한 모든 설정과 설치할 패키지 등을 명시하는 파일입니다.

아래 [그림1.2]를 보면서 image빌드 프로세스(이 포스팅에서 docker 명령어는 자세히 다루지 않습니다.)를 살펴보겠습니다. 아래는 ‘Node.js’기반의 앱을 이미지로 빌드하는 과정을 간단히 보여주는 그림입니다.

docker-container2 drawio * 그림 1.2

빌드 자체는 Docker CLI도구에 의해 수행되지 않습니다. 대신, 전체 디렉토리의 내용이 Docker daemon으로 업로드 되고 이미지는 그곳에서 빌드됩니다.

이미지를 빌드하기 위해 Docker는 먼저 베이스 이미지(node:12)를 Docker Hub에서 가져옵니다. 물론 해당 이미지가 이미 실행환경(로컬 또는 VM)에 있다면 가져오지 않습니다. 그런 다음, Docker는 해당 이미지로부터 새 컨테이너를 생성하고 Dockerfile의 다음 지시사항을 실행합니다.

만약, ‘Spring Boot’앱이라면 ‘OpenJDK’같이 Java 런타임 환경이 설치된 베이스 이미지가 필요하겠죠.

이미지 레이어 (Image Layer)

[그림1.2]를 보면, 이미지(Image)가 여러 레이어(Layer)로 구성되어 있다는 것을 보셨을겁니다. 각 이미지는 기본 이미지의 레이어와 그 위에 새로운 단일 레이어로만 구성되어 있다고 생각할 수도 있지만 그렇지 않습니다. 이미지를 빌드할 때 Dockerfile의 각 개별 지시문에 대한 새 레이어가 생성합니다.

docker history라는 명령어를 입력하여. 레이어와 그 용량을 볼 수 있습니다. 최 상단 레이어부터 출력됩니다. ‘Docker Desktop’를 사용하시는 분이면, 아래 [그림1.3]처럼 이미지를 클릭해서 보실 수 있습니다.

스크린샷 2023-10-30 오후 1 47 39 *그림 1.3


오늘 포스팅에선 Docker를 이용하여 컨테이너(Container)와 이미지(Image)에 대해 이해하는 시간을 가져보았습니다. 다음 포스팅에선 컨테이너가 가상 머신을 사용하지 않고 프로세스 격리가 가능한 방법을 알아보고 컨테이너가 계속 실행상태로 유지되어야 하는 이유을 알아보겠습니다.