본문 바로가기
Docker

Docker Compose 멀티 컨테이너 관리

by 정권이 내 2024. 10. 25.

Docker Compose

img

Docker Compose는 여러 개의 Docker 컨테이너를 손쉽게 정의하고 실행할 수 있게 해주는 도구입니다. 일반적으로 docker-compose.yml 파일을 사용하여 컨테이너의 서비스, 네트워크, 볼륨 등을 정의한 후, 단일 명령어로 모든 컨테이너를 관리할 수 있습니다.

여러 컨테이너가 상호작용해야 하는 멀티 컨테이너 애플리케이션에서 특히 유용합니다.

 

주요 개념

  1. 서비스 (Service): 애플리케이션의 컨테이너를 의미하며, 각 서비스는 하나의 컨테이너를 나타냅니다.
  2. 네트워크 (Network): 컨테이너들이 서로 통신할 수 있도록 네트워크를 설정합니다.
  3. 볼륨 (Volume): 컨테이너의 데이터를 지속적으로 저장할 수 있는 스토리지입니다.

 

Docker Compose 구성 요소

1. version

  • Docker Compose 파일의 형식을 정의하는 버전을 나타냅니다.
  • yml 파일을 해석하고, 지원하는 구문과 기능을 결정하는 기준이 됩니다.

 

2. servies

  • 각 서비스는 Docker에서 실행되는 개별 애플리케이션 컨테이너를 의미합니다
  • 애플리케이션 이름을 지정하고, 해당 애플리케이션에 사용할 이미지, 포트 설정, 환경 변수, 종속성 등을 정의할 수 있습니다
services:
  web:
    image: nginx
    ports:
      - "80:80"
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example

 

3. networks

  • Docker Compose 내에서 서비스 간의 네트워크를 정의합니다.
  • 서비스 간의 통신을 위한 별도의 네트워크를 설정할 수 있으며, 기본적으로 bridge 네트워크가 사용됩니다.
  • 각 서비스는 특정 네트워크에 연결할 수 있으며, 여러 네트워크에 연결하는 것도 가능합니다.
networks:
  frontend:
  backend:

 

4. volumes

  • 컨테이너에 영구 데이터를 저장할 수 있도록 디스크 볼륨을 설정합니다.
  • volumes는 호스트와 컨테이너 간의 데이터를 공유하거나 컨테이너 재시작 후에도 데이터를 유지하도록 합니다.
volumes:
  db-data:

 

Docker compose 버전 종류

version은 Docker Compose 파일의 형식을 정의하는 버전을 나타냅니다 버전 별로는 다음과 같은 특징들이 있습니다.

 

version1

  • version을 명시하지 않거나 생략하면 기본적으로 Version 1으로 간주됩니다.
  • 가장 기본적인 구문 구조를 제공하며, 서비스 정의만 지원하고 networksvolumes의 구체적인 설정은 지원하지 않습니다.
  • 모든 서비스는 기본 bridge 네트워크를 공유하며, 외부 네트워크 구성이나 볼륨 관리는 제한적입니다.
  • 현재는 거의 사용되지 않으며, 이후 버전으로 전환이 권장됩니다.
# Version 1의 경우, 명시적으로 version을 표기하지 않습니다.
web:
  image: nginx
  ports:
    - "80:80"
db:
  image: mysql:5.7
  environment:
    MYSQL_ROOT_PASSWORD: example

 

version2

  • Docker Compose 1.6부터 도입되었으며, version: "2"로 명시하여 사용합니다.
  • networksvolumes를 별도로 정의할 수 있어, 서비스 간 네트워크 격리 및 데이터 영속성을 지원합니다.
  • 각 서비스에 대해 depends_on 키를 사용해 서비스 간 의존 관계를 지정할 수 있지만, 구체적인 시작 순서는 제어하지 않습니다.
  • Docker가 설치된 시스템에서 직접 실행되며, 클러스터 기능은 제공하지 않습니다.
version: "2"

services:
  web:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frontend

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - backend

networks:
  frontend:
  backend:

volumes:
  db-data:

 

version3

  • Docker Compose 1.13부터 도입되었으며, Swarm 모드와 호환성을 제공합니다. version: "3" 또는 version: "3.x"로 명시해 사용합니다.
  • deploy 키가 추가되어 각 서비스의 배포 설정을 정의할 수 있으며, replicas, resources(메모리, CPU 할당 등) 같은 설정을 지원해 Docker Swarm 환경에서의 확장이 가능합니다.
  • depends_on 키는 여전히 존재하지만, Version 3에서는 서비스 간 의존성을 보다 세밀하게 제어하기 위해 healthcheck 설정을 사용하는 것이 권장됩니다.
version: "3.8"

services:
  web:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frontend

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - backend
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.5"
          memory: "512M"

networks:
  frontend:
  backend:

volumes:
  db-data:

 

docker engine, docker-compose 버전 대응

Compose File FormatDocker Engine Release
3.920.10.0+
3.819.03.0+
3.718.06.0+
3.618.02.0+
3.517.12.0+
3.417.09.0+
3.317.06.0+
3.217.04.0+
3.11.13.1+
31.13.0+
2.417.12.0+
2.317.06.0+
2.21.13.0+
2.11.12.0+
21.10.0+
11.9.1+

 

Docker compose 내부 네트워크

Docker compose로 실행된 복수개의 컨테이너들은 network설정에 따라 서로 같은 네트워크에 존재하여 컨테이너간 내부 통신이 가능합니다.

 

Docker Compose의 네트워크 설명

  • Docker Compose는 기본적으로 각 프로젝트에 대해 고유한 브리지 네트워크를 생성합니다.
  • 같은 Compose 파일에서 정의된 서비스는 이 네트워크에 자동으로 연결됩니다.
  • 이 네트워크 내에서는 각 컨테이너가 서비스 이름을 통해 서로를 인식할 수 있습니다.

 

내부 네트워크 예시 docker-compose.yml

version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
  
  app:
    image: my-spring-boot-app:latest
    ports:
      - "8081:8080"

 

통신 방법

  • web 컨테이너(Nginx)는 app 컨테이너(Spring Boot)와 같은 네트워크에 있습니다.
  • web 컨테이너에서 app 컨테이너로 접근할 때, app:8080이라는 방식으로 접근할 수 있습니다.
  • 여기서 app은 서비스 이름을 의미하며, Docker가 이 이름을 내부 IP 주소로 자동으로 변환합니다.

 

예상 시나리오

  • web(Nginx) 컨테이너가 리버스 프록시로 설정된 경우
server {
    listen 80;
    location / {
        proxy_pass http://app:8080;
    }
}

여기서 proxy_pass http://app:8080;는 Nginx가 내부 네트워크를 통해 app 서비스(Spring Boot 컨테이너)에 요청을 전달한다는 뜻입니다.

 

외부와 내부 네트워크의 차이

  • 외부 네트워크: 컨테이너 외부에서 접근하기 위해 포트를 매핑합니다 (예: 8080:80, 8081:8080).
  • 외부 네트워크에서는 호스트의 IP 주소나 localhost를 통해 접근합니다.
  • 내부 네트워크: Docker Compose가 생성한 네트워크 내에서 서비스 이름을 통해 접근합니다. IP 주소 대신 서비스 이름으로 접근이 가능하므로 더 편리합니다.

 

Docker compose 명령어

Docker Compose는 다음과 같은 명령어로 애플리케이션을 관리할 수 있습니다.

 

docker-compose build

docker-compose.yml 파일에 정의된 서비스들의 이미지를 빌드하는 데 사용됩니다. 로컬에서 Dockerfile을 기반으로 이미지를 생성하고, 이후 docker-compose up 명령을 통해 컨테이너로 실행할 수 있습니다.

docker-compose build

 

docker-compose up

정의된 모든 서비스를 시작합니다. -d 옵션을 사용하면 백그라운드에서 실행됩니다.

docker-compose up
docker-compose up -d

 

docker-compose down

실행중인 모든 서비스를 중지하고 제거합니다.

docker-compose down

 

docker-compose ps

현재 실행 중인 모든 서비스를 확인합니다.

docker-compose ps

 

docker-compose logs

모든 서비스의 로그를 확인합니다.

docker-compose logs

 

docker-compose stop

실행중인 모든 서비스를 중지합니다.

docker-compose stop

 

docker-compose, Dockerfile 관계

둘 다 Docker 환경에서 자주 사용되지만, 목적과 사용 방식이 다릅니다. 여기서 중요한 건 각각의 차이점을 파악하고 어떻게 조합해서 사용할 수 있는지를 아는 것입니다.

 

역할 및 차이점

Dockerfile

  • 역할: Docker 이미지를 정의하고 생성하기 위한 도구입니다. 애플리케이션의 환경을 코드로 설정할 수 있어, 특정 애플리케이션의 실행 환경을 표준화할 수 있습니다.
  • 기능: 설치해야 할 패키지, 애플리케이션 소스 코드, 환경 변수 설정 등을 포함하여 이미지 자체를 만드는 데 사용됩니다.
  • 사용 목적: 하나의 이미지를 정의하여 이를 여러 환경에서 재사용할 수 있게 하는 것입니다.

 

Docker Compose

  • 역할: 여러 컨테이너를 관리하고 조정하기 위한 도구입니다. 다양한 Docker 이미지를 사용하여 멀티-컨테이너 애플리케이션을 구성하고, 각 컨테이너 간의 네트워크, 볼륨, 환경 변수 등을 설정합니다.
  • 기능: 여러 컨테이너를 정의하고 실행하는데 필요한 설정을 YAML 형식으로 작성하며, 단일 명령어로 모든 컨테이너를 동시에 관리할 수 있게 합니다.
  • 사용 목적: 복잡한 애플리케이션이나 마이크로서비스처럼 여러 개의 컨테이너가 협력해야 하는 상황에서 사용됩니다.

 

결론

  • Dockerfile은 애플리케이션 환경을 캡슐화하여 이미지를 생성하는 데 유용하고, Docker Compose는 이 이미지를 기반으로 여러 컨테이너를 효율적으로 관리할 수 있게 해줍니다. 따라서, 둘을 함께 사용하여 개발과 배포의 효율성을 높이는 것이 일반적인 접근 방식입니다.
반응형

댓글