Docker
Docker
Docker
- 내가 만든 프로그램이 다른 컴퓨터에서는 안 돌아가는 상황을 방지하기 위해 만들어졌다.
- 소프트웨어를 일관되게 빌드하고 실행하고 배포하는 것이 목적
- 애플리케이션을 더 쉽게 만들고, 배포하고, 실행할 수 있도록 도와주는 컨테이너화 플랫폼(containerization platform)
- 애플리케이션과 그 종속성을 격리된 환경에서 실행할 수 있는 컨테이너(Container)로 패키징해서, 어디서나 일관된 방식으로 실행될 수 있도록 한다.
관련 중요 개념들
컨테이너(Container)
- 애플리케이션과 그 애플리케이션을 실행하는 데 필요한 모든 라이브러리, 종속성, 설정 등을 포함하는 독립적인 실행 환경
- 호스트 운영체제의 커널을 공유하고 독립적인 파일 시스템, 네트워크 공간, 프로세스 공간을 가진다.
- 가상 머신(VM)보다 더 가볍고 빠르게 동작한다.
이미지(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는 컨테이너 생성과 시작을 매우 빠르고 효율적으로 처리할 수 있다.
Dockerfile
- Docker 이미지를 생성하는 데 필요한 설정과 명령을 정의한 텍스트 파일
- 애플리케이션의 설치 방법, 환경 설정, 실행 명령 등을 포함한다.
- 어떤 베이스 이미지를 사용할지(FROM)
- 어떤 패키지를 설치할지(RUN)
- 애플리케이션의 소스 코드를 어디에 복사할지(COPY)
- 최종적으로 실행할 명령은 무엇인지(CMD 또는 ENTRYPOINT) 등을 포함
- Dockerfile을 기반으로
docker build
명령을 사용하여 이미지를 생성한다.
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
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: 가장 잘 알려진 공개 레지스트리로, 수많은 공식 이미지와 사용자 생성 이미지를 호스팅
- 프라이빗 레지스트리를 설정하여 내부적으로만 이미지를 관리할 수도 있다.
컨테이너 런타임 (Container Runtime)
- 실제로 컨테이너를 생성, 실행, 정지하는 저수준 실행 계층
- Docker는 내부적으로 containerd(고수준 런타임)와 runc(저수준 실행기)를 함께 사용
containerd
는 이미지 관리, 볼륨 마운트, 네트워크 설정 등을 담당하고, 실제 실행은runc
가 수행runc
는 OCI(Open Container Initiative) 명세를 따르며 리눅스 커널 기능(cgroups, namespaces)을 이용해 컨테이너를 실행- Kubernetes는 Docker 대신
containerd
,CRI-O
,gVisor
,Kata Containers
등 다양한 런타임과 연동 - Kubernetes 1.20부터 Docker 자체가 아닌 Docker 내부의 containerd를 사용하기 때문에 중간 계층인
dockershim
이 제거되며, Kubernetes에서 Docker 직접 사용은 더 이상 권장되지 않는다.
네트워킹(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
보안(Security)
- 컨테이너는 OS 커널을 공유하므로 격리 수준이 낮을 수 있고, 보안에 주의해야 한다.
- 주요 보안 기능:
seccomp
: 시스템 콜 제한AppArmor
,SELinux
: 접근 권한 제어read-only
파일 시스템 설정- 비루트 사용자(non-root user) 권장
- 보안 진단 도구:
- Docker Bench for Security
- Trivy: 이미지 취약점 스캐너
이미지 최적화(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
컨테이너 상태 및 수명주기(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 # 실행 후 자동 삭제
- 컨테이너는 다음과 같은 상태를 가진다:
멀티 아키텍처(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
기본적인 작동 흐름
- Dockerfile 작성
- 이미지 빌드 (
docker build
) - 이미지 저장 및 관리 (
docker images
,docker push
) - 컨테이너 실행 (
docker run
) - 컨테이너 관리 (
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 Compose | Kubernetes |
---|---|---|
목적 | 로컬 개발 및 간단한 테스트 | 프로덕션 환경에서 대규모 애플리케이션 배포 |
스케일링 | 제한적 (docker-compose scale ) | 자동 및 수동 스케일링 지원 |
오케스트레이션 기능 | 제한적 (단순 컨테이너 관리) | 완전한 오케스트레이션 플랫폼 |
배포 및 롤아웃 | 지원하지 않음 | 롤링 업데이트, Canary 배포 등 지원 |
모니터링 및 복구 | 기본적인 컨테이너 모니터링 | 자동 복구, 상태 관리, 헬스 체크 지원 |
클러스터링 및 다중 호스트 | 단일 호스트에 국한됨 | 다중 호스트 클러스터링 지원 |
로드 밸런싱 | 지원하지 않음 | 클러스터 내 로드 밸런싱 및 외부 트래픽 관리 |
- Docker Compose는 비교적 단순한 애플리케이션 스택(예: 웹 서버, 데이터베이스) 관리에 주로 쓰이고, Kubernetes는 마이크로서비스 기반 애플리케이션을 관리하고 오케스트레이션하는 데 적합하다.
- 개발자는 Docker Compose를 사용하여 로컬 환경에서 애플리케이션을 개발하고 테스트한 다음, Kubernetes를 사용해서 프로덕션 환경으로 배포할 수 있다.
- Kubernetes는 Docker Compose와 호환되는
kompose
라는 도구로 Docker Compose 파일을 Kubernetes 매니페스트 파일로 변환하는 기능을 지원한다.
- Kubernetes는 Docker Compose와 호환되는
- 정리하면, Docker Compose는 로컬 개발 및 간단한 테스트 환경에서 여러 컨테이너를 쉽게 관리하고 실행하기 위한 도구로 주로 단일 호스트에서 사용된다. 반면 Kubernetes는 클러스터 내에서 대규모의 분산 환경에서 애플리케이션을 자동으로 배포, 관리, 스케일링 및 복구하는 데 최적화된 오케스트레이션 플랫폼이다.
This post is licensed under CC BY 4.0 by the author.