도커 A to Z - 데이터 관리 및 볼륨 작업

김상운(개발둥이)·2022년 9월 18일
0

도커 A to Z

목록 보기
3/5
post-thumbnail

도커에서 데이터란?

  • 어플리케이션
    • code + enviroment
    • 개발자가 작성한 코드
    • 이미지가 빌드 되면 변경할 수 없다.
    • 읽기 전용! 이미지에만 저장된다.
  • 임시 앱 데이터
    • 실행중인 컨테이너에서 생성된 것
    • 임시 파일 또는 메모리에 저장되는 것
    • 읽기 쓰기 가능! 컨테이너에 저장된다.
  • 영구적인 앱 데이터
    • 실행중인 컨테이너에서 생성된 것
    • 파일이나 데이터 베이스에 저장된다.
    • 컨테이너가 중지 또는 재 시작되도 손실이 되면 안된다.
    • 읽기 쓰기 가능, 영구적이게 컨테이너와 볼륨에 저장된다.

컨테이너는 이미지를 기반으로 생성된다.

계속 말하지만 이미지는 컨테이너의 청사진으로 컨테이너는 이미지의 모든 레이어위에 컨테이너 레이어가 올라간다.

이미지일때는 읽기 전용
컨테이너일 때는 읽기-쓰기 가능

볼륨이란?

볼륨은 하나의 폴더로써 호스트 머신위에서 존재하며, 하디디스크는 컨테이너에 의해서 마운트 된다. 도커에 의해 관리된다.

호스트 머신이란, 내 PC 를 뜻한다.

  • 볼륨은 컨테이너가 종료되도 영구히 저장하며 컨테이너가 재시작 되어도 볼륨안의 데이터는 컨테이너 안에서 사용 가능하다.
  • 컨테이너는 볼륨에 데이터를 읽고 쓸 수 있다.

볼륨의 종류와 외부 저장소

익명 볼륨

  • 이름이 없는 볼륨으로 docker run 명령어 시 볼륨의 이름을 정할 수 없다.
  • 하나의 컨테이너를 위해서 생성한다.
  • --rm 옵션 사용시 컨테이너 종료 시 익명 볼륨은 삭제된다.
  • 컨테이너간에 공유되지 않는다.
  • 같은 컨테이너에서 재사용 되지 않는다.

네임드 볼륨

  • 이름이 있는 볼륨으로 docker run 명령어 시 볼륨의 이름을 정할 수 있다.
  • 어떠한 구체적인 컨테이너에 한정되지 않는다.
  • 컨테이너가 종료되어도 삭제되지 않는다.
  • 컨테이너 간에 공유가 가능하다.
  • 같은 컨테이너에서 재사용 가능하다.

두 볼륨의 공통점: 도커는 호스트 머신의 데이터가 저장 될 폴더와 경로를 설정한다. 하지만 구체적인 경로는 알 수 없다.

바인드 마운트

  • 볼륨과 같이 호스트 머신의 데이터가 저장될 폴더와 경로를 설정한다. 볼륨과 달리 구체적인 경로를 설정하여야 한다.
  • 호스트 파일 시스템이 위치한다. 어떠한 컨테이너에도 한정되지 않는다.
  • 호스트 머신에서 삭제하지 않는 이상 삭제되지 않는다.
  • 컨테이너 간에 공유가 가능하다.
  • 같은 컨테이너에서 재사용 가능하다.

마운트란

실제 공간인 디스크를 사용하기 위해서 현재 사용하고 있는 운영체제에 연결하는 것

볼륨 명령어

위 그림처럼 위에서부터 익명, 네임드, 바인드 마운트 순이다.

익명

docker run -v /app/data

도커 이미지/컨테이너의 파일 시스템 상에서 호스트 머신에 마운트 할 경로를 지정한다. 익명이기에 이름은 없다

네임드

docker run -v volume-name:/app/data

도커 이미지/컨테이너의 파일 시스템 상에서 호스트 머신에 마운트 할 경로를 지정한다. 이름을 경로앞에 [이름:경로] 와 같이 입력한다.

바인드 마운트

docker run –v /path/to/code:/app/code …

호스트 머신에서 마운트될 저장공간의 절대 경로를 입력한다.

바인드 마운트 사용과 주의 사항

node.js 예시이다.

Dockerfile

FROM node:14

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE $PORT

CMD [ "npm", "start" ]

한번 이미지로 부터 실행된 컨테이너는 원본 소스코드가 변경되도 컨테이너의 소스코드는 변경되지 않는다.

하지만 바인드 마운트를 사용하여 컨테이너에서 사용될 어플리케이션 소스코드를 호스트 머신의 원본 소스코드가 존재하는 저장공간에 바인딩 마운트하여 컨테이너에서 어플리케이션을 실행하고자 하는 소스코드가 호스트 머신의 마운트된 저장공간에서 존재하기 때문에 호스트 머신에서의 소스 코드 수정이 컨테이너에 반영이 된다.

주의!

위의 Dockerfile 을 사용하여 아래의 docker run 을 하게 될 경우 node module 이 없다는 에러가 발생한다.

명령어

docker run -p 3000:8000 -d --rm --name 컨테이너이름 -v feedback:/app/feedback -v "D:\docker-study\섹션3\data-volumes-02-added-dockerfile\data-volumes-02-added-dockerfile:/app" feedback-node

문제점

  • 이 폴더에 있는 모든 것을 app 폴더에 바인딩한다. (마운트 바인딩)
  • 이미지가 생성될 때 모든 것을 app 폴더에 복사함. 모든 종속성을 설치하지만 결국 이미지 생성을 위해 수행한 npm install 과 같은 RUN 명령이 의미가 없다.
  • 왜냐하면 이 마운트를 컨테이너에 바인딩하면 /app 폴더의 모든것을 로컬 폴더로 덮어쓰기 때문이다.
  • 그리고 이 로컬 폴더에는 이 앱에 필요한 종속성이 없다.

해결법

위의 명령어에 -v /app/node_modules 옵션을 추가한다.

  • -v 옵션에는 우선순위가 있다. 이미지&컨테이너의 구체적인 경로일 경우 먼저 해당 볼륨이 생성된다.
  • 로컬의 호스트 머신의 저장경로에 의해 덮어 써지기 이전에 노드 모듈이 저장될 /app/node_modules 의 내용을 익명 볼륨으로 저장하여 덮어써지는걸 방지한다.

ARG vs ENV

ARG

  • Dockerfile 내부에서만 사용이 가능하다. CMD 에는 사용할 수 없다.
  • 이미지를 빌드할 때 사용한다.

ENV

  • 컨테이너의 환경 변수설정.
  • Dockerfile과 어플리케이션의 코드에서 사용이 가능하다.
  • docker run 명령어에서도 사용 가능

Dockerfile

FROM node:14

ARG DEFAULT_PORT=80

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

ENV PORT ${DEFAULT_PORT}

EXPOSE $PORT

CMD [ "npm", "start" ]

ARG 로 Docker 파일 내에서 사용할 변수를 설정하는데 사용한다.
ENV 로 소스코드에서 사용할 환경변수를 설정하며 Dockerfile 내에서 CMD 를 제외하고 사용가능 하다.

.env 폴더 사용

Dockerfile 내부에서 ENV를 사용하지 않고 설정할 수 있다.
프로젝트 내부에서 .env 파일을 생성 후 위와 같이 작성한다.

Docker run --env-file .env

로 대체 가능하다.

Docker run --env PORT=8000

ENV 명령어 .env 파일이 없어도 위와 같이 설정할 수 있다!

profile
공부한 것을 잊지 않기 위해, 고민했던 흔적을 남겨 성장하기 위해 글을 씁니다.

0개의 댓글