김가은-2

김가은-2

[따베도] 도커 시리즈 - 이론

3-1. 도커 컨테이너 살펴보기 - 이론편

4-1. 도커 컨테이너 만들기 - 이론편

5-1. 컨테이너 보관창고 - 이론편

6-1. Docker 컨테이너 사용하기 - 이론편

7-1. Docker 컨테이너 리소스 관리 - 이론편

8-1. Docker Container Storage - 이론편

9-1. 컨테이너간 통신(네트워크) - 이론편

10-1. 빌드에서 운영까지 (using Docker Compose) - 이론편


컨테이너와 컨테이너 이미지

  1. 컨테이너

  • 하나의 애플리케이션 실행 단위로, 독립된 환경에서 실행되는 프로세스

  • 서로 완전히 분리된 공간에서 실행되므로, 다른 컨테이너에 영향을 주지 않음

  • 각 컨테이너는 CPU, 메모리, 네트워크, 디스크 리소스를 가상으로 독립적으로 할당받음

  • 개발자는 특정 컨테이너만 수정해서 기능을 업데이트할 수 있음 (모듈성 ↑)

 

  1. 컨테이너 이미지

  • 컨테이너 실행을 위한 정적인 파일 조합

  • 디스크에는 읽기 전용 파일 형태로 저장됨

  • 여러개의 Layer로 구성되어 하나의 어플리케이션이 실행될 수 있도록 모아져있

  • 명령어 docker pull, docker run 등을 통해 Docker Hub 같은 저장소에서 가져올 수 있음

 

컨테이너 이미지 구조 상세

https://citronbanana.tistory.com/193

 

  1. 컨테이너 VS 컨테이너 이미지

구분

컨테이너 이미지

컨테이너

구분

컨테이너 이미지

컨테이너

정의

실행을 위한 설계도

실제 실행 중인 인스턴스

형태

파일 (Read-Only)

프로세스 (Read/Write)

저장 위치

하드디스크

메모리

명령어

docker pull, build

docker run, start, stop

image-20250521-134853.png

 

  1. 컨테이너와 컨테이너 이미지 동작 방식

  • Docker Hub 등에서 이미지 다운로드 (docker pull)

  • 컨테이너 생성 및 실행 (docker run)

  • 이미지 기반으로 컨테이너가 메모리에서 프로세스로 실행됨

  • 호스트 입장에서는 컨테이너가 하나의 격리된 프로세스로 보임

image-20250521-135444.png

 

  1. 용어 정리

  • 컨테이너 이미지 : 디스크에 저장된 정적인 구성 정보 (읽기 전용)

  • 컨테이너 : 이미지를 기반으로 실행된 동적 프로세스 (읽기/쓰기 가능)

  • Docker Daemon : 이미지를 관리하고, 컨테이너를 실행하는 핵심 엔진

  • Docker Client : 사용자가 명령을 입력하는 인터페이스

  • Docker Host : 위 모든 것이 동작하는 머신

  • Docker Hub : 이미지 저장소


컨테이너 만들기

  1. 무엇으로 컨테이너를 만드는가

  • 컨테이너 하나 = 하나의 애플리케이션

  • 애플리케이션이 실행되기 위해선 다음 구성요소 필요:

    1. 운영 환경 (런타임): 예) Node.js, Python, PHP 등

    2. 애플리케이션 소스 코드: app.js, main.py

    3. 실행 명령어: 컨테이너 시작 시 실행될 명령어

  • 예시:

    • 쇼핑몰 전체 플랫폼 → 다양한 기능별 컨테이너로 구성 (쇼핑카트, 주문 서비스, 상품관리 등)

    • 각 컨테이너는 적절한 언어/프레임워크를 기반으로 구성

    • 이 방식은 마이크로서비스 아키텍처(MSA) 로 확장 가능

image-20250521-144501.png

 

  1. 컨테이너는 어떻게 만드는가 → Dockerfile

  • Dockerfile : 컨테이너 이미지를 생성하기 위한 설정 명령어 모음파일일

  • 자주 쓰는 명령어:

    • FROM: 기반 이미지 (예: node:14)

    • COPY: 소스코드 복사

    • CMD: 컨테이너 실행 시 실행할 명령어

지시어

의미

지시어

의미

FROM

베이스 이미지 지정 (운영 환경)

COPY / ADD

소스코드 또는 파일 복사

CMD / ENTRYPOINT

컨테이너 실행 시 실행될 명령

WORKDIR, ENV, USER, EXPOSE, VOLUME 등도 자주 사용됨

 

image-20250521-143320.png

 

  1. 컨테이너를 배포하기

  • 컨테이너 이미지를 다른 사람들과 공유하려면 레지스트리(Hub) 에 등록

  • 대표적인 레지스트리:

image-20250521-143817.png
  • 배포 절차 순서

    • docker login (허브 로그인)

    • docker build (이미지 생성)

    • docker push (허브에 업로드)


컨테이너 보관함

  1. Container Registry

  • 컨테이너 이미지를 저장하는 저장소

  • 컨테이너 이미지들을 모아두고 필요할 때 가져다 씀 (pull), 새로 올리기도 함 (push)

    • Docker Hub (공개/퍼블릭) : hub.docker.com에서 제공하는 공식 저장소

    • Private Registry (사내/프라이빗) : 보안, 내부 배포 목적으로 회사 내부에서 직접 운영하는 저장소. Docker Hub와는 달리 외부에 노출되지 않음.

 

  1. Docker Hub (공개/퍼블릭)

 

  1. Private Registry (사내/프라이빗)

Docker Hub에서 registry 컨테이너를 사용

  • 명령 예시:

docker run -d -p 5000:5000 --restart=always --name registry registry:2

 

  • 이미지를 push할 때는 이름 앞에 Registry 주소 (IP:Port)를 붙임

docker tag myapp localhost:5000/myapp docker push localhost:5000/myapp

컨테이너 실행 라이프사이클

image-20250522-015424.png
  1. 컨테이너 이미지 사용

  • 검색 : docker search <이미지명>

  • 다운로드 : docker pull <이미지명[:태그]>

  • 목록 확인 : docker images

  • 상세 정보 : docker inspect <이미지명>

  • 삭제 : docker rmi <이미지명>

 

  1. 컨테이서 실행하기 (이미지 → 싫행 중인 컨테이너 만들기)

이미지는 Disk에 저장되고, 컨테이너로 만든 다음 실행을 해줘야 메모리 위에 올라감

  • 컨테이너 생성 : docker create --name <이름> <이미지>

  • 컨테이너 실행 : docker start <컨테이너 이름>

  • 이미지 Pull+Create+Start 한번에 실행 : docker run --name <이름> <이미지>

  • 컨테이너 종료 : docker stop <이름>

  • 컨테이너 삭제 (이미지는 유지) : docker rm <이름>

 

  1. 동작중인 컨테이너 상태 확인

  • 목록 조회 : docker ps (-a 로 종료된 컨테이너까지 포함)

  • 상세 확인 : docker inspect <컨테이너 이름> → inspect 명령어는 이미지도 가능

  • 로그 보기 : docker logs <컨테이너 이름>

  • 프로세스 확인 : docker top <컨테이너 이름> → 컨테이너 내 실행중인 프로세스 조회

  • 명령 원격 실행 : docker exec -it <컨테이너> bash (접속)

  • 중지/재시작 : docker stop, docker start, docker restart


Docker 컨테이너 리소스 관리

  1. 리소스 제한의 필요성

  • 컨테이너는 기본적으로 호스트 리소스(CPU, 메모리, 디스크)를 제한 없이 모두 사용 가능함

  • 여러 컨테이너가 동시에 실행될 경우 리소스 쟁탈이 발생함 → 일부 컨테이너가 과도하게 리소스 사용 가능

  • 따라서 컨테이너 실행 시 적절한 리소스 제한(쿼터) 설정이 요구됨

 

  1. 메모리 리소스 제한

  • 예) docker run -m 512m nginx

옵션

설명

옵션

설명

--memory 또는 -m

최대 사용 메모리 크기 (예: 512m)

--memory-reservation

최소 보장 메모리

--memory-swap

메모리 + 스왑 공간의 총합 제한 (즉, 스왑 = memory-swap - memory)

  • --memory=512m → 실제 물리 메모리 제한은 512MB

  • --memory-swap 생략 → 메모리 + 스왑 합쳐서 최대 1024MB까지 가능

--oom-kill-disable

메모리 부족 시 강제 종료 방지 (OOM Kill 방지)

  • default 경우 제한된 리소스 임계치를 초과하면 강제 kill되었음

  1. CPU 리소스 제한

  • 예) docker run --cpus=1.5 nginx

옵션

설명

옵션

설명

--cpus

사용할 CPU 비율 (예: 0.5는 50%만 사용)

--cpuset-cpus

특정 CPU 코어만 지정 (예: 0,1)

--cpu-shares

상대적 CPU 점유 비율 (기본: 1024)

  1. Disk I/O 리소스 제한

옵션

설명

옵션

설명

--blkio-weight

I/O 우선순위 (10~1000, 기본: 500)

--device-read-bps

초당 읽기 속도 제한 (예: 10mb)

--device-write-bps

초당 쓰기 속도 제한

--device-read-iops

초당 읽기 IOPS 제한

--device-write-iops

초당 쓰기 IOPS 제한

  1. 컨테이너 리소스 모니터링 도구

명령어

설명

명령어

설명

docker stats

실시간으로 컨테이너 CPU, 메모리, I/O 사용량 확인

docker events

컨테이너 관련 이벤트 실시간 모니터링 (시작, 중지 등)

cAdvisor

구글에서 만든 컨테이너 리소스 모니터링 웹 툴 (별도 설치)


Docker Container Storage

  1. Container Volume

  • 컨테이너 이미지 → 읽기 전용(Read-only)

  • 컨테이너가 실행이 되어야만 읽고 쓰기 가능한 레이어(Read/Write Layer) 가 추가됨.

  • 이 데이터는 컨테이너가 삭제되면 함께 사라짐 → 영구 저장 불가함

 

  1. 데이터를 영구족으로 보존하기

  • 호스트 디스크에 별도 저장공간을 마련해서 마운트(연결) 해야 함.

  • → 컨테이너 안에서 생성된 데이터가 호스트 디스크에 저장되기 때문에 컨테이너가 삭제돼도 데이터는 보존

  • 예) docker run -v /host/db:/var/lib/mysql ...

-v 옵션 사용:

docker run -v [호스트 디렉토리]:[컨테이너 디렉토리] ...
image-20250523-021732.png

 

  • 보안상 읽기 전용 마운트(Read-only) 도 가능

  • 예) docker run -v /host/web:/usr/share/nginx/html:ro ...

 

  1. 볼륨 종류

  • 바인드 마운트: 호스트 디렉토리 지정

  • 익명 볼륨: 호스트 경로 생략 → Docker가 임시 위치 자동 생성

  • 네임드 볼륨: Docker가 관리하는 이름 있는 저장소 사용 (docker volume create 등)

 


컨테이너 간 통신

  1. 컨테이너 네트워크 구조

  • 컨테이너는 기본적으로 docker0 브리지 네트워크(172.17.0.1)를 통해 통신함. → 게이트웨이 역할

  • 컨테이너에 내부 IP (172.17.0.x)가 자동 할당됨

  • 브리지 네트워크는 NAT와 포트포워딩을 통해 외부와 통신 가능.

image-20250526-002943.png

 

  1. 컨테이너 포트를 외부로 노출

웹 기반의 서비스의 경우 외부에서 컨테이너의 80 포트로 연결되어야 함 이럴 때 어떻게 통신이 이루어지는가

docker run -p [호스트포트]:[컨테이너포트] docker run -p [컨테이너포트] --> 호스트포트는 랜덤매칭됨 docker run -P --> 컨테이너에서 EXPOSE된 포트가 자동 매핑됨.
  • 예 ) docker run --name web -d -p 80:80 nginx:1.14

  • -p 8080:80 → 호스트 8080 요청이 컨테이너의 80번 포트로 전달됨.

  • 동일한 호스트 포트를 여러 컨테이너에 할당할 수는 없음

  • 포트포워딩 결과는 iptables 에서 확인 가능 (iptables -t nat -L -n -v)

 

  1. 컨테이너에 Static IP 를 할당하는 방법

User Defined Bridge Network를 생성해 원하는 대역의 네트워크와 Static IP 지정 가능

단, User Defined Bridge Network를 생성하지 않으면 지정 불가함

$docker network create --driver bridge \ --subnet 192.168.100.0/24 \ --gateway 192.168.100.254 \ mynet

 

이 네트워크를 사용할 경우, 컨테이너에 스태틱 IP도 지정 가능.

$docker run -d --name web -p 80:80 \ nginx1.14 $docker run -d --name appjs \ --net mynet --ip 192.168.100.100 \ -p 8080:8080 \ smlinux/appjs
image-20250526-010758.png

 

  1. 컨테이너끼리 통신

  • 같은 브리지 네트워크에 속하면 컨테이너 이름으로 통신 가능.

  • 또는 --link 옵션을 통해 컨테이너 간 통신 설정 가능 (구버전 방식).

  • 예: WordPress 컨테이너에서 MySQL 컨테이너로 연결

    $docker run -d --name mysql \ -v /dbdata:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=wordpress \ -e MYSQL_PASSWORD=wordpress mysql:5.7 $docker run -d --name wordpress --link mysql:mysql \ -e WORDPRESS_DB_PASSWORD=wordpress -p 80:80 wordpress:4

    WordPress는 MySQL에 링크된 mysql 호스트명으로 접근 가능하게 됨

image-20250526-004603.png

Docker Compose

  1. Docker Compose란

컨테이너를 실행할 때 지정하는 옵션 등을 YAML 파일로 만들어서 Docker Compose가 실행하게 됨

  • 여러 개의 컨테이너를 일괄적으로 정의하고 실행할 수 있는 도구

  • docker run 명령을 대신해 여러 설정을 YAML 파일에 정의

  • YAML 파일을 기준으로 이미지, 포트, 볼륨, 링크, 환경변수 등을 지정 가능

  • Compose 명령어들:

    • docker-compose up : 전체 컨테이너 실행

    • docker-compose ps : 실행 상태 확인

    • docker-compose stop / down : 컨테이너 중지/삭제

    • docker-compose logs : 로그 보기

    • docker-compose scale : 서비스 인스턴스 개수 조절

 

  1. YAML 작성하기

https://docs.docker.com/reference/samples/ 여기서 예제 YAML 파일이 제공됨

 

  1. 도커 컴포즈로 빌드부터 운영까지

  • 1단계 : 서비스 디렉토리 생성

$ mkdir composetest $ cd composetest

 

  • 2단계 : 빌드를 위한 Dockerfile 생성

$ cat > Dockerfile FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP=app.py ENV FLASK_RUN_HOST=0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt EXPOSE 5000 COPY . . CMD ["flask", "run"]

 

  • 3단계 : docker-compose.yml 생성

$ cat > docker-compose.yml version: "3" services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"

 

  • 4단계 : docker-compose 명령어 실행

$ docker-compose up -d
image-20250526-021515.png