🐳 Docker 기초
컨테이너 기반 가상화 플랫폼 Docker의 핵심 개념부터 실전 활용까지. Build once, Run anywhere.
🐳Docker의 정의
Docker란?
Docker는 애플리케이션을 컨테이너라는 격리된 환경에 패키징하여
어디서나 실행할 수 있게 해주는 오픈소스 플랫폼입니다.
Solomon Hykes가 개발했으며,
현대 소프트웨어 개발과 배포의 핵심 도구가 되었습니다.
💡 핵심 개념
Docker는 "Build once, Run anywhere" 철학을 실현합니다.
한 번 만든 컨테이너는 개발 환경, 테스트 환경, 프로덕션 환경 어디서나 동일하게 작동합니다.
🤔왜 Docker를 사용할까요?
1. 환경 일관성 보장
- "내 컴퓨터에서는 되는데?" 문제를 해결합니다.
- 개발, 스테이징, 프로덕션 환경이 완전히 동일합니다.
- 팀원 간 환경 차이로 인한 버그를 방지합니다.
2. 빠른 배포와 확장
- 가상 머신보다 훨씬 가볍고 빠르게 시작됩니다. (수 초 내)
- 마이크로서비스 아키텍처(MSA)에 최적화되어 있습니다.
- 필요에 따라 컨테이너를 즉시 추가/제거할 수 있습니다.
3. 리소스 효율성
- 호스트 OS 커널을 공유하여 오버헤드가 적습니다.
- 동일 하드웨어에서 더 많은 앱을 실행할 수 있습니다.
4. 격리성과 보안
- 각 컨테이너는 독립적인 환경에서 실행됩니다.
- 의존성 충돌 문제를 원천적으로 해결합니다.
5. 버전 관리와 롤백
- Docker 이미지를 버전별로 관리할 수 있습니다.
- CI/CD 파이프라인과 완벽하게 통합됩니다.
📚 용어 정리 : 호스트 OS와 커널
1. 호스트 OS (Host OS)
물리적인 하드웨어에 직접 설치되어, 가상 머신들에게 자원을 배분하고 관리하는 운영체제입니다.
- 자원 추상화: CPU, 메모리, 스토리지 등 물리 하드웨어를 가상 자원으로 변환합니다.
- 하이퍼바이저 실행: VMware, VirtualBox 같은 하이퍼바이저가 구동되는 기반이 됩니다.
2. 커널 (Kernel)
시스템의 가장 낮은 수준에서 프로세스 관리, 메모리 관리, 파일 시스템 관리를 수행합니다.
- VM: 집을 땅부터 새로 짓는 것 → 무겁고 느림
- 컨테이너: 건물의 기초(커널)를 공유하고 방(컨테이너)만 나누어 쓰는 것 → 가볍고 빠름
🏛️Docker의 필요성
😰 기존 개발 환경의 문제점
1. 복잡한 환경 설정
OS, 라이브러리, 의존성 설치...
2. 내 컴퓨터에선 성공
"Works on my machine"
3. 다른 컴퓨터에선 😭
환경 불일치로 인한 오류 발생
💡 핵심 요약
- Docker는 단순한 소스 코드뿐만 아니라 실행 환경(OS 설정, 라이브러리 등)까지 통째로 패키징하여 배포합니다.
- 이를 통해 "개발 환경(내 컴퓨터)에서는 잘 되는데, 다른 쪽에서는 안 되는" 불일치 문제를 원천적으로 해결합니다.
📦컨테이너란?
컨테이너의 개념
컨테이너는 애플리케이션과 그 실행에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리, 설정)을 포함하는 표준화된 소프트웨어 단위입니다.
컨테이너의 핵심 특징
1. 격리성 (Isolation)
각 컨테이너는 자체 파일 시스템, 프로세스, 네트워크를 가지며 다른 컨테이너와 완전히 격리됩니다.
2. 이식성 (Portability)
한 번 생성된 컨테이너 이미지는 Docker가 설치된 어느 환경에서나 실행 가능합니다.
3. 경량성 (Lightweight)
OS 커널을 공유하므로 VM보다 훨씬 가볍고 빠릅니다.
4. 불변성 (Immutability)
컨테이너 이미지는 변경 불가능하여 일관성이 보장됩니다.
⚔️컨테이너 vs 가상 머신 (VM)
가상 머신의 구조
- 하드웨어 → 호스트 OS → 하이퍼바이저 → 게스트 OS → 애플리케이션
- 각 VM마다 완전한 OS가 필요합니다 (GB 단위)
- 부팅 시간이 분 단위로 소요됩니다.
컨테이너의 구조
- 하드웨어 → 호스트 OS → Docker Engine → 컨테이너
- 호스트 OS의 커널을 공유합니다.
- 부팅 시간이 초 단위로 매우 빠릅니다.
- 크기가 작습니다 (MB 단위).
⚡ 성능 비교
- 시작 시간: VM은 수 분, 컨테이너는 수 초
- 크기: VM은 수 GB, 컨테이너는 수십 MB~수백 MB
- 성능: VM은 오버헤드 높음, 컨테이너는 거의 네이티브 수준
- 밀도: 동일 서버에서 컨테이너를 훨씬 더 많이 실행 가능
🏗️모놀리식에서 MSA로의 진화
1. 모놀리식
거대한 단일 애플리케이션
(수정/배포가 어려움)
2. 컨테이너 패키징
환경 일관성 확보
3. 마이크로서비스 (MSA)
기능 단위로 쪼개어 독립 배포
💡 핵심 요약
- Docker 컨테이너 기술의 발전 덕분에, 애플리케이션을 레고 블록처럼 작은 단위로 나누어 관리하기 수월해졌습니다.
- 이를 바탕으로, 오늘날의 많은 시스템들이 모놀리식에서 MSA(마이크로서비스 아키텍처)로 진화할 수 있게 되었습니다.
🌐Docker Hub
Docker Hub란?
🔗 Docker Hub는 Docker 이미지를 저장하고 공유할 수 있는 클라우드 기반 레지스트리 서비스입니다.
Docker Hub 홈
이미지 검색 (예: Python)
📚 용어 정리: 이미지 태그 (Tag)
- latest: 가장 최신 버전 (기본값)
- slim: 최소한의 패키지만 설치하여 크기를 줄인 버전
- alpine: Alpine Linux 기반의 초경량 이미지 (5MB 내외)
- bookworm / bullseye: Debian Linux의 버전 코드네임
- windowsservercore: Windows 기반 컨테이너 이미지
⌨️Docker 주요 명령어
기본 정보 확인
이미지 관련
저장소(Hub) 관련
컨테이너 관련
🔍Docker 정보 확인
Docker가 정상적으로 설치되었는지 버전 및 시스템 정보를 확인합니다.
Docker version 확인
📋 출력 결과 보기
- Client: Docker CLI(명령줄 도구)의 버전 정보입니다.
- Server (Engine): Docker 데몬(서버)의 버전 정보입니다.
- containerd: 컨테이너 런타임의 버전입니다.
- runc: OCI 컨테이너를 생성/실행하는 저수준 런타임입니다.
Docker info 확인
📋 출력 결과 보기
- Containers / Images: 시스템의 컨테이너/이미지 수입니다.
- Storage Driver: 시스템의 이미지 저장 드라이버입니다.
- Cgroup Driver / Version: 시스템의 cgroup 설정입니다.
- Operating System: Docker가 실행 중인 호스트 OS 정보입니다.
🏃컨테이너 실행 실습
Docker 이미지 다운로드 및 확인
컨테이너 실행 및 내부 탐색
💡 실습 포인트
- docker pull ubuntu:24.04: Docker Hub에서 Ubuntu 24.04 이미지를 다운로드합니다.
- docker run -it ubuntu:24.04 /bin/bash: 컨테이너를 생성하고 대화형 쉘로 접속합니다.
- -i: 표준 입력(stdin)을 열어둡니다.
- -t: 가상 터미널을 할당합니다.
- ifconfig: 컨테이너는 최소한의 패키지만 포함하므로 추가 도구는 설치되어 있지 않습니다.
- exit: 컨테이너 쉘을 종료하고 호스트로 돌아옵니다.
🏗️이미지 생성 및 빌드
실제 예제 프로젝트 flask-app을 기반으로 Docker 이미지를 만드는 과정을 살펴봅니다.
📁 프로젝트 구조
📄 app.py
🔨 이미지 빌드
💡 빌드 과정 이해
- docker build는 Dockerfile의 명령어를 한 줄씩 읽으며, 각 명령어마다 레이어(Layer)를 생성합니다.
- -t flask-image:1.0은 이미지 이름과 태그를 지정합니다.
- . 은 현재 디렉토리를 빌드 컨텍스트로 지정합니다.
🔎이미지 관리 및 조회
이미지 목록 확인
📋 출력 결과 보기
이미지 상세 정보 확인
이미지의 설정, 레이어, 환경 변수 등을 JSON 형식으로 상세 출력합니다.
이미지 레이어 히스토리 확인
📋 출력 결과 보기
💡 각 명령어마다 레이어가 생성되는 것을 볼 수 있습니다.
🌐이미지 배포 및 가져오기
이미지 다운로드
이미지 업로드
이미지 검색
💡 배포 워크플로우
- 1단계:
docker login으로 Docker Hub에 로그인합니다. - 2단계:
docker tag로 이미지에 저장소 이름을 붙입니다. - 3단계:
docker push로 이미지를 업로드합니다. - 4단계: 다른 서버에서
docker pull로 다운로드하여 사용합니다.
🧹이미지 삭제 및 정리
이미지 삭제 실습
📋 출력 결과 보기
⚠️ 각 레이어가 하나씩 삭제되는 것을 확인할 수 있습니다.
미사용 이미지 일괄 정리
전체 정리 (System Prune)
⚠️ 주의사항
- docker rmi: 해당 이미지를 사용하는 컨테이너가 있으면 삭제할 수 없습니다.
- docker image prune -a: 사용하지 않는 모든 이미지를 삭제하므로 주의가 필요합니다.
📄Dockerfile 이해하기
Dockerfile은 Docker 이미지를 만들기 위한 설정 파일입니다. 실제 Dockerfile을 통해 각 명령어 배치를 알아봅니다.
📄 ./flask-app/Dockerfile
💡 순서가 중요한 이유 — 캐시
requirements.txt를 제일 먼저 복사하면, 코드만 수정했을 때 패키지 설치 단계를 캐시로 재사용할 수 있어 빌드가 무척 빨라집니다.- Dockerfile은 위에서 아래로 순서대로 실행됩니다.
- 파일 이름은 반드시
Dockerfile(대소문자 주의)이어야 합니다.
📝주요 Dockerfile 명령어
FROM / COPY / RUN
CMD vs ENTRYPOINT
ENV / EXPOSE
💡 차이점
COPYvsADD: COPY는 로컬 파일만 복사하고, ADD는 압축해제 및 원격 URL을 지원합니다. 가급적 COPY 사용.CMD: 컨테이너 실행 시docker run ... [명령]으로 변경 가능합니다.
📄Dockerfile 작성하기
| 명령어 | 설명 |
|---|---|
| FROM | 베이스 이미지 지정 (예: FROM python:3.9) |
| LABEL | 이미지 메타데이터(작성자, 버전 등) 추가 |
| RUN | 이미지 빌드 시 실행할 리눅스 명령어 (패키지 설치 등) |
| WORKDIR | 작업 디렉토리 설정 (cd와 유사) |
| COPY / ADD | 호스트의 파일을 컨테이너로 복사 (ADD는 URL/압축해제 지원) |
| ENV | 환경 변수 설정 (실행 시에도 유지됨) |
| ARG | 빌드 시점에만 유효한 변수 정의 |
| EXPOSE | 컨테이너가 사용할 포트 명시 (문서화 용도) |
| CMD | 컨테이너 시작 시 실행할 기본 명령어 (오버라이드 가능) |
| ENTRYPOINT | 컨테이너 시작 시 무조건 실행되는 명령어 |
* 레이어를 추가하는 명령어: FROM, RUN, COPY, ADD
🔨이미지 빌드하기
flask-app 빌드 실습
캐시 없이 처음부터 빌드
🐍 빌드 최적화 팁 (Python)
💡 빌드 옵션 정리
- -t [이름]:[태그]: 이미지 태그 지정
- -f [파일명]: 기본 Dockerfile이 아닌 다른 파일 사용
- . (마지막 점): 빌드 경로를 현재 폴더로 지정
🚀컨테이너 실행하기
flask-app 컨테이너 실행
로그 확인
📋 출력 결과 보기
API 접속 확인
컨테이너 중지 및 삭제
💡 주요 옵션 정리
- -d: 백그라운드 환경에서 컨테이너 실행
- -p 5000:5000: 호스트포트:컨테이너포트 연결 설정
- --name: 컨테이너 이름 지정
- 종료 시
stop명령 후rm명령으로 깔끔히 정리합니다.
📝Dockerfile 예제
Python (FastAPI) — ./fast-api-app
📄 requirements.txt: fastapi==0.115.0, uvicorn==0.30.0
📌핵심 정리
1️⃣ Docker란 무엇인가?
- 컨테이너 기반 가상화 플랫폼
- "Build once, Run anywhere" 철학
- 환경 일관성, 빠른 배포, 리소스 효율성 제공
2️⃣ 컨테이너
- 애플리케이션과 의존성을 포함하는 표준화된 단위
- VM보다 가볍고 빠름 (초 단위 시작, MB 단위 크기)
- 격리성, 이식성, 불변성 보장
3️⃣ 주요 명령어
4️⃣ Docker Build & Run
🎉 수고하셨습니다!
Docker 강의를 완료하셨습니다! 이제 Docker의 기본 개념과 핵심 기능을 이해하고 있습니다. 실습을 통해 경험을 쌓고, Kubernetes로 나아가세요!