본문 바로가기

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

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 컨테이너를 함께 정의하고 실행할 수 있도록 돕는 도구입니다.
  • 단일 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 : 컨테이너가 실행될 때 실행할 명령어를 정의합니다.

 

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 동작을 한번에 실행시키는 명령어. Creates a new container from an image.
      • 이미지가 없으면 자동으로 레포지토리에서 pull하는 방식으로 동작함.
      • 예) docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=test -d -p 3306:3306
      • --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.
    •  docker-compose up : docker compose를 통해서 docker run을 진행함. 

 

 

  • 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 커스텀 네트워크 설정 : 사용자 정의 네트워크를 생성하여 컨테이너 간 통신을 세밀하게 제어.

 

 

 

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

Jenkins CI/CD 자동화  (0) 2025.01.26
Gradle 빌드 사용법  (0) 2025.01.02
빌드와 Gradle 개념  (0) 2024.11.12
빌드 파일 서버 배포  (0) 2024.11.12
리눅스  (0) 2024.01.24