[Docker] 컨테이너 볼륨 마운트로 호스트와 파일 공유하기

Loopy·2023년 6월 22일
0

삽질기록

목록 보기
20/28
post-thumbnail

문제 상황

현재 진행중인 프로젝트에서, EC2 내부에 존재하는 크롤링 json 파일을 도커에 띄워진 Spring Boot 에서 읽어오지 못하는 문제가 발생했다. 같이 개발하는 현업자분 덕분에 마운트라는 키워드를 알게 되었고, 적용한 내용을 기록하고자 한다.

우선, 도커의 구조에 대해 먼저 알아보자.

☁️ 도커 네트워크

도커 컨테이너 접속하기

도커는 그냥 동작하는 하나의 프로세스라고 생각해, 프로세스에 어떻게 접속하지라는 생각이 들었었다. 하지만 단지 같은 OS에 독립적인 구역을 나눈 것이기 때문에 접속할 수 있는게 맞다.

docker exec -it  [컨테이너 ID] /bin/bash

예를 들어 Spring Boot 도커 컨테이너에 들어가보면, 기본적인 Java program을 구동하기 위한 JDK 만 설치되어 있는 형식이다.

따라서 우리는 바로 여기에 EC2 에 있는 데이터를 그대로 가져다 놓아야, Spring Boot 어플리케이션이 실행될 때 경로를 찾아올 수 있다.

그렇다면 어떻게 이동시키지? 매번 복사를 해야하나?

도커 이미지 구조

도커 이미지로 컨테이너를 생성하면, 이미지는 읽기 전용이 되고 쓰기 작업은 Container Layer 라는 곳에서 수행된다. 그림을 보면 당연한 말이겠지만, 컨테이너가 삭제되면 해당 컨테이너에서 작업했던 사항들이 날라가게 된다.

그리고 이러한 문제점의 해결방법으로, 호스트와 볼륨을 공유할 수 있다.

☁️ 마운트(Mount) 개념

볼륨이란?

볼륨이란, 파일들과 디렉토리들을 저장하는 논리적 데이터 저장소이다. HDDSDD 와 같은 물리적 데이터 저장소인 디스크들, 혹은 드라이브와 같다고 생각하면 된다. 하지만 볼륨(드라이브)를 새로 생성했을 경우, 컴퓨터가 해당 볼륨을 사용할 수 있도록 알려줘야 한다.

이렇게 볼륨을 컴퓨터가 사용할 수 있도록 적용하는 과정을 마운트(mount)라고 한다. 그리고 데이터가 도커 호스트 내에서 어디 존재하는지에 따라 바인드/볼륨 마운트 두 종류로 나뉜다.

1. 바인드 마운트

데이터가 Host System의 파일 또는 디렉토리가 컨테이너에 mount 된다. 즉, 호스트 시스템의 어느 위치에서든지 저장을 할 수 있다.

docker run --mount source=[호스트 디렉토리 경로], target=[컨테이너 디렉토리 경로]

파일 또는 디렉토리는 호스트 시스템의 전체 경로로 참조되지만, target 디렉토리는 도커 컨테이너 내부에 미리 존재할 필요는 없다. 만약 없을 경우, 참조된 경로로 파일 또는 디렉토리가 자동으로 생성된다.

하지만 바인드 마운트 방식은 호스트 파일 시스템 구조에 의존적이라는 치명적인 단점이 존재한다. 만약 호스트 운영체제가 바뀐다면, 경로를 다시 설정해줘야 하기 때문이다. 또한 다른 프로세스들이 마운트된 공간에 접근 할 수 있기 때문에 격리된 환경을 만들지 못해 보안상 취약하다.

🔖 언제 사용하면 좋을까?
호스트 머신에서 컨테이너로 파일을 공유해야하는 경우

2. 볼륨 마운트

Docker (Linux 에서는 /var/lib/docker/volume/ )가 관리하는 Host File System 의 일부에 데이터를 적재시키는 방식이다.

볼륨이 Docker 에 의해 관리되고 Host System 과 분리된다는 점을 제외하면, 바인드 마운트와 비슷하게 동작한다.

실행 중인 컨테이너가 해당 볼륨을 사용하지 않아도 자동으로 삭제되지 않고 계속 도커 호스트에 남아있을 수 있다는 장점이 존재한다.

🔖 언제 사용하면 좋을까?
실행 중인 여러 컨테이너 간에 데이터 공유가 필요한 경우

docker volume create [볼륨이름]  // 생성
docker volume inspect [볼륨 이름]  // 생성한 볼륨 보기

현재 나는 호스트 머신에 있는 파일을 컨테이너가 사용할 수 있게 공유하는 것이므로, 바인드 마운드 방식을 채택했다.

☁️ 깃허브 액션과 바인드 마운팅 트러블 슈팅

깃허브 액션에서 마운팅을 시도한다면, pwd 를 통해서 호스트 디렉토리 경로를 지정해주면 안된다. 아래와 같이 actions-runner 디렉토리 내부 경로가 참조되기 떄문에, 직접 /home/ec2-user/[디렉토리] 로 명시해 지정해주어야 한다.

  1. pwd 사용한 경우 마운팅 실패
 docker run -v `pwd`/ahachul_data/datas/:/home -d -p 80:8080 --name XX ...

  1. 직접 경로를 지정해준 경우 마운팅 성공
 docker run -v /home/ec2-user/ahachul_data/datas/:/home -d -p 80:8080 --name XX ...

드디어 도커 컨테이너로 접속했을 때 지정해준 경로로 json 파일들이 잘 들어온 것을 볼 수 있다!

참고 자료
https://medium.com/@su_bak/volume-이란-무엇일까-a9a33f262615#:~:text=이렇게%20볼륨을%20컴퓨터가,것도%20마운트한다%20라고%20합니다.
https://medium.com/dtevangelist/docker-기본-5-8-volume을-활용한-data-관리-9a9ac1db978c
https://velog.io/@sorzzzzy/Docker-7.-파일-복사와-볼륨-마운트
https://www.daleseo.com/docker-volumes-bind-mounts/

profile
개인용으로 공부하는 공간입니다. 잘못된 부분은 피드백 부탁드립니다!

0개의 댓글