Docker/Kubernetes 정리 5

윤석주·2023년 2월 25일
0

docker

목록 보기
6/10

Bind Mounts

지난 포스팅에서 보았듯, 도커에서 제공하는 External Data Storage의 종류는 다음과 같습니다.

  • Volumes (Managed by Docker)
    • Anonymous Volumes
    • Named Volumes
    • Docker sets up a folder / path on your host machine, exact location is unknown to you(dev). Managed via docker volume commands.
  • Bind Mounts (Managed by you)

이번에는 Bind Mounts에 대해 알아보겠습니다.

특징

우리는 이미지와 컨테이너를 배웠습니다. 우리는 코드와 환경의 스냅샷을 이용해 이미지를 만들고, 이미지를 이용해 컨테이너를 생성하죠.

만약 코드가 변경된다면 이미지를 재빌드하고 컨테이너를 재실행해야 합니다. 이러한 방식은 코드가 변경될 때 마다 적용해야 하기에 어려움이 있을 수 있습니다. 즉, 어떤 코드들은 변경하는 즉시 반영되어야 한다는 것이죠.

Bind mounts는 이런 경우 도움이 될 수 있습니다. Bind mount는 지난 volume과 달리 host machine의 특정 폴더를 개발자가 관리할 수 있습니다. 그리고 지난시간에 본 것 처럼 volume에 저장하듯 데이터를 저장하고 컨테이너의 폴더와 연동할 수 있죠.

따라서 이곳에 소스코드를 저장한다면 기존처럼 COPY후 이미지를 만들 필요가 없어집니다. 그러므로 컨테이너는 항상 최신코드에 접근할 수 있는 것이죠.

volume과 가장 큰 차이점은 도커가 해당 마운트 포인트를 관리해주느냐 안해주느냐의 차이입니다. 볼륨은 도커상에서 이미지나 컨테이너, 네트워크와 비슷한 형식으로 관리되는 이점이 있습니다. 그래서 대부분의 상황에서는 볼륨을 사용하는 것이 권장됩니다. 하지만 컨테이너화된 로컬 개발 환경을 구성할때는 바인드 마운트가 더 유리할 수 있습니다.

일반적인 로컬 개발은 현재 작업 디렉터리에 프로젝트 저장소를 git clone 받아놓고 코드를 변경합니다. 따라서 바인드 마운트를 이용해 작업 디렉토리를 컨테이너의 특정 경ㅊ로로 마운트해주면 코드를 변경할 때 마다 변경 사항을 실시간으로 컨테이너를 통해 확인할 수 있습니다.

적용 방법

Bind mount는 볼륨처럼 컨테이너를 만들며 옵션을 이용해 설정할 수 있습니다.
docker run -d -p 3000:80 --rm --name ${app} -v ${absolute_hostmaching_path}:/${container_path} ${image}
다음과 같이 -v 옵션을 사용합니다. 형식은 위에 보는 것 처럼 호스트 머신의 path와 컨테이너 path를 ':'을 이용해 매핑하여 사용하며, 이때 호스트 머신의 path는 absolute path를 사용해야 합니다.

absolute path를 반드시 사용해야 하는 것은 아닙니다. 다음과 같은 방법을 통해 shortcut을 사용할 수 있습니다.

  • macOS / Linux: -v $(pwd):/app
  • Windows: -v "%cd%":/app
    OS에 따라 형식이 조금 다른것을 기억해야 합니다.

주의사항

방금 본 것 처럼 Bind mount는 호스트의 특정 폴더를 컨테이너의 폴더에 바인딩하여 실시간으로 반영될 수 있도록 도와줍니다.

하지만 이렇기에 문제가 생기는 경우도 존재합니다. 일반적으로 우리는 다음과 같은 기준으로 Dockerfile을 세팅합니다(노드 기준)

...
COPY package*.json /app
RUN npm install
COPY . .
...

이미지 생성 과정에서 필요한 패키지를 인스톨하고 파일을 카피하죠. 하지만 바인드 마운트를 사용하면 컨테이너의 폴터가 로컬 호스트의 폴더로 overwriting됩니다. 따라서 이미지 생성 과정에 패키지를 인스톨했다고 하더라도 로컬 작업 공간에 인스톨 되어있지 않으면 컨테이너에선 오류가 발생하게 됩니다.

가장 쉬운 방법은 local에도 npm install을 적용해주면 됩니다. 하지만.. 그러고 싶지 않겠죠?

이럴때 anonymous volume을 이용할 수 있습니다. 컨테이너 생성시 다음과 같이 2개의 -v 옵션을 사용합니다.
-v /${container_path}/node_modules -v ${host_machine_path}:${container_path}
도커는 여러개의 볼륨이 패스가 겹치는 경우, 더 자세하게 명시가 되어있는 볼륨을 우선적으로 선택합니다. 따라서 이미지 생성시에 만들어지는 node_modules 폴더는 anonymous volume에 저장되며, bind mount보다 우선적으로 참조하게 됩니다.

이렇게 하면 바인드 마운트를 이용하면서도 로컬에 의존성을 설치할 필요 없이 정상적으로 개발을 할 수 있습니다.

출처

profile
웹 개발을 공부하고 있는 윤석주입니다.

0개의 댓글