본문 바로가기

개발기술/빌드, 배포, 운영

Docker 개념 및 커맨드

가상화(Virtualization) vs. 컨테이너(Containerization)

  • 가상화: 하나의 물리 시스템(호스트)에서 하드웨어 자원을 소프트웨어적으로 나누어 여러 개의 독립된 컴퓨팅 환경(가상 머신, VM)을 생성하는 기술. 하이퍼바이저라는 소프트웨어가 지원. 각 가상머신은 독립적인 컴퓨팅 환경으로 독립적인 OS를 갖고 어플리케이션 실행가능.
    • 독립된 환경 : 자원, OS, 커널, 파일 시스템 등 모든 것이 완전하게 분리됨.
  • 컨테이너 : 애플리케이션과 그 실행에 필요한 필요한 모든 실행 환경(코드, 라이브러리, 시스템 도구 등)을 패키징하여 실행하는 경량화된 가상화 기술. 주로 리눅스 컨테이너 기술(Linux Containers, LXC) 기반. 각 컨테이너는 독립적인 OS가 아니라 OS 커널을 공유하면서 격리된 환경을 갖음.
    • 격리된 환경 :같은 OS에서 라이브러리와 실행 환경을 독립적으로 관리하지만, OS 자체는 공유.

도커 생태계 

  • 도커 :  도커는 컨테이너 기술을 기반으로 애플리케이션이 서로 격리된 환경에서 실행될 수 있도록 지원하는 컨테이너 플랫폼입니다.
  • 도커 사용 이유:
    1. 환경일관성 :  표준화된 실행 환경을 포함해 일관된 결과 제공.  ( JVM 같은 실행환경, OS일관성, JVM 설정관리 등)
    2. 배포 간소화 : 모든 설정과 환경이 포함된 Docker 이미지를 배포하면 끝
    3. 유연한 설정관리 :  JVM 옵션이나 환경 변수를 컨테이너 실행 시 커맨드로 동적으로 변경 가능
  • 컨테이너와 이미지 관계:
    • 이미지 : 이미지는 컨테이너를 생성하기 위한 템플릿입니다. 애플리케이션 실행에 필요한 모든 코드, 라이브러리, 의존성, 설정 파일 등이 포함된 읽기 전용 파일 시스템입니다. 
      • 이미지는 도커 허브(Docker Hub) 또는 다른 레지스트리에서 다운로드하거나, 직접 작성한 Dockerfile로 빌드 가능. 이미지를 빌드하는 것은 마치 Jar를 환경으로 감싸는(Container화)하는 개념으로 생각하면 유용.
    • 도커 컨테이너 :  이미지를 실행한 인스턴스입니다.
    • 도커 레지스트리 : 도커 이미지를 저장하고 다운로드할 수 있는 저장소. 도커 허브는 대표적인 공개 레지스트리

도커 허브 

 

  Docker Hub는 컨테이너 이미지를 저장하고 공유할 수 있는 레지스트리이며, **퍼블릭 저장소(public)**와 **개인 저장소(private)**를 제공한다. 개인 저장소는 로그인이 필요한 사용자만 접근 가능하도록 설정할 수 있다.

 

  • Docker Hub 로그인 : docker login -u <your-dockerhub-username>
  • Docker Hub 개인 저장소에 푸쉬 (Push) : docker push <your-dockerhub-username>/<your-app>:<tag>
  • Docker Hub 개인 저장소에서 풀 (Pull) : docker pull <your-dockerhub-username>/<your-app>:<tag>
  •  : 도커 이미지를 저장하고 다운로드할 수 있는 저장소. 도커 허브는 대표적인 공개 레지스트리

 

도커 셋팅순서

  1. Dockerfile 작성: 애플리케이션(jar)을 도커 이미지로 만들기 위한 Dockerfile을 작성합니다.
  2. dockerfile 실행하여 도커이미지 생성 ; docker build
  3. Docker Compose 설정:  dockerfile로 생성된 이미지들을 한꺼번에 설정하고 관리하기위한 파일생성 ; docker composeup
  4. 배포 실행: docker-compose up 명령어를 사용해 모든 컨테이너를 동시에 실행합니다.

 

Dockerfile 설정

Dockerfile은 Docker 이미지를 커스터마이징하여 빌드하기 위한 설정 파일입니다.

# 베이스 이미지를 선택
FROM python:3.9-slim

# 애플리케이션 파일을 컨테이너 내부로 복사
COPY app.py /app/

# 의존성을 설치
RUN pip install flask

# 애플리케이션 실행 명령어
CMD ["python", "/app/app.py"]
FROM openjdk:17
EXPOSE 8080
RUN mkdir -p deploy
WORKDIR /deploy
COPY user/build/libs/user-0.0.1-SNAPSHOT.jar api.jar
ENTRYPOINT ["java", "-jar", "/deploy/api.jar", "--spring.profiles.active=dev"]
  • FROM: 베이스 이미지를 지정합니다. (python:3.9-slim 이미지를 기반으로 함).
  • WORKDIR /deploy : 이후의 모든 명령(COPY, ENTRYPOINT 등)은 /deploy 디렉토리에서 실행됩니다.
  • COPY :로컬 파일(app.py)을 컨테이너의 /app/ 경로로 복사.
    • /app/가 컨테이너 내부에 존재하지 않을시 폴더를 생성해준다. 
  • RUN: 이미지 빌드 과정 중 실행할 명령어(여기서는 pip install로 Flask 설치).
    • RUN mkdir -p deploy : 컨테이너 내부에 /deploy 디렉토리를 생성합니다.
      • -p 옵션은 디렉토리가 이미 존재해도 에러 없이 넘어가며, 경로 상의 필요한 모든 디렉토리를 생성합니다.
  • run : 이미지 빌드 과정에서 명령 실행,  
  • ENTRYPOINT : 컨테이너 실행 시 고정 명령 설정
  • EXPOSE 8080 : 컨테이너 내부에서 사용할 포트 지정 (호스트 포트와 매핑 X)
    • 호스트 포트와 매핑은 Docker run 동작시 -p 옵션으로 설정해야 합니다.
docker run -p 8080:8080 <image>
  • COPY: 로컬 파일(app.py)을 컨테이너의 /app/ 경로로 복사.

Docker Compose 설정

  • Docker Compose는 이미지로부터 여러 Docker 컨테이너를 함께 정의하고 실행할 수 있도록 돕는 도구입니다.  여러 개의 Docker 컨테이너를 한꺼번에 실행/관리할 수 있게 도와주는 도구
    • 단일 YAML 파일(docker-compose.yml)에 컨테이너의 설정, 네트워크, 볼륨 등을 정의하여 관리와 실행을 단순화할 수 있습니다. 즉, 여러 개의 docker run 명령`어를 대체하는 역할을 합니다.
    • 네트워크 관리: : Docker Compose는 컨테이너 간의 통신을 위한 네트워크를 자동으로 설정하고, 컨테이너 이름을 호스트명으로 사용하도록 지원합니다.
    • 리소스 자동화: 의존성 있는 서비스(depends_on)를 올바른 순서로 실행. 재사용 가능한 네트워크 및 볼륨을 자동으로 관리.
version: '3.8'  # Docker Compose 파일의 버전

services:       # 서비스 정의
  app:          # 서비스 이름
    image: zerobase-heritage # 사용할 Docker 이미지
    ports:       # 호스트와 컨테이너 간의 포트 매핑
      - "8080:8080"
    environment: # 환경 변수
      - SPRING_PROFILES_ACTIVE=dev
    volumes:     # 볼륨 마운트
      - ./app-data:/app/data
    networks:    # 네트워크 설정
      - my-network

  db:           # 데이터베이스 서비스
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: zerobase_heritage
      MYSQL_USER: testuser
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"
    networks:
      - my-network

 

  • version : Compose 파일의 버전을 명시합니다. : 최신 버전: '3.8'.
  • services : 애플리케이션의 각 컨테이너를 정의하는 섹션으로 각 이름은 임의로 정할 수 있으며 Docker Compose 내부에서 사용되는 서비스 이름입니다.
  • image : 사용할 Docker 이미지를 지정합니다.
  • ports:호스트와 컨테이너 간의 포트를 매핑합니다.
  • volumes:  컨테이너를 삭제하거나 재시작하면 내부의 데이터도 사라지므로, 데이터를 영구적으로 저장하기 위해 볼륨 마운트를 사용합니다.
  • environment : 환경 변수를 설정합니다.
  • depends_on : 의존성을 설정하여 특정 서비스가 먼저 실행되도록 보장합니다.
  • networks :  컨테이너를 my-network라는 네트워크에 연결합니다. 같은 네트워크에 있는 다른 컨테이너와 통신 가능하며, DNS 이름(서비스 이름)을 통해 접근합니다.복잡한 네트워크 구성이 필요하면 networks 섹션에서 세부 설정(서브넷, 고정 IP 등)을 추가가능
  • command : 컨테이너가 실행될 때 실행할 명령어를 정의합니다.

 

도커의 데이터 처리

  도커 컨테이너와 외부 파일(또는 호스트 시스템) 사이의 데이터 처리에 쓰이는 대표적인 기능으로 volume과 COPY가 있음. 각각 사용목적과 시점이 다름

항목 COPY volume
목적 이미지 생성 시 파일 복사 컨테이너 실행 시 외부와 파일 공유
시점 Dockerfile 단계 docker-compose.yml or docker run 시
주 용도 앱 소스코드, 설정파일 포장 DB, 로그, 개발 중 파일 연결
한계 수정 불가 (이미지 내부로 복사됨) 실시간 수정 가능 (호스트와 공유됨)

 

  • COPY  : Dockerfile에서 이미지에 파일을 "포장"
    • 현재 디렉토리의 app 폴더를 이미지 안의 /app 경로로 복사함.
    • 앱 실행에 필요한 파일, 설정 등을 빌드 시점에 넣는 용도야. 이미지 안에 고정되므로 실행 중 수정 불가.
COPY ./app /app

 

  • volume — 실행 중 외부 경로와 연결
    • 로컬 디렉토리 ./app을 컨테이너의 /app에 연결.
    • 양방향 실시간 반영 가능.
    • docker compose를 통해서 실행하거나 명령어 docker -v ./uploads:/app/uploads myapp을 통해서 설정가능
    • 볼륨마운트 옵션 : <옵션>에 ro 또는 rw를 명시할 수 있음
      • ro : read-only (읽기 전용)
      • rw : read-write (기본값 생략가능, 읽기/쓰기 허용)
services:
    app:
        image: myapp
        volumes:
              - ./app:/app
docker run -v <호스트 경로>:<컨테이너 경로>:<옵션> 이미지이름

 

 

 

Kubernetes

컨테이너 오케스트레이션(Container Orchestration)은 여러 개의 컨테이너를 자동으로 배포, 관리, 확장, 복구하는 기술을 의미.  Compose는 여러개의 컨테이너를 실행시킬 수 있어 로컬 환경에 적합하지만, 쿠버네틱스는 운영 환경에서 컨테이너를 자동으로 관리, 복구, 확장하는 기능까지 포함하여 운영환경에 더 적합.

 

 

 

 

 

도커 주요 명령어

 

주요 FLow : 도커 이미지생성 - 도커 컨테이너 실행/compose 파일 실행

 

 

  •  1. 이미지(Image) 관련 기능
    •  docker image pull [이미지 이름]: 레지스트리에서 이미지 가져오기
      • - 레포지토리 정보를 생략하면 도커의 공식 허브레포지토리에서 가져오게됨, 태그정보도 생략하면 최신의 정보를 가져옴.
    •  docker image rm [이미지 ID]: 이미지 제거
    • docker image ls: 보유한 이미지 목록 확인
    • docker build [OPTIONS] PATH : 도커파일로부터 이미지 빌드
      • -t tag-name :   이미지를 빌드하면서 이름과 태그를 지정.
      • -f Dockerfile.dev: 디폴트로 Dockerfile을 찾지만  사용할 Dockerfile을 명시적으로 지정합니다. 환경별로 다른 설정의 dockerfile을 사용할때 유용

 

 

  • 2. 컨테이너 시작 : 이미지를 기반으로 컨테이너를 실행하고, 컨테이너의 상태를 관리.
    • docker create : 컨테이너를 생성
    • docker start CONTAINER_ID : 컨테이너가 생성되어있지만 실행이 되지 않을때 사용
    • docker restart CONTAINER_ID : 컨테이너 재시작
    • docker run [option] IMAGE `: create와 start 동작을 한번에 실행시키는 명령어. 이미지가 없으면 자동으로 레포지토리에서 pull하는 방식으로 동작함.
      • 예) docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=test -d -p 3306:3306
      • --rm : 컨테이너가 종료되면 자동으로 삭제 
      • -it : 도커바깥의 현재 프로세스터미널에서 도커 내부로 인터랙티브 실행 + 터미널 출력 가능
      • --name container-name : 실행하는 컨테이너에 이름을 명명할 수 있음 
      • -e enviroenment-variable = value : 환경변수를 설정해줌
        • 명령어에 사용된 환경변수(예: MYSQL_ROOT_PASSWORD)는 사용자가 임의로 정의한 것이 아니라, MySQL Docker 이미지에서 미리 정의된 필수 환경변수입니다.
          • MYSQL_PASSWORD (선택): MYSQL_USER로 생성된 사용자에 할당할 비밀번호를 지정합니다.
          • MYSQL_USER (선택): 새로 생성할 사용자 이름을 지정합니다
          • MYSQL_DATABASE (선택): 컨테이너 시작 시 생성할 데이터베이스 이름을 지정합니다.
      • -d : 도커는 기본적으로 포그라운드로 실행되어 터미널을 종료하면 같이 꺼짐, 본 옵션으로 데몬으로 실행
      • -p  <호스트포트>:<컨테이너포트> : port forwarding 정보를 입력, host의 포트와 guest의 포트셋팅 정보를 입력함.
        • Docker는 기본적으로 컨테이너 네트워크를 브릿지(Bridge) 모드로 실행하며, -p 옵션을 사용하면 자동으로 localhost를 통해 연결 가능하게 설정됨, 
      • -v ${PWD}:/app : (volume): Mounts a folder from your host system into the container.
        • This allows the container to access files from your local system.
  • 2.1 docker compose 
    • docker compose up : 컨테이너 빌드 + 실행 (YAML 기반)
    • docker compose up -d : 백그라운드 실행 (daemon mode)
    • docker compose down : 컨테이너 중지 + 네트워크, 볼륨 정리
    • docker compose -f docker-compose.yml up : -f 옵션으로 YAML 파일명 지정 가능
  • 3. 컨테이너 동작 : 이미지를 기반으로 컨테이너를 실행하고, 컨테이너의 상태를 관리.

 

  • docker exec -it [컨테이너 이름] bash:  Run a Command in an Running Container. 
    • docker exec -it  [컨테이너 이름] bash: Docker는 컨테이너를 대상으로 명령어 /bin/sh를 실행합니다. 
    • docker exec -it my-mariadb mysql -u root -p : Docker는 컨테이너 대상으로 mysql 명령어를 실행하고 root계정으로 접속합니다.
       
    • -it
      • -i (interactive):  표준 입력(키보드)을 활성화하여 사용자가 입력을 할 수 있게 합니다.
      • -t (tty): 터미널(TTY) 세션을 생성하여 사용자와 컨테이너 간 상호작용이 가능하도록 합니다.
        • -it 명령어는 백그라운드 모드가 아니라 사용자와 직접 상호작용하기 위해서 세션을 생성하는 것
    • /bin/sh : 컨테이너 내부에서 실행할 명령입니다. 여기서는 셸(Shell)을 실행하여 사용자가 컨테이너 내부 환경에 접속하도록
  • docker cp : copy files from your host machine to the running container  
    • docker cp "C:/Users/bsh62/OneDrive/바탕 화면/Linux-2024.2.5" my-container:/app

 

  • 4 컨테이너 관리 
    • docker stop CONTAINER_ID : 컨테이너 종료
      • docker stop $(docker ps -q) : 현재 실행중인 모든 컨테이너 종료
    • docker rm <container-id> : 중지된 컨테이너 삭제
    • docker container prune : 모든 중지된 컨테이너 삭제
    • docker ps(process) : 실행되고있는 컨테이너의 리스트 및 상태의 조회
      • docker ps -a : 중지된 모든 컨테이너까지 조회하기
    • docker logs [컨테이너 이름]: 컨테이너 로그 확인

 

  • 5. 네트워크(Network) 관련 기능.
    • Docker에는 여러 가지 네트워크 모드가 있지만, 기본적으로 컨테이너는 bridge 네트워크 모드를 사용함.
      •  컨테이너끼리 격리된 네트워크를 구성하는 기본 네트워크 모드. 호스트(로컬 컴퓨터)와 연결할 수 있도록 브릿지를 생성하여 통신 가능
      • bridge 네트워크는 호스트 OS(로컬 컴퓨터)와 컨테이너 간 가상 네트워크를 제공하지만, 외부 네트워크에는 자동으로 노출되지 않음.
      • 외부에서 접근가능하도록 하려면 1. 방법 : -p 0.0.0.0:<포트>:<컨테이너포트>로 실행 (외부 연결 허용) 2. 방법 2: Docker 방화벽(iptables)에서 포트 허용
    • 4.1 기본 네트워크 사용 : 도커가 제공하는 기본 브리지 네트워크를 사용하여 컨테이너 간 통신.
    • 4.2 커스텀 네트워크 설정 : 사용자 정의 네트워크를 생성하여 컨테이너 간 통신을 세밀하게 제어.

 

 

 

'개발기술 > 빌드, 배포, 운영' 카테고리의 다른 글

원격제어  (0) 2025.03.13
Jenkins CI/CD 자동화  (0) 2025.01.26
빌드와 Gradle 개념, Gradle 빌드 사용법  (0) 2024.11.12
빌드 후 서버 배포  (0) 2024.11.12
리눅스  (0) 2024.01.24