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.