코딩하는 털보

Docker Mount의 두 가지 방식 본문

Diary/Today I Learned

Docker Mount의 두 가지 방식

이정인 2023. 2. 17. 17:33

Dockerfile

FROM openjdk:11
MAINTAINER JeongIn Lee <rockintuna@e8ight.co.kr>

# set Time Zone
ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ARG MIRROR=https://dlcdn.apache.org/flume
ARG VERSION=1.11.0
ARG BIN_VERSION=apache-flume-${VERSION}

RUN apt-get update && apt-get install wget ca-certificates

#install apache flume
RUN mkdir -p /opt/flume/plugins.d/agent/lib \
  && mkdir -p /opt/logs \
  && wget ${MIRROR}/${VERSION}/${BIN_VERSION}-bin.tar.gz \
  && tar -zxvf ${BIN_VERSION}-bin.tar.gz -C /opt/flume --strip 1 \
  && rm -rf ${BIN_VERSION}.tgz

# mv dataAdapter library
COPY ./dataAdapter/build/libs/dataAdapter.jar /opt/flume/plugins.d/agent/lib/dataAdapter.jar
COPY ./dataAdapter/src/main/agent/lib /opt/flume/plugins.d/agent/libext

# mv flume agent settings
COPY ./dataAdapter/src/main/agent/adaptorWO.conf /opt/flume/conf
COPY ./dataAdapter/src/main/agent/flume-env.sh /opt/flume/conf
COPY ./dataAdapter/src/main/agent/log4j2.xml /opt/flume/conf/log4j2.xml

위의 Dockerfile을 실행하는 docker-compose

version: '3'

services:
  data-ingest:
    container_name: data-ingest
    image: 172.16.28.217:12000/ndxpro-dataingest:v1.2
    restart: always
    volumes:
      - /mnt/sda1/logs/data-ingest:/opt/logs
      - /mnt/sda1/flume/conf:/opt/flume/conf
    environment:
      - EUREKA_URL=http://eureka:8761/eureka
      - DATASOURCE_URL=jdbc:postgresql://postgres:5432/ndxpro
      - POSTGRES_USER=ndxpro
      - POSTGRES_PASSWORD=ndxpro123!
      - KAFKA_URL=pipeline-kafka-1:19092,pipeline-kafka-2:29092,pipeline-kafka-3:39092,pipeline-kafka-4:49092,pipeline-kafka-5:59092
      - GATEWAY_URL=http://gateway:8000
      - SPRING_PROFILES_ACTIVE=prod
    ports:
      - 54003:8080
    depends_on:
      - eureka
      - gateway
      - postgres

networks:
  default:
    name: ndxpro
    external: true

위 설정의 문제점은??

Issue

위와 같은 설정을 통해 docker를 실행하면,

docker-compose의 volume 설정대로 container의 /opt/flume/conf 디렉토리와 호스트의 /mnt/sda1/flume/conf 디렉토리에 Dockerfile에서 COPY한 파일들이 생성되어 있는것을 기대했다.

하지만 호스트 디렉토리에도 컨테이너 내부의 디렉토리에도 COPY한 파일을 찾을 수 없었다.

Why?

docker volume 호스트 디스크 mount 방식은 두 가지가 있는데,

1) docker volume을 사용하는 방법과
2) bind mount 사용하는 방법이다.

bind mount는 위와 같이 "host directory":"container directory" 모양으로 하는 방법인데, 이렇게 mount하면 docker에서 이 volume을 관리하지 않게 된다.

물론 docker volume ls 에도 안나오고 여러 volume 관리 기능을 사용할 수 없다. 그렇기 때문에 docker에서도 이 방법보다 docker volume을 사용하는 방법을 추천함.

문제는! bind mount가 docker의 초기화 기능 또한 지원하지 않기 때문에 dockerfile의 해당 디렉토리에 대한 COPY또한 적용할 수 없었던 것.

log4j2.xml 파일이 COPY가 안되어서 log 파일이 남지 않았던 것을 log4j2.xml 설정이 잘못된 줄 알고 한참 걸렸다.

반면 Docker volume은 docker에서 관리되기 때문에 여러가지 docker 관련 기능을 지원한다.

해결방법은 docker-compose 만으로 해결했다.

먼저, docker volume을 생성해야 하는데, docker-compose 의 volumes 를 사용하여 없으면 자동으로 생성되도록 하였다.

volumes:
  flume:
    name: flume

그리고 docker volume의 컨테이너 적용은 bind mount와 다르게 volume의 이름을 이용한다.

"volume name":"container directory"

수정된 docker-compose

version: '3'

services:
  data-ingest:
    container_name: data-ingest
    image: 172.16.28.217:12000/ndxpro-dataingest:v1.2
    restart: always
    volumes:
      - /mnt/sda1/logs/data-ingest:/opt/logs
      - flume:/opt/flume/conf
    environment:
      - EUREKA_URL=http://eureka:8761/eureka
      - DATASOURCE_URL=jdbc:postgresql://postgres:5432/ndxpro
      - POSTGRES_USER=ndxpro
      - POSTGRES_PASSWORD=ndxpro123!
      - KAFKA_URL=pipeline-kafka-1:19092,pipeline-kafka-2:29092,pipeline-kafka-3:39092,pipeline-kafka-4:49092,pipeline-kafka-5:59092
      - GATEWAY_URL=http://gateway:8000
      - SPRING_PROFILES_ACTIVE=prod
    ports:
      - 54003:8080
    depends_on:
      - eureka
      - gateway
      - postgres

networks:
  default:
    name: ndxpro
    external: true

volumes:
  flume:
    name: flume
Comments