도커 컨테이너 레이어(layer)와 볼륨(volume)

dong5854·2022년 2월 23일
0

docker

목록 보기
6/8
post-thumbnail

레이어(layer)

이미지 레이어
도커의 컨테이너에서 볼륨(volume)의 필요성을 느끼기 위해 알아야 하는 개념으로는 레이어(layer)라는 개념이 있다.

이미지는 위의 그림과 같이 여러 이미지 레이어로 이루어져 있는데 이런 이미지 레이어를 사용하는 이유는 만약 사용자가 소스를 수정하거나 추가했을 때 전체를 다시 다운받는 것은 비효율적이기 때문에 변경된 부분만을 새로운 레이어로 추가 및 삭제하기 위한 개념이다. 실제로 도커 파일을 빌드할 때 처음 빌드하는 때에 비해 수정을 한 후 다시 빌드하는 것이 시간이 덜 걸리는 것도 이 레이어 덕분이다.
이미지 레이어는 읽기전용이기 때문에 한번 이미지가 빌드되면 수정이 불가능하다.

dong@ubuntu:~/docker-complete/NODE-SERVER$ sudo docker build .
Sending build context to Docker daemon   7.68kB
Step 1/7 : FROM node
 ---> f8c8d04432c3
Step 2/7 : WORKDIR /app
 ---> Using cache
 ---> 2e857cbad3b6
Step 3/7 : COPY package.json /app
 ---> Using cache
 ---> 5fb8ee901037
Step 4/7 : RUN npm install
 ---> Using cache
 ---> f4e411d9dbbb
Step 5/7 : COPY . /app
 ---> 177db9d9b963
Step 6/7 : EXPOSE 80
 ---> Running in 93441cb924d2
Removing intermediate container 93441cb924d2
 ---> 71f1c6b51cd5
Step 7/7 : CMD ["node", "server.js"]
 ---> Running in 887db838aea4
Removing intermediate container 887db838aea4
 ---> 9a685b7161af
Successfully built 9a685b7161af

위에서처럼 docker build를 진행할 때 하나의 step이 하나의 레이어라고 볼 수 있고, 특정 레이어에 변화가 없으면 캐시를 사용하는 것을 확인할 수 있다.

컨테이너 레이어
이미지의 레이어는 읽기 전용이기 때문에 쓰기 작업이 불가능하다고 하지만 우리가 이미지를 도커 컨테이너에 올려 사용을하게되면 로그가 작성되거나 데이터베이스에 데이터가 저장되는 것과 같은 쓰기 작업들이 일어난다. 이런 쓰기 작업들은 이미지를 사용해서 컨테이너를 생성했을 때 만들어지는 컨테이너 레이어에 쌓이게 된다. 컨테이너 레이어는 이미지 레이어와 다르게 읽기 및 쓰기 작업이 가능하다.

이 컨테이너 레이어는 이미지 레이어와 다르게 컨테이너가 종료되면 사라지기 때문에 컨테이너 레이어에 쌓여있던 데이터도 손실이 된다.
컨테이너를 사용해 서비스를 하다보면 데이터베이스에 우리 서비스 사용자의 계정정보와 같은 손실되면 안되는 데이터들이 쌓이기 마련이다. 이런 컨테이너 레이어의 데이터를 호스트에 저장하여 보존하기 위해 도커의 볼륨(volume)을 사용해야 한다.

볼륨(volume)

도커의 볼륨을 사용하는 방식으로는 크게 3가지가 있다.

docker run -v /app/data, docker run -v data:/app/data, docker run -v path/to/code:/app/data
첫번째 방식은 볼륨의 이름을 할당해주지 않는 익명 볼륨(Anonymous Volume), 두번째 방식은 이름을 지정해주는 볼륨(named volume) 마지막 방식은 바인드 마운트(bind mount)를 통해 호스트 파일 시스템의 특정경로를 컨테이너에 마운트해주는 방식이다.

이 세 방식의 차이를 정리해 보자면

Anonymous Volume

  • 하나의 컨테이너만을 위해 생성됨
  • 컨테이너 -rm를 통해 제거되면 같이 제거된다.
  • 하나의 컨테이너를 위해 생성되기 때문에 다른 컨테이너와 공유가 불가능하다.
  • 이름이 지정되어 있지 않기 때문에 재사용이 불가능하다.

named Volume

  • 하나의 컨테이너에 종속되지 않음
  • 볼륨을 생성한 컨테이너가 제거된다 해도 같이 제거되지 않는다.
  • 컨테이너들 사이에 공유가 가능하다.

Anonymous Volume과 named volume의 공통점으로는 도커가 호스트 머신에서 경로를 지정해준다. docker volume inspect를 통해 경로를 확인하는 것이 가능하다.

bind mount

  • 바인드 마운트를 사용하면 호스트 머신의 파일 시스템의 경로와 컨테이너의 경로를 연결해줄 수 있다.
  • 마운트과 완료되면 호스트 머신에서 해당 경로의 파일을 수정하면 마운트된 컨테이너의 파일도 수정된다.
  • 컨테이너의 파일이 수정될 때도 호스트 머신의 해당 경로의 파일이 수정된다.

    바인드 마운트는 ro 옵션을 주어 볼륨을 읽기 전용으로 마운트 하는것도 가능하다.

Anonymous Volume을 사용하는 이유
위의 설명만 본다면 Annymous volume은 아무 쓸모가 없어 보이지만 유용하게 사용되는 경우가 있다.

FROM node:14

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 80

VOLUME [ "/app/node_modules" ]

CMD [ "npm", "start" ]

위와 같이 도커 파일에서 annonymous volume을 생성해주는 VOLUME [ "/app/node_modules" ]가 왜 필요한지 의문의 들 수 있다. 만약 docker run -v path/to/code:/app를 이용해 실행하면 호스트 머신의 path/to/code경로의 모든 데이터가 도커 컨테이너에 마운트하는 과정에서 컨테이너의 /app경로를 overwrite하게 된다. 만약 호스트 머신에 node_modules가 없다면 도커파일을 통해 빌드해서 생성된 node_modules는 overwrite되어 사라질 것이고, 결과적으로 모든 노드 모듈들이 사라져 노드 모듈을 사용하는 코드가 정상적으로 실행되지 않을 것이다. 하지만 node_modules에 대하여 위의 도커파일과 같이 익명 볼륨을 만들어준다면 node_modules의 데이터는 도커가 경로를 지정해준 호스트 머신에 저장되기 때문에 overwrite되는 것을 방지해줄 수 있다.

named volume vs bind mount

named volume과 bind mount는 자신의 상황에 따라 어느 것 사용할지 잘 생각해볼 필요가 있다. 구글링을 해본 결과 대부분의 상황에서는 named volume이 백업과 마이그레이션에서 이점을 가져가고 Docker상에서 관리가 된다는 이점 때문에 named voume을 사용하는 것을 권장하나 개발환경을 구성할 때에는 바인드 마운트를 사용해 호스트 머신에서 소스코드를 변경해 컨테이너를 통해 실시간으로 확인할 수 있고 컨테이너를 통해 변경된 부분도 호스트 머신의 마운트된 디렉토리에 바로 반영이 되기 때문에 더 유리할 수 있다고 한다.

도커 volume에 관한 document 링크
docker volume이란?
docker volume create
docker volume inspect
docker volume ls
docker volume prune
docker volume rm

profile
https://github.com/dong5854?tab=repositories

0개의 댓글