[MLOps] Docker Compose를 이용한 데이터 생성 자동화

이한슬·2025년 2월 16일

MLOps

목록 보기
4/9
post-thumbnail

이 글은 MLOps for MLE를 공부하고 정리한 내용입니다.

Docker Compose

Docker Compose는 다중 컨테이너 애플리케이션을 정의 공유할 수 있도록 개발된 도구로, 단일 명령을 사용하여 모두 실행 또는 종료할 수 있도록 개발된 도구

실제 서비스를 서버 위에 실행시킬 때, 여러 개의 서비스들이 필요할 경우가 있다.
Docker Compose는 여러 서비스들을 한 번에 실행하고 종료할 수 있도록 해준다.

Docker Compose로 DB 서버와 Data Generator를 한 번에 관리해보자.
우선, 이전에 실행한 DB 서버와 Data Generator를 종료시킨다.

$ docker rm --force postgres-server data-generator

이제 docker-compose.yaml이라는 이름으로 Compose 파일을 작성한다.
가장 먼저 versionservices를 작성한다.

version: "3"

services:
  • version: Compose 파일의 버전
  • services: Compose에 묶일 서비스들을 작성, 하나의 서비스는 하나의 컨테이너를 의미

Postgres Server Service

다음으로, 데이터를 저장할 postgres server 서비스를 작성한다.

version: "3"

services:
  postgres-server:
    image: postgres:14.0
    container_name: postgres-server
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydatabase
  • postgres-server: 서비스의 이름, 실행되는 컨테이너의 호스트 이름이 됨
  • image: 사용할 컨테이너의 이미지
  • ports: 컨테이너에서 외부로 노출할 포트 포워딩을 설정, 형식은 host:container로 사용되며 여러 개 지정 가능
  • environment: 컨테이너를 실행할 때 사용한 -e 옵션과 같은 역할

Data Generator Service

data-generator 서비스는 postgres-server 서비스와 다르게 직접 이미지를 build해서 사용한다.

version: "3"

services:
  postgres-server:
    image: postgres:14.0
    container_name: postgres-server
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydatabase
      
  data-generator:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: data-generator
    depends_on:
      - postgres-server
    command: ["postgres-server"]
  • build:
    - context: 이미지를 build하기 위해 Dockerfile이 있는 절대경로 또는 상대경로
    - dockerfile: context에서 설정한 경로에 있는 Dockerfile의 파일명
  • depends_on: Compose로 띄워지는 서비스 간의 종속성 순서대로 서비스를 시작할 때 사용, 여기서는 postgres server가 먼저 실행되고 난 뒤에 Data Generator를 실행해야 하기 때문에 postgres server의 서비스 이름인 postgres-server를 입력
  • command: Dockerfile에 작성되어 있는 CMD를 덮어쓰기, data-generator 서비스가 시작될 때 'postgres-server'라는 명령을 실행하라는 뜻

Docker Compose Healthcheck

이제 작성한 Compose 파일을 실행해본다.
Compose 파일은 up, down 명령어를 통해 실행과 종료를 할 수 있다.

$ docker compose up -d
  • -d: Detached 모드로 실행으로, 백그라운드에서 컨테이너를 실행 후 유지한다.

하지만 docker ps를 입력해보면 postgres server만 띄워져있다.

$ docker ps
CONTAINER ID   IMAGE           COMMAND                   CREATED          STATUS          PORTS                    NAMES
a2c089e2a028   postgres:14.0   "docker-entrypoint.s…"   34 seconds ago   Up 33 seconds   0.0.0.0:5432->5432/tcp   postgres-server

앞서 depends_on으로 서비스 간의 종속성은 정했지만, 실제로 postgres server가 띄워진 뒤에 곧바로 Data Generator가 띄워진다.
Postgres server는 아직 준비가 되어있지 않은데, Data Generator가 띄워져서 DB에 연결을 하려다보니 Data Generator가 Exited 되는 문제가 발생한 것이다.
따라서, postgres server가 사용 가능한 상태가 되어있는지 체크를 한 뒤에 Data Generator를 띄워야 한다.
이를 위해서 Docker Compose Healthcheck를 사용한다.

yaml 파일에 healthcheck부분과 condition을 추가한다.

version: "3"

services:
  postgres-server:
    image: postgres:14.0
    container_name: postgres-server
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydatabase
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-U", "root", "-d", "mydatabase"]
      interval: 10s
      timeout: 5s
      retries: 5

  data-generator:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: data-generator
    depends_on:
      postgres-server:
        condition: service_healthy
    command: ["postgres-server"]
  • test: 테스트 할 명령어, 여기서는 pg_isready를 이용하여 DB가 준비상태인지 테스트
  • interval: Healthcheck 간격
  • timeout: Healthcheck의 timeout
  • retries: Timeout의 횟수
  • condition:
    - Healthcheck 기능을 사용하기 위해 depends_on의 parameter로 condition: service_healthy를 입력
    - Postgres server의 healthcheck를 Data Generator에서 적용시키기 위해 postgres-server 밑에 condition을 추가

이렇게 되면, 10초마다 테스트를 실행했을 때 5초 이내에 DB 가 준비 상태가 되었는지를 체크할 것이며, 실패 시 5번 재시도 한다.

이제 다시 서비스들을 실행하면 정상적으로 실행되는 것을 확인할 수 있다.

$ docker compose up -d

Docker Compose Network

위의 서비스를 실행한 후 생성된 네트워크를 확인해본다.

$ docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
e70a27ba6315   bridge          bridge    local
0cc86c667aff   host            host      local
e1be548ae25e   mlops_default   bridge    local
022aa7357483   none            null      local

위와 같이 mlops_default라는 이름의 네트워크가 생성된 것을 확인할 수 있다.
네트워크의 이름은 특별히 지정하지 않을 경우 {디렉토리명}_default로 자동으로 생성된다.

mlops_default를 확인해보자.

$ docker network inspect mlops_default
[
    {
        "Name": "mlops_default",
		...
        "ConfigOnly": false,
        "Containers": {
            "c532cf2bdf1e29a432ed4331be20d72f1ee2db6bf5b74be31a2b16f5a4023d30": {
                "Name": "postgres-server",
                ...
            },
            "e806375c4d524ddd36b6510e2d27e9828eaa4c5579c39d41b2e5879771c21e1c": {
                "Name": "data-generator",
                ...
            }
        ...
    }
]

네트워크에 자동으로 postgres-serverdata-generator 컨테이너가 추가된 것을 볼 수 있다.
이처럼 Compose 파일을 사용하면 네트워크에 대해서 신경쓰지 않고 편리하게 컨테이너들을 연결해서 사용할 수 있다.

앞으로 이어지는 파트에서는 서로 네트워크의 연결이 필요하기 때문에 이름을 지정해서 생성한다.
먼저, 실행한 서비스들을 종료한다.

$ docker compose down -v
  • -v: 생성된 볼륨까지 삭제한다.

네트워크 생성은 services와 같은 레벨에 networks를 입력하면 된다.

version: "3"

services:
  postgres-server:
    image: postgres:14.0
    container_name: postgres-server
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydatabase
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-U", "root", "-d", "mydatabase"]
      interval: 10s
      timeout: 5s
      retries: 5

  data-generator:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: data-generator
    depends_on:
      postgres-server:
        condition: service_healthy
    command: ["postgres-server"]
    
networks:
  default:
    name: mlops-network
  • default: 서비스 전체의 기본 네트워크
  • name: 네트워크의 이름

다시 docker compose를 실행한다.

$ docker compose up -d

실행 후 네트워크를 확인한다.

$ docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
e70a27ba6315   bridge          bridge    local
0cc86c667aff   host            host      local
d6e812384bd8   mlops-network   bridge    local
022aa7357483   none            null      local

mlops-network가 추가된 것을 확인할 수 있다.

데이터 확인

Local

psql을 이용하여 DB에 접속하고, 계속해서 데이터가 삽입되고 있는지 확인한다.

$ set PGPASSWORD=1234
$ psql -h localhost -p 5432 -U root -d mydatabase
mydatabase=# select * from iris_data;
 id  |         timestamp          | sepal_length | sepal_width | petal_length | petal_width | target
-----+----------------------------+--------------+-------------+--------------+-------------+--------
   1 | 2025-02-16 09:56:24.755775 |          5.4 |         3.9 |          1.7 |         0.4 |      0
   2 | 2025-02-16 09:56:25.760509 |          5.5 |         2.4 |          3.8 |         1.1 |      1
   3 | 2025-02-16 09:56:26.77736  |            5 |           3 |          1.6 |         0.2 |      0
   4 | 2025-02-16 09:56:27.793637 |          5.4 |         3.4 |          1.5 |         0.4 |      0
   5 | 2025-02-16 09:56:28.798815 |          7.2 |         3.6 |          6.1 |         2.5 |      2
   6 | 2025-02-16 09:56:29.818902 |          6.1 |         2.6 |          5.6 |         1.4 |      2

Data Generator Container

docker exec를 이용하여 Data Generator 컨테이너 안으로 접속한다.

$ docker exec -it data-generator /bin/bash

psql을 이용하여 DB로 접속한다.

$ set PGPASSWORD=1234
$ psql -h postgres-server -p 5432 -U root -d mydatabase
mydatabase=# select * from iris_data;
 id  |         timestamp          | sepal_length | sepal_width | petal_length | petal_width | target
-----+----------------------------+--------------+-------------+--------------+-------------+--------
   1 | 2025-02-16 09:56:24.755775 |          5.4 |         3.9 |          1.7 |         0.4 |      0
   2 | 2025-02-16 09:56:25.760509 |          5.5 |         2.4 |          3.8 |         1.1 |      1
   3 | 2025-02-16 09:56:26.77736  |            5 |           3 |          1.6 |         0.2 |      0
   4 | 2025-02-16 09:56:27.793637 |          5.4 |         3.4 |          1.5 |         0.4 |      0
   5 | 2025-02-16 09:56:28.798815 |          7.2 |         3.6 |          6.1 |         2.5 |      2
   6 | 2025-02-16 09:56:29.818902 |          6.1 |         2.6 |          5.6 |         1.4 |      2
profile
궁금하면 일단 먹어보는 소프트웨어 전공생

0개의 댓글