Docker & Kubernetes 완전 정복 1편: Docker 기초 - 컨테이너 개념과 설치
Docker & Kubernetes Complete Guide Part 1: Docker Basics - Container Concepts and Installation
서론: 컨테이너 기술의 시대
현대 소프트웨어 개발과 배포 환경에서 Docker는 이제 필수적인 기술이 되었습니다. "내 컴퓨터에서는 잘 돌아가는데..."라는 말은 개발자들 사이에서 오랫동안 농담처럼 사용되어 왔지만, Docker의 등장으로 이 문제는 과거의 일이 되었습니다.
이 시리즈에서는 Docker의 기본 개념부터 Kubernetes를 활용한 대규모 컨테이너 오케스트레이션까지 체계적으로 학습합니다. 첫 번째 편에서는 컨테이너 기술의 개념, Docker의 아키텍처, 설치 방법, 그리고 첫 번째 컨테이너를 실행하는 방법까지 다루겠습니다.
1. 컨테이너 기술이란?
1.1 컨테이너의 정의
컨테이너(Container)는 애플리케이션과 그 실행에 필요한 모든 종속성(라이브러리, 설정 파일, 바이너리 등)을 하나의 패키지로 묶어 격리된 환경에서 실행할 수 있게 해주는 기술입니다.
컨테이너는 호스트 운영체제의 커널을 공유하면서도 각각 독립적인 파일 시스템, 네트워크, 프로세스 공간을 가집니다. 이를 통해 애플리케이션은 어떤 환경에서도 동일하게 동작할 수 있습니다.
1.2 컨테이너 기술의 핵심 개념
- 격리(Isolation): 각 컨테이너는 독립적인 환경에서 실행되어 다른 컨테이너나 호스트 시스템에 영향을 주지 않습니다.
- 이식성(Portability): 컨테이너는 어디서든 동일하게 실행됩니다. 개발 환경, 테스트 환경, 운영 환경 간의 차이가 없습니다.
- 경량성(Lightweight): 가상머신과 달리 OS 전체를 포함하지 않아 빠른 시작과 적은 리소스 사용이 가능합니다.
- 불변성(Immutability): 컨테이너 이미지는 한 번 생성되면 변경되지 않으며, 동일한 이미지로 항상 동일한 환경을 재현할 수 있습니다.
2. 가상머신 vs 컨테이너 비교
2.1 가상머신(VM)의 구조
전통적인 가상화 기술인 가상머신은 하이퍼바이저(Hypervisor) 위에 각각 독립적인 운영체제(Guest OS)를 설치합니다:
┌─────────────────────────────────────────────────────────┐
│ Applications │
├─────────────────────────────────────────────────────────┤
│ Guest OS │ Guest OS │ Guest OS │ Guest OS │
├─────────────────────────────────────────────────────────┤
│ Hypervisor │
├─────────────────────────────────────────────────────────┤
│ Host OS │
├─────────────────────────────────────────────────────────┤
│ Hardware │
└─────────────────────────────────────────────────────────┘
2.2 컨테이너의 구조
컨테이너는 호스트 OS의 커널을 공유하며, 컨테이너 런타임(Container Runtime)이 격리를 담당합니다:
┌─────────────────────────────────────────────────────────┐
│ Container │ Container │ Container │ Container │
│ + App │ + App │ + App │ + App │
├─────────────────────────────────────────────────────────┤
│ Container Runtime │
├─────────────────────────────────────────────────────────┤
│ Host OS │
├─────────────────────────────────────────────────────────┤
│ Hardware │
└─────────────────────────────────────────────────────────┘
2.3 비교 표
| 항목 | 가상머신(VM) | 컨테이너(Container) |
|---|---|---|
| 시작 시간 | 분 단위 (OS 부팅 필요) | 초 단위 (프로세스 시작) |
| 리소스 사용 | GB 단위 (전체 OS 포함) | MB 단위 (앱 + 종속성) |
| 격리 수준 | 완전한 하드웨어 수준 격리 | 프로세스 수준 격리 |
| 이식성 | 하이퍼바이저 종속 | 어디서든 동일하게 실행 |
| 밀도 | 하나의 서버에 수십 개 | 하나의 서버에 수백 개 |
| 사용 사례 | 다른 OS 실행, 완전 격리 필요시 | 마이크로서비스, CI/CD, 개발 환경 |
3. Docker의 역사와 장점
3.1 Docker의 탄생
Docker는 2013년 dotCloud라는 PaaS 회사(현재 Docker, Inc.)의 Solomon Hykes가 처음 공개했습니다. Linux 컨테이너(LXC) 기술을 기반으로 시작했지만, 이후 자체 컨테이너 런타임인 libcontainer를 개발하여 더욱 독립적인 플랫폼으로 발전했습니다.
Docker의 등장 이전에도 컨테이너 기술은 존재했지만(chroot, FreeBSD Jail, Solaris Zones, LXC 등), Docker는 이를 쉽고 표준화된 방식으로 사용할 수 있게 만들어 대중화에 성공했습니다.
3.2 Docker의 주요 장점
- 개발-운영 환경 일치: "Works on my machine" 문제 해결. 개발, 테스트, 운영 환경이 동일합니다.
- 빠른 배포: 컨테이너 이미지를 통해 애플리케이션을 초 단위로 배포할 수 있습니다.
- 효율적인 리소스 사용: VM 대비 훨씬 적은 리소스로 더 많은 애플리케이션을 실행할 수 있습니다.
- 마이크로서비스 아키텍처 지원: 각 서비스를 독립적인 컨테이너로 분리하여 관리할 수 있습니다.
- 버전 관리: 이미지 태그를 통해 애플리케이션의 다양한 버전을 관리할 수 있습니다.
- 확장성: 동일한 이미지로 여러 컨테이너를 쉽게 생성하여 수평 확장이 가능합니다.
- 커뮤니티와 생태계: Docker Hub를 통해 수백만 개의 공개 이미지를 활용할 수 있습니다.
4. Docker 아키텍처
Docker는 클라이언트-서버 아키텍처를 사용합니다. 주요 구성요소를 살펴보겠습니다.
4.1 Docker Engine
Docker Engine은 Docker의 핵심 구성요소로, 컨테이너를 생성하고 실행하는 역할을 합니다. 세 가지 주요 구성요소로 이루어져 있습니다:
- Docker Daemon (dockerd): 백그라운드에서 실행되며 Docker 객체(이미지, 컨테이너, 네트워크, 볼륨)를 관리합니다.
- REST API: Daemon과 통신하기 위한 인터페이스를 제공합니다.
- Docker CLI (docker): 사용자가 Docker를 제어하기 위한 명령줄 인터페이스입니다.
4.2 Docker Client
Docker Client는 사용자가 Docker와 상호작용하는 주요 방법입니다. docker 명령어를 사용하면 클라이언트가 이 명령을 Docker Daemon에 전송하고, Daemon이 이를 실행합니다.
# 사용자가 명령 입력
docker run nginx
# Docker Client가 Docker Daemon에 요청 전송
# Docker Daemon이 nginx 이미지를 다운로드하고 컨테이너 실행
4.3 Docker Daemon
Docker Daemon (dockerd)은 Docker API 요청을 수신하고 Docker 객체를 관리합니다. 여러 Daemon이 서로 통신하여 Docker 서비스를 관리할 수도 있습니다.
4.4 Docker 객체
- 이미지(Image): 컨테이너를 생성하기 위한 읽기 전용 템플릿입니다.
- 컨테이너(Container): 이미지의 실행 가능한 인스턴스입니다.
- 네트워크(Network): 컨테이너 간 통신을 위한 격리된 네트워크입니다.
- 볼륨(Volume): 컨테이너의 데이터를 영구적으로 저장하기 위한 공간입니다.
4.5 Docker 아키텍처 다이어그램
┌──────────────────────────────────────────────────────────────┐
│ Docker Host │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Docker Daemon │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────────────┐ │ │
│ │ │ Images │ │ Containers│ │ Networks/Volumes │ │ │
│ │ └───────────┘ └───────────┘ └───────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ REST API │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Docker CLI │ │
│ └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
▲
│
▼
┌──────────────────────────┐
│ Docker Registry │
│ (Docker Hub) │
└──────────────────────────┘
5. Docker 설치
Docker는 Windows, macOS, Linux 모든 플랫폼에서 설치할 수 있습니다. 각 운영체제별 설치 방법을 살펴보겠습니다.
5.1 Windows에서 Docker 설치
요구 사항:
- Windows 10 64bit: Pro, Enterprise, Education (Build 19041 이상)
- Windows 11 64bit: Home, Pro, Enterprise, Education
- WSL 2 (Windows Subsystem for Linux 2) 활성화
- 하드웨어 가상화 지원 (BIOS에서 활성화)
설치 단계:
- Docker 공식 웹사이트에서 Docker Desktop for Windows를 다운로드합니다.
- 다운로드한
Docker Desktop Installer.exe를 실행합니다. - 설치 중 "Use WSL 2 instead of Hyper-V" 옵션을 선택합니다.
- 설치 완료 후 시스템을 재시작합니다.
- Docker Desktop을 실행하고 서비스 약관에 동의합니다.
# 설치 확인 (PowerShell에서)
docker --version
docker run hello-world
5.2 macOS에서 Docker 설치
요구 사항:
- macOS 12.0 (Monterey) 이상
- Apple Silicon (M1/M2/M3) 또는 Intel 프로세서
- 최소 4GB RAM
설치 단계:
- Docker 공식 웹사이트에서 Docker Desktop for Mac을 다운로드합니다.
- 다운로드한
Docker.dmg파일을 열고 Docker를 Applications 폴더로 드래그합니다. - Applications에서 Docker를 실행합니다.
- 시스템 권한 요청을 승인합니다.
# Homebrew를 사용한 설치 (대안)
brew install --cask docker
# 설치 확인
docker --version
docker run hello-world
5.3 Linux (Ubuntu/Debian)에서 Docker 설치
Linux에서는 Docker Engine을 직접 설치합니다:
# 기존 Docker 패키지 제거
sudo apt-get remove docker docker-engine docker.io containerd runc
# 필요한 패키지 설치
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
# Docker 공식 GPG 키 추가
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Docker 저장소 추가
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Docker Engine 설치
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 현재 사용자를 docker 그룹에 추가 (sudo 없이 docker 사용)
sudo usermod -aG docker $USER
# 변경사항 적용 (로그아웃 후 다시 로그인 또는)
newgrp docker
# 설치 확인
docker --version
docker run hello-world
5.4 Linux (CentOS/RHEL)에서 Docker 설치
# 필요한 패키지 설치
sudo yum install -y yum-utils
# Docker 저장소 추가
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Docker Engine 설치
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Docker 서비스 시작 및 활성화
sudo systemctl start docker
sudo systemctl enable docker
# 현재 사용자를 docker 그룹에 추가
sudo usermod -aG docker $USER
# 설치 확인
docker --version
docker run hello-world
6. 첫 번째 컨테이너 실행
6.1 Hello World 컨테이너
Docker가 정상적으로 설치되었는지 확인하는 가장 간단한 방법은 hello-world 이미지를 실행하는 것입니다:
docker run hello-world
실행 결과:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:53641cd209a4fecfc68e21a99871ce8c6920b2e7502df0a20671c6fccc73a7c6
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
...
6.2 nginx 웹 서버 컨테이너
이제 실제로 사용할 수 있는 nginx 웹 서버를 컨테이너로 실행해 봅시다:
# nginx 컨테이너 실행
docker run -d -p 8080:80 --name my-nginx nginx
# 옵션 설명:
# -d: 백그라운드에서 실행 (detached mode)
# -p 8080:80: 호스트의 8080 포트를 컨테이너의 80 포트에 연결
# --name my-nginx: 컨테이너에 이름 부여
# nginx: 사용할 이미지 이름
브라우저에서 http://localhost:8080에 접속하면 nginx 환영 페이지를 볼 수 있습니다.
# 실행 중인 컨테이너 확인
docker ps
# 결과 예시:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint..." 10 seconds ago Up 9 seconds 0.0.0.0:8080->80/tcp my-nginx
# 컨테이너 로그 확인
docker logs my-nginx
# 컨테이너 중지
docker stop my-nginx
# 컨테이너 시작
docker start my-nginx
# 컨테이너 삭제 (중지 후)
docker stop my-nginx
docker rm my-nginx
6.3 대화형 컨테이너 실행
컨테이너 내부에 직접 접속하여 명령을 실행할 수도 있습니다:
# Ubuntu 컨테이너에 대화형으로 접속
docker run -it ubuntu bash
# 옵션 설명:
# -i: 대화형 모드 (interactive)
# -t: TTY 할당 (터미널)
# ubuntu: 사용할 이미지
# bash: 실행할 명령
# 컨테이너 내부에서 명령 실행
root@container_id:/# cat /etc/os-release
root@container_id:/# apt update
root@container_id:/# exit # 컨테이너 종료
7. Docker Hub 소개
7.1 Docker Hub란?
Docker Hub는 Docker 이미지를 저장하고 공유하는 클라우드 기반 레지스트리 서비스입니다. GitHub가 소스 코드를 위한 것이라면, Docker Hub는 Docker 이미지를 위한 것입니다.
- 공개 저장소: 무료로 무제한 공개 이미지를 저장할 수 있습니다.
- 비공개 저장소: 유료 플랜으로 비공개 이미지를 저장할 수 있습니다.
- 공식 이미지: Docker가 검증한 공식 이미지들을 제공합니다.
- 자동 빌드: GitHub/Bitbucket과 연동하여 자동 이미지 빌드가 가능합니다.
7.2 Docker Hub 사용하기
# Docker Hub에서 이미지 검색
docker search nginx
# 결과 예시:
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 19000 [OK]
linuxserver/nginx An Nginx container... 200
# 이미지 다운로드 (pull)
docker pull nginx
docker pull nginx:1.25 # 특정 버전 지정
# Docker Hub 로그인 (이미지 push를 위해)
docker login
# 자신의 이미지 태깅
docker tag my-image:latest username/my-image:latest
# Docker Hub에 이미지 업로드 (push)
docker push username/my-image:latest
7.3 주요 공식 이미지
| 이미지 | 설명 | 예시 명령어 |
|---|---|---|
| nginx | 고성능 웹 서버 | docker run -d -p 80:80 nginx |
| mysql | MySQL 데이터베이스 | docker run -d -e MYSQL_ROOT_PASSWORD=pass mysql |
| postgres | PostgreSQL 데이터베이스 | docker run -d -e POSTGRES_PASSWORD=pass postgres |
| redis | 인메모리 데이터 저장소 | docker run -d -p 6379:6379 redis |
| node | Node.js 런타임 | docker run -it node |
| python | Python 런타임 | docker run -it python:3.11 |
| ubuntu | Ubuntu Linux | docker run -it ubuntu bash |
| alpine | 경량 Linux (5MB) | docker run -it alpine sh |
8. 결론 및 다음 단계
이번 1편에서는 컨테이너 기술의 기본 개념, Docker의 아키텍처, 설치 방법, 그리고 첫 번째 컨테이너를 실행하는 방법까지 살펴보았습니다.
핵심 정리
- 컨테이너는 애플리케이션과 종속성을 패키지로 묶어 격리된 환경에서 실행하는 기술입니다.
- VM과의 차이: 컨테이너는 호스트 OS 커널을 공유하여 더 가볍고 빠릅니다.
- Docker 아키텍처: Client-Server 구조로 Docker CLI, Docker Daemon, Docker Registry로 구성됩니다.
- 기본 명령어:
docker run,docker ps,docker stop,docker rm - Docker Hub: Docker 이미지를 저장하고 공유하는 레지스트리 서비스입니다.
다음 편 예고
2편에서는 Docker 이미지와 컨테이너 관리에 대해 더 깊이 다룹니다:
- 이미지와 컨테이너의 차이
- 이미지 레이어 개념
- docker pull/push/images/rmi 명령어
- 컨테이너 생명주기 관리
- docker run 옵션 상세 (-d, -p, -v, -e, --name)
- docker exec와 attach
- 컨테이너 로그 확인과 리소스 제한
컨테이너 기술은 현대 소프트웨어 개발의 핵심입니다. Docker를 마스터하면 더 효율적인 개발 환경과 배포 파이프라인을 구축할 수 있습니다. 다음 편에서 더 실용적인 Docker 활용법을 배워보겠습니다!