Post

Docker

Docker

docker-logo

Docker

docker

  • 내가 만든 프로그램이 다른 컴퓨터에서는 안 돌아가는 상황을 방지하기 위해 만들어졌다.
  • 소프트웨어를 일관되게 빌드하고 실행하고 배포하는 것이 목적
  • 애플리케이션을 더 쉽게 만들고, 배포하고, 실행할 수 있도록 도와주는 컨테이너화 플랫폼(containerization platform)
  • 애플리케이션과 그 종속성을 격리된 환경에서 실행할 수 있는 컨테이너(Container)로 패키징해서, 어디서나 일관된 방식으로 실행될 수 있도록 한다.


관련 중요 개념들

  1. 컨테이너(Container)

    • 애플리케이션과 그 애플리케이션을 실행하는 데 필요한 모든 라이브러리, 종속성, 설정 등을 포함하는 독립적인 실행 환경
    • 호스트 운영체제의 커널을 공유하고 독립적인 파일 시스템, 네트워크 공간, 프로세스 공간을 가진다.
    • 가상 머신(VM)보다 더 가볍고 빠르게 동작한다.
  2. 이미지(Image)

    • 컨테이너를 생성하는 데 사용되는 템플릿(패키지)
    • 애플리케이션과 종속성뿐만 아니라 필요한 파일, 환경 변수, 명령 등을 정의한 구성 파일을 포함한다.
    • Docker Hub와 같은 저장소에서 관리되고 배포될 수 있다.
    • 여러 단계의 이미지 레이어로 구성된다.
      • Docker 이미지는 여러 단계의 레이어로 구성되어 있다.
      • 각 레이어는 파일 시스템의 변경 사항을 나타내는데, 깃 커밋기록과 비슷한 개념이다.
      • 예시: Docker 이미지는 다음과 같은 레이어로 구성된다.

        레이어 1: ubuntu:latest 베이스 이미지
        레이어 2: 패키지 업데이트(RUN apt-get update -y)
        레이어 3: curl 설치 (RUN apt-get install -y curl)
        레이어 4: 애플리케이션 파일 복사 (COPY . /app)

      • Docker는 컨테이너를 생성할 때 이미지를 구성하는 모든 레이어를 사용하여 최종적인 파일 시스템을 구성한다. 하지만 이 과정에서 각 레이어는 읽기 전용으로 다루어지며, 실제로는 모든 데이터를 매번 새로 읽는 것이 아니라, 캐싱된 레이어를 재사용하기 때문에 Docker는 컨테이너 생성과 시작을 매우 빠르고 효율적으로 처리할 수 있다.
  3. Dockerfile

    • Docker 이미지를 생성하는 데 필요한 설정과 명령을 정의한 텍스트 파일
    • 애플리케이션의 설치 방법, 환경 설정, 실행 명령 등을 포함한다.
      • 어떤 베이스 이미지를 사용할지(FROM)
      • 어떤 패키지를 설치할지(RUN)
      • 애플리케이션의 소스 코드를 어디에 복사할지(COPY)
      • 최종적으로 실행할 명령은 무엇인지(CMD 또는 ENTRYPOINT) 등을 포함
    • Dockerfile을 기반으로 docker build 명령을 사용하여 이미지를 생성한다.
  4. Volume & 데이터 관리

    • 컨테이너는 기본적으로 비휘발성 저장소가 없으며, 컨테이너 삭제 시 데이터도 삭제됨
    • Volume: Docker가 관리하는 데이터 저장소 (컨테이너 간 공유 가능)
    • Bind Mount: 호스트의 디렉토리를 컨테이너 내부에 연결
    • 명령 예시:
      1
      2
      
      docker run -v my-volume:/data my-image
      docker run -v $(pwd)/logs:/var/log/app my-image
      
  5. Docker Engine

    • Docker 컨테이너의 생성, 배포, 관리 등을 담당하는 클라이언트-서버 애플리케이션
    • Docker 데몬(Docker Daemon)
      • Docker의 핵심 백그라운드 프로세스
      • 컨테이너를 빌드(생성), 실행, 모니터링, 삭제
      • 이미지와 컨테이너의 네트워크 및 저장소 관리
      • Docker CLI로부터 명령을 수신하고 이를 실행
      • 클러스터링 및 오케스트레이션 기능(예: Docker Swarm)도 제공
    • Docker CLI(Client)
      • 사용자가 Docker와 상호작용할 수 있는 커맨드라인 인터페이스(CLI) 도구
      • docker run, docker build, docker pull, docker push 등의 명령어를 통해 Docker Daemon에 요청을 보낸다.
      • REST API를 사용하여 Docker Daemon과 통신한다.
    • Docker Registry (도커 레지스트리)
      • Docker 이미지를 저장하고 배포
      • Docker Hub: 가장 잘 알려진 공개 레지스트리로, 수많은 공식 이미지와 사용자 생성 이미지를 호스팅
      • 프라이빗 레지스트리를 설정하여 내부적으로만 이미지를 관리할 수도 있다.
  6. 컨테이너 런타임 (Container Runtime)

    • 실제로 컨테이너를 생성, 실행, 정지하는 저수준 실행 계층
    • Docker는 내부적으로 containerd(고수준 런타임)와 runc(저수준 실행기)를 함께 사용
    • containerd는 이미지 관리, 볼륨 마운트, 네트워크 설정 등을 담당하고, 실제 실행은 runc가 수행
    • runcOCI(Open Container Initiative) 명세를 따르며 리눅스 커널 기능(cgroups, namespaces)을 이용해 컨테이너를 실행
    • Kubernetes는 Docker 대신 containerd, CRI-O, gVisor, Kata Containers 등 다양한 런타임과 연동
    • Kubernetes 1.20부터 Docker 자체가 아닌 Docker 내부의 containerd를 사용하기 때문에 중간 계층인 dockershim이 제거되며, Kubernetes에서 Docker 직접 사용은 더 이상 권장되지 않는다.
  7. 네트워킹(Networking)

    • Docker는 컨테이너 간 통신과 외부와의 연결을 위해 다양한 네트워크 드라이버를 지원한다.
    • 주요 네트워크 드라이버:
      • bridge: 기본값. 컨테이너 간 가상 네트워크를 생성 (호스트와 분리)
      • host: 호스트의 네트워크와 동일한 네임스페이스 사용
      • none: 네트워크 비활성화
      • overlay: 여러 호스트 간 컨테이너 네트워크를 구성 (Swarm, Kubernetes에서 사용)
    • 네트워크 관련 명령어 예시:
      1
      2
      3
      
      docker network ls
      docker network create my-bridge
      docker run --network=my-bridge my-image
      
  8. 보안(Security)

    • 컨테이너는 OS 커널을 공유하므로 격리 수준이 낮을 수 있고, 보안에 주의해야 한다.
    • 주요 보안 기능:
      • seccomp: 시스템 콜 제한
      • AppArmor, SELinux: 접근 권한 제어
      • read-only 파일 시스템 설정
      • 비루트 사용자(non-root user) 권장
    • 보안 진단 도구:
  9. 이미지 최적화(Image Optimization)

    • Dockerfile 작성 시 빌드 속도와 캐시 활용을 고려한 최적화 필요
    • 팁:
      • 자주 변경되는 파일은 마지막에 COPY
      • RUN 명령은 가능한 한 줄로 묶기 (레이어 수 최소화)
    • 멀티 스테이지 빌드 활용 시 빌드 환경과 실행 환경을 분리해 이미지 크기를 줄일 수 있다.
      1
      2
      3
      4
      5
      6
      7
      
      FROM node:20 AS builder
      WORKDIR /app
      COPY . .
      RUN npm install && npm run build
      
      FROM nginx:alpine
      COPY --from=builder /app/dist /usr/share/nginx/html
      
  10. 컨테이너 상태 및 수명주기(Container Lifecycle)

    • 컨테이너는 다음과 같은 상태를 가진다:
      • created, running, paused, exited, dead
    • docker ps -a로 전체 상태 확인 가능
    • 수명주기 관련 명령어:
      1
      2
      3
      4
      
      docker stop <container>
      docker rm <container>
      docker restart <container>
      docker run --rm my-image  # 실행 후 자동 삭제
      
  11. 멀티 아키텍처(Multi-Architecture) 지원

    • ARM (Apple M1/M2) 및 x86 환경을 모두 지원하는 이미지 빌드가 가능
    • docker buildx를 활용하여 플랫폼별 이미지 생성:
      1
      2
      
      docker buildx create --use
      docker buildx build --platform linux/amd64,linux/arm64 -t my-image:multiarch . --push
      


기본적인 작동 흐름

  1. Dockerfile 작성
  2. 이미지 빌드 (docker build)
  3. 이미지 저장 및 관리 (docker images, docker push)
  4. 컨테이너 실행 (docker run)
  5. 컨테이너 관리 (docker ps, docker stop, docker rm 등)


Docker의 장점

  • 이식성(Portability): 개발 환경에서 운영 환경까지 일관된 실행 환경을 제공하므로 “개발 환경에서는 잘 되는데, 운영 환경에서는 문제가 발생하는” 상황을 줄여준다.
  • 경량화(Lightweight): 컨테이너는 OS 커널을 공유하므로 VM보다 훨씬 가볍고 빠르게 동작한다.
  • 빠른 배포(Fast Deployment): 컨테이너는 프로세스 수준에서 동작하므로, 가상 머신보다 훨씬 빠르게 시작하고 종료할 수 있다.
  • 버전 관리 및 재사용성(Version Control & Reusability): Docker 이미지는 버전 관리가 가능하며, 여러 단계의 이미지 레이어를 사용하여 효율적으로 관리할 수 있다.
  • 확장성 및 클라우드 네이티브(Scalability & Cloud-Native): Kubernetes와 같은 도구와 함께 사용하여 애플리케이션을 쉽게 확장하고 관리할 수 있다.


Docker Compose와 Kubernetes

기능Docker ComposeKubernetes
목적로컬 개발 및 간단한 테스트프로덕션 환경에서 대규모 애플리케이션 배포
스케일링제한적 (docker-compose scale)자동 및 수동 스케일링 지원
오케스트레이션 기능제한적 (단순 컨테이너 관리)완전한 오케스트레이션 플랫폼
배포 및 롤아웃지원하지 않음롤링 업데이트, Canary 배포 등 지원
모니터링 및 복구기본적인 컨테이너 모니터링자동 복구, 상태 관리, 헬스 체크 지원
클러스터링 및 다중 호스트단일 호스트에 국한됨다중 호스트 클러스터링 지원
로드 밸런싱지원하지 않음클러스터 내 로드 밸런싱 및 외부 트래픽 관리
  • Docker Compose는 비교적 단순한 애플리케이션 스택(예: 웹 서버, 데이터베이스) 관리에 주로 쓰이고, Kubernetes는 마이크로서비스 기반 애플리케이션을 관리하고 오케스트레이션하는 데 적합하다.
  • 개발자는 Docker Compose를 사용하여 로컬 환경에서 애플리케이션을 개발하고 테스트한 다음, Kubernetes를 사용해서 프로덕션 환경으로 배포할 수 있다.
    • Kubernetes는 Docker Compose와 호환되는 kompose라는 도구로 Docker Compose 파일을 Kubernetes 매니페스트 파일로 변환하는 기능을 지원한다.
  • 정리하면, Docker Compose는 로컬 개발 및 간단한 테스트 환경에서 여러 컨테이너를 쉽게 관리하고 실행하기 위한 도구로 주로 단일 호스트에서 사용된다. 반면 Kubernetes는 클러스터 내에서 대규모의 분산 환경에서 애플리케이션을 자동으로 배포, 관리, 스케일링 및 복구하는 데 최적화된 오케스트레이션 플랫폼이다.
This post is licensed under CC BY 4.0 by the author.