Docker 컨테이너 효율적으로 구성 및 실행하는 방법

DockerBeginner
지금 연습하기

소개

이 포괄적인 Docker 튜토리얼은 개발자와 IT 전문가에게 컨테이너 기술에 대한 심층적인 정보를 제공합니다. 핵심 Docker 개념 이해부터 실용적인 설치 및 관리 기법까지, 이 가이드는 최신 소프트웨어 개발 및 배포를 위해 Docker 의 강력한 컨테이너화 기능을 활용하는 데 필요한 모든 것을 다룹니다.

Docker 기본 사항

컨테이너 기술 소개

Docker 는 개발자가 애플리케이션을 효율적으로 패키징, 배포 및 실행할 수 있도록 하는 강력한 컨테이너 기술 플랫폼입니다. 컨테이너는 소프트웨어와 해당 종속성을 캡슐화하는 가볍고 이식 가능한 환경을 제공합니다.

핵심 Docker 개념

graph TD
    A[Docker Engine] --> B[Container]
    A --> C[Image]
    A --> D[Dockerfile]
개념 설명
Docker Image 애플리케이션 코드 및 종속성을 포함하는 읽기 전용 템플릿
Container Docker 이미지의 실행 가능한 인스턴스
Docker Engine 컨테이너를 생성하고 관리하는 런타임 환경

Docker 설치 확인

LabEx 환경에는 Docker 가 사전 설치되어 있습니다. Docker 버전을 확인하여 사용 준비가 되었는지 확인해 보겠습니다.

docker --version

출력 결과는 Docker version 20.10.21, build baeda1f와 같이 Docker 버전을 표시해야 합니다. 이는 Docker 가 올바르게 설치되었고 접근 가능하다는 것을 확인시켜 줍니다.

첫 Docker 이미지 가져오기

Docker 이미지는 컨테이너를 생성하기 위한 일련의 명령을 포함하는 읽기 전용 템플릿입니다. Docker 설치를 테스트하는 데 사용되는 최소 이미지인 hello-world 이미지를 가져오겠습니다.

docker pull hello-world

이 명령은 Docker Hub 에서 hello-world 이미지를 로컬 머신으로 다운로드합니다. 이미지 다운로드 진행 상황과 이미지가 성공적으로 가져와졌다는 확인 메시지를 볼 수 있습니다.

첫 Docker 컨테이너 실행

이제 이미지를 가져왔으므로 이를 사용하여 컨테이너를 실행해 보겠습니다. 컨테이너를 실행한다는 것은 이미지의 인스턴스를 생성하는 것을 의미합니다.

docker run hello-world

hello-world를 실행하면 Docker 는 다음과 같은 작업을 수행합니다.

  1. 로컬에 hello-world 이미지가 있는지 확인합니다. 없다면 가져옵니다 (이미 수행했습니다).
  2. 이미지로부터 새 컨테이너를 생성합니다.
  3. 컨테이너 내의 실행 파일을 실행합니다.
  4. 컨테이너는 "Hello from Docker!" 메시지를 출력한 후 종료됩니다.

이는 Docker 컨테이너의 기본 수명 주기를 보여줍니다: 이미지를 가져오고, 컨테이너를 실행하며, 컨테이너는 정의된 작업을 수행합니다.

Docker 이미지 목록 보기

다운로드한 이미지를 보려면 docker images 명령을 사용합니다.

docker images

이 명령은 방금 가져온 hello-world 이미지를 포함하여 로컬 시스템에 저장된 모든 Docker 이미지를 나열합니다. 저장소, 태그, 이미지 ID, 생성 날짜 및 크기와 같은 세부 정보를 볼 수 있습니다.

컨테이너 수명 주기 이해

컨테이너는 자체 파일 시스템, 프로세스 및 네트워크 인터페이스를 갖춘 격리된 환경을 제공합니다. 컨테이너는 빠르고 신속하게 시작, 중지, 이동 및 삭제될 수 있으므로 마이크로서비스 및 클라우드 네이티브 애플리케이션에 이상적입니다.

Dockerfile 파일 관리

Dockerfile 기본 사항

Dockerfile 은 이미지를 조립하기 위해 사용자가 명령줄에서 호출할 수 있는 모든 명령을 포함하는 텍스트 문서입니다. 컨테이너화된 애플리케이션의 환경, 종속성 및 구성을 정의합니다.

graph TD
    A[Dockerfile] --> B[Build Command]
    B --> C[Docker Image]
    C --> D[Container]

첫 Dockerfile 생성

설정 단계에서 생성된 docker_app 디렉토리로 이동합니다. 이 디렉토리가 이번 실습의 작업 디렉토리가 됩니다.

cd /home/labex/project/docker_app

이제 이 디렉토리에 Dockerfile이라는 간단한 Dockerfile 을 생성해 보겠습니다. 이 Dockerfile 은 Ubuntu 를 기반으로 이미지를 생성하고 간단한 텍스트 파일을 추가합니다.

nano Dockerfile

Dockerfile에 다음 내용을 추가합니다.

## Use an official Ubuntu base image
FROM ubuntu:22.04

## Set the working directory inside the container
WORKDIR /app

## Create a simple text file
RUN echo "Hello from Dockerfile!" > /app/message.txt

## Command to run when the container starts
CMD ["cat", "/app/message.txt"]
  • FROM ubuntu:22.04: 이 지시문은 새 이미지의 기본 이미지를 지정합니다. Ubuntu 22.04 를 사용합니다.
  • WORKDIR /app: Dockerfile 에서 이 지시문 다음에 오는 모든 RUN, CMD, ENTRYPOINT, COPY 또는 ADD 지시문에 대한 작업 디렉토리를 설정합니다. /app이 존재하지 않으면 생성됩니다.
  • RUN echo "Hello from Dockerfile!" > /app/message.txt: 이 지시문은 빌드 프로세스 중에 이미지 내부에서 명령을 실행합니다. 여기서는 /app 디렉토리에 "Hello from Dockerfile!"이라는 내용으로 message.txt 파일을 생성합니다.
  • CMD ["cat", "/app/message.txt"]: 이 지시문은 실행 중인 컨테이너에 대한 기본 명령을 제공합니다. 이 이미지에서 컨테이너를 실행하면 cat /app/message.txt가 실행되어 메시지 파일의 내용이 표시됩니다.

Ctrl+S를 눌러 파일을 저장하고 Ctrl+X를 눌러 nano를 종료합니다.

Docker 이미지 빌드

Dockerfile 을 만들었으므로 이를 사용하여 Docker 이미지를 빌드해 보겠습니다. docker build 명령은 Dockerfile 을 읽고 Docker 이미지를 생성합니다.

docker build -t my-ubuntu-app .
  • docker build: Docker 이미지를 빌드하는 명령입니다.
  • -t my-ubuntu-app: 이 옵션은 이미지에 my-ubuntu-app이라는 이름을 태그합니다. 원하는 이름을 사용할 수 있습니다.
  • .: 빌드 컨텍스트를 지정하며, 이는 지정된 PATH 또는 URL에 있는 파일 집합입니다. .은 현재 디렉토리 (/home/labex/project/docker_app) 가 빌드 컨텍스트임을 나타냅니다. Docker 는 이 디렉토리에서 Dockerfile을 찾습니다.

Dockerfile 의 각 지시문에 해당하는 빌드 프로세스의 각 단계가 표시되는 출력을 볼 수 있습니다.

사용자 정의 Docker 컨테이너 실행

이미지를 성공적으로 빌드한 후, 이를 사용하여 컨테이너를 실행하여 message.txt 내용을 확인해 보겠습니다.

docker run my-ubuntu-app

이 명령은 my-ubuntu-app 이미지에서 새 컨테이너를 생성하고 실행합니다. Dockerfile 의 CMD 지시문이 실행되며, 터미널에 "Hello from Dockerfile!"이 출력되는 것을 볼 수 있습니다.

컨테이너 파일 시스템 검사

컨테이너 내에서 파일이 어떻게 관리되는지 더 자세히 이해하기 위해 대화형 세션을 실행하고 생성한 파일을 검사해 보겠습니다.

docker run -it my-ubuntu-app /bin/bash
  • -it: 이 플래그는 의사 TTY 를 할당하고 STDIN을 열어 두어 컨테이너와 상호 작용할 수 있도록 합니다.
  • my-ubuntu-app: 실행하려는 이미지의 이름입니다.
  • /bin/bash: Dockerfile 의 CMD 지시문을 재정의하고 대신 컨테이너 내에서 Bash 셸을 실행하여 명령 프롬프트를 제공합니다.

컨테이너 내부에 들어가면 새로운 명령 프롬프트 (예: root@<container_id>:/app#) 가 표시됩니다. 이제 파일을 나열하고 message.txt의 내용을 볼 수 있습니다.

ls -l
cat message.txt

message.txt가 나열되고 해당 내용이 표시되는 것을 볼 수 있습니다. 컨테이너를 종료하려면 exit를 입력하면 됩니다.

exit

이 대화형 세션은 message.txt 파일이 성공적으로 생성되었고 컨테이너의 파일 시스템 내에서 접근 가능하다는 것을 보여줍니다.

고급 Docker 기법

다단계 빌드 전략 (Multi-Stage Build Strategies)

다단계 빌드는 Dockerfile 에서 여러 개의 FROM 문을 사용할 수 있게 해주는 강력한 기능입니다. 각 FROM 지시문은 다른 기본 이미지를 사용할 수 있으며, 각 FROM 지시문은 새로운 빌드 단계를 시작합니다. 이는 빌드 환경과 런타임 환경을 분리하여 Dockerfile 의 복잡성을 최적화하고 최종 이미지 크기를 줄이는 데 도움이 됩니다.

graph TD
    A[Build Stage] --> B[Compile/Build]
    B --> C[Runtime Stage]
    C --> D[Minimal Production Image]

다단계 빌드를 위한 준비

이 예시에서는 빌드 단계가 필요한 간단한 애플리케이션을 시뮬레이션할 것입니다. build_script.shfinal_app.txt 파일을 생성합니다.

먼저 docker_app 디렉토리에 있는지 확인합니다.

cd /home/labex/project/docker_app

이제 간단한 빌드 스크립트를 생성합니다.

nano build_script.sh

build_script.sh에 다음 내용을 추가합니다.

#!/bin/bash
echo "Running build process..."
echo "This is the final application output." > /app/output/final_app.txt
echo "Build complete."

파일을 저장 (Ctrl+S) 하고 종료 (Ctrl+X) 합니다.

다음으로, 최종 애플리케이션 콘텐츠를 위한 플레이스홀더를 생성합니다. 실제 시나리오에서는 빌드 프로세스에 의해 생성될 것입니다.

nano final_app.txt

final_app.txt에 다음 내용을 추가합니다.

This is a placeholder for the final application.

파일을 저장 (Ctrl+S) 하고 종료 (Ctrl+X) 합니다.

다단계 Dockerfile 구현

이제 다단계 빌드를 사용하도록 Dockerfile을 수정해 보겠습니다. build_script.sh를 실행하는 "빌더" 단계와 빌더 단계에서 필요한 출력만 복사하는 "프로덕션" 단계가 있습니다.

nano Dockerfile

기존 내용을 다음으로 바꿉니다.

## Stage 1: Builder stage
FROM ubuntu:22.04 AS builder

## Install bash to run the script
RUN apt-get update && apt-get install -y bash

## Set working directory for the builder stage
WORKDIR /build

## Copy the build script and make it executable
COPY build_script.sh .
RUN chmod +x build_script.sh

## Create a directory for output
RUN mkdir -p /build/output

## Run the build script
RUN ./build_script.sh

## Stage 2: Production stage
FROM ubuntu:22.04

## Set working directory for the production stage
WORKDIR /app

## Copy only the necessary artifact from the builder stage
COPY --from=builder /build/output/final_app.txt .

## Command to run when the container starts
CMD ["cat", "final_app.txt"]
  • FROM ubuntu:22.04 AS builder: 첫 번째 단계를 시작하고 builder라는 이름을 지정합니다.
  • RUN apt-get update && apt-get install -y bash: 빌더 단계에 bash를 설치합니다. 이는 스크립트를 실행하는 데 필요합니다.
  • WORKDIR /build: 빌더 단계의 작업 디렉토리를 설정합니다.
  • COPY build_script.sh .: 빌드 스크립트를 빌더 단계로 복사합니다.
  • RUN chmod +x build_script.sh: 스크립트를 실행 가능하게 만듭니다.
  • RUN mkdir -p /build/output: 빌더 단계에 출력 디렉토리를 생성합니다.
  • RUN ./build_script.sh: 빌드 스크립트를 실행하여 /build/outputfinal_app.txt를 생성합니다.
  • FROM ubuntu:22.04: 두 번째 단계 (프로덕션 단계) 를 시작합니다. 기본적으로 builder 단계에서 아무것도 상속하지 않는 새로운 ubuntu:22.04 이미지를 사용합니다.
  • WORKDIR /app: 프로덕션 단계의 작업 디렉토리를 설정합니다.
  • COPY --from=builder /build/output/final_app.txt .: 이것이 다단계 빌드의 핵심 지시문입니다. builder 단계의 /build/output 디렉토리에서 final_app.txt를 프로덕션 단계의 현재 디렉토리 (/app) 로 복사합니다. 이를 통해 최종 아티팩트만 포함되어 프로덕션 이미지를 작게 유지할 수 있습니다.
  • CMD ["cat", "final_app.txt"]: 프로덕션 컨테이너가 시작될 때 실행될 명령으로, 복사된 파일의 내용을 표시합니다.

파일을 저장 (Ctrl+S) 하고 종료 (Ctrl+X) 합니다.

다단계 이미지 빌드 및 실행

이제 다단계 Dockerfile 을 사용하여 새 이미지를 빌드해 보겠습니다.

docker build -t multi-stage-app .

빌드 출력을 관찰합니다. builder 단계와 최종 단계 모두에 대한 단계를 볼 수 있습니다.

빌드가 완료된 후 컨테이너를 실행하여 final_app.txt 내용이 표시되는지 확인합니다.

docker run multi-stage-app

"This is the final application output."이 출력되는 것을 볼 수 있으며, 이는 다단계 빌드가 빌드 단계에서 최종 이미지로 아티팩트를 성공적으로 복사했음을 확인시켜 줍니다.

Docker 리소스 정리

더 이상 필요하지 않은 Docker 리소스 (컨테이너 및 이미지) 를 정리하여 디스크 공간을 확보하는 것이 좋습니다.

먼저 모든 컨테이너 (종료된 컨테이너 포함) 를 나열합니다.

docker ps -a

ID 또는 이름으로 특정 컨테이너를 제거할 수 있습니다.

docker rm $(docker ps -aq)

이 명령은 종료된 모든 컨테이너를 제거합니다. docker ps -aq는 모든 컨테이너 ID 를 나열하고 docker rm은 해당 컨테이너를 제거합니다.

다음으로 모든 이미지를 나열합니다.

docker images

ID 또는 이름으로 특정 이미지를 제거할 수 있습니다. 실행 중인 컨테이너에서 아직 사용 중인 이미지는 제거하지 않도록 주의하십시오.

docker rmi my-ubuntu-app multi-stage-app hello-world ubuntu:22.04

이 명령은 이 실습에서 생성하고 사용한 이미지를 제거합니다. 이미지가 컨테이너에서 아직 사용 중인 경우 먼저 해당 컨테이너를 제거해야 합니다.

docker images

이 명령은 이미지가 제거되었음을 보여줍니다.

이것으로 Docker 기본 사항 및 고급 기법에 대한 실습을 마칩니다. Dockerfile 생성, 이미지 빌드, 컨테이너 실행 및 다단계 빌드를 사용한 이미지 크기 최적화 방법을 배웠습니다.

요약

Docker 기본 사항, Dockerfile 관리 및 고급 기법을 숙달함으로써 개발자는 더 효율적이고 이식 가능하며 확장 가능한 소프트웨어 환경을 만들 수 있습니다. 이 튜토리얼은 컨테이너 생성, 이미지 관리 및 배포 전략에 대한 실용적인 기술을 제공하여 개발 워크플로우를 간소화하고 클라우드 네이티브 애플리케이션 아키텍처를 채택할 수 있도록 합니다.