데이터 관리와 볼륨

·2023년 2월 12일
0

docker

목록 보기
3/7
post-thumbnail

서비스를 운영할 때 사용하는 데이터의 종류

어플리케이션 데이터

어플리케이션의 소스 파일이나, 실행파일, 실행을 위해 필요한 패키지 파일, 환경 설정 파일 등 어플리케이션 실행에 필요한 데이터를 말한다. 이러한 데이터들은 빌드할 때, 도커 이미지에 포함시키는 것이 일반적이다. 도커 이미지는 읽기 전용이므로 빌드된 이후 변경되지 않는다. 즉 어플리케이션 데이터는 이미지에 읽기전용으로 저장된다.

임시 데이터

어플리케이션이 실행되는 동안만 사용되는 데이터를 말한다. 사용자의 요청을 처리하는 동안 만들어지는 임시 파일을 예로 들 수 있다. 이러한 데이터는 컨테이너 메모리나 파일 시스템에 저장되고 컨테이너가 종료되면 사라지낟. 즉 임시데이터는 컨테이너에 저장되고 읽기/쓰기가 가능한 데이터이다.

영구 데이터

서비스가 제공되는 동안 사용되는 데이터를 말한다. 사용자의 회원정보는 회원가입 요청을 통해 만들어지고 이는 서비스가 유지되는 동안 사라져서는 안된다. 도커 컨테이너와 상관없이 데이터가 유지되어야 하기 때문에, 컨테이너 외부의 파일시스템이나 데이터베이스에 저장한다. 즉 컨테이너 외부에 저장되고 계속 유지되며 읽기/쓰기가 가능한 데이터이다.

컨테이너의 파일 시스템

컨테이너는 서로 컨테이너간 영향을 미치지 않는 독립된 환경을 제공한다. 컨테이너를 생성하는 경우, 만약 데이터를 생성하여, 저장하는 작업이 이루어진다면 일반적으로 해당 데이터는 어플리케이션이 실행되는 사용되는 임시데이터로 분류가 되고, 컨테이너 내의 파일 시스템에 의해, 컨테이너 내에 저장되게 된다.

이러면 문제가 되는 것이, 컨테이너가 삭제되는 경우 기존 컨테이너의 임시 데이터도 삭제 된다는 것이다. 기존의 데이터는 지속하여 모으면서, 필요하지 않은 컨테이너는 삭제할 수는 없는가? 이에 대한 해결책이 볼륨이다.

볼륨

도커의 내장 기능에는 볼륨이라는 것이 존재한다. 볼륨은 어플리케이션을 통해 사용된 데이터를 이후에도 유지하도록 도와준다. 이미지나 컨테이너 내에 존재하는 것이 아닌, 다른 공간을 매핑하여 컨테이너가 인식할 수 있도록 해준다. 따라서 컨테이너를 삭제하여도 데이터를 유지하는 것이 가능하다.

익명 볼륨

익명 볼륨은 임의의 경로에 생성된 볼륨과 사용할 수 있는 볼륨이다 컨테이너의 폴더와 로컬 폴더를 매핑하는 역할을 하지만 개발자가 해당 경로에 대해 위치를 찾거나 엑세스 할 수 있는 방법은 없다. 이는 기존 데이터를 사용하지 않고 컨테이너를 빠르게 실행하고 종료하는 경우에 적합하다. 일련의 예로 node_modules 가 있다. (코드를 실행하기 위해서는 필요하고, 따로 개발자가 이부분을 건드려서는 안되며, 종료시에는 필요가 없기 때문)

익명볼륨은 일반적으로 하나의 컨테이너와 연관이 되어있으며 해당 볼륨을 사용하고 있는 컨테이너가 종료되면 볼륨도 같이 삭제되기 때문에 데이터를 유지하기 위한 방법으로 적합하지는 않다.

컨테이너 실행시 익명 볼륨을 해당 컨테이너에 설정하는 명령어는 다음과 같다.

docker run -v <volume_path> <my_image>

명명된 볼륨

컨테이너가 삭제되어도 볼륨이 삭제되지 않는 방법이 바로 명명된 볼륨 named volume 이다. 익명 볼륨과 마찬가지로 컨테이너의 폴더와 로컬 폴더가 매핑되지만 개발자는 해당 경로에 대하여 엑세스할 수 있는 방법은 없다. 명명된 볼륨은 일반적으로 다수의 컨테이너와 연관이 되어있으며, 컨테이너 삭제하여도 데이터는 유지되기 때문에 기존의 데이터를 영구적으로 가지고 사용하면서도, 따로 데이터 업데이트 하지 않거나, 접근할 필요가 없는 데이터를 보관하는 데 적합하다.

컨테이너 실행시 명명된 볼륨을 해당 컨테이너에 설정하는 명령어는 다음과 같다.

docker run -v <volume_name>:<volume_path> <my_image>

바인드 마운트

바인드 마운트는 볼륨외에 로컬 파일 시스템의 디렉토리나 파일을 컨테이너로 매핑하는 또 하나의 방법으로써, 명명된 볼륨과 동일하게 컨테이너가 삭제되어도 해당 데이터가 유지하지만 해당 경로에 대한 위치를 알 수 있기 때문에, 개발자가 접근하는 것 역시 가능하다. 기존의 데이터를 영구적으로 가지고 사용하면서도, 데이터에 접근이 가능하면서, 데이터의 변경점을 업데이트 해야하는 경우 사용된다. 주로 개발환경 전역을 바인드 마운트하여 컨테이너 재시작 없이 라이브 데이터를 렌더링하기 위해 사용한다.

컨테이너 실행시 바인드 마운트를 해당 컨테이너에 설정하는 명령어는 다음과 같다.

docker run -v <local_path>:<volume_path> <my_image>
// 해당 전체 경로를 부르는 명령어가 있다.
// macOS / Linux : $(pwd)
// Windows : "%cd%"
// ex) docker run -v $(pwd):<volume_path> <my_image>

바운드 마운트를 사용하는 경우, 컨테이너에 로컬의 데이터를 덮어쓰는 과정이 진행되기 때문에, 이미지 빌드시 COPY 과정과 비교하며 실행 중 필요한 요소들이 덮어씌워지는 문제가 없는지 확인할 필요가 있다. 이럴 때는 삭제되어서는 안되는 폴더경로를 찾아, 볼륨을 통해 설정하는 것으로 문제를 해결할 수 있다.

도커는 여러 볼륨들이 있고, 만약 해당 볼륨들의 경로 서로를 내포하는 상태라면 더 구체적인 경로를 가진 볼륨을 우선시 하여 따른다. 만약 바인드 마운트를 통해 /app 을 설정하였고, 익명 볼륨을 통해 /app/node_modules 을 설정하였다면, /app/node_modules 이 훨씬 깊숙하고 구체적인 경로이기 때문에, 익명 볼륨을 따라, /app 안에 /node_modules 에 필요한 데이터가 덮어씌워지지 않은 체 남게 되는 것이다.

읽기 전용 볼륨

기본적으로 볼륨을 통해 설정된 데이터는 읽고 쓰는 것이 모두 가능하다. 하지만 컨테이너에서 실행 중인 어플리케이션은 연결된 파일을 변경해서는 안되기 때문에, 컨테이너에 이를 제한할 수 있는 옵션 명령어가 있다.

read-only 옵션을 통해 컨테이너에 읽기 전용 볼륨을 설정할 수 있다. 이는 볼륨이 안전하게 사용되도록 하기 위해, 컨테이너에서 해당 볼륨에 대한 쓰기 작업이 수행되지 않도록 하기 위한 목적으로 사용된다. 읽기 전용 볼륨을 설정하는 명령어는 다음과 같다.

docker run -v <volume_name>:<volume_path>:ro <my_image>

볼륨 관리하기

볼륨을 관리하기 위한 명령어들은 다음과 같다.

  • docker volume ls : 익명 볼륨과 명명된 볼륨을 확인할 수 있다.
  • docker volume create <volume_name> : 익명 볼륨을 생성한다.
  • docker volume rm <volume_name> : 명명된 볼륨을 삭제한다. 만약 해당 볼륨을 사용하는 컨테이너가 있다면 삭제 하는 것이 불가능하다.
  • docker volume prune : 사용하지 않는 볼륨들을 삭제한다.
  • docker volume inspect <volume_name> : 해당 볼륨에 대한 세부 정보를 확인할 수 있다. 이는 볼륨의 경로, 드라이버 등의 속성들을 포함하고 있으며, 볼륨을 관리할 때 간단한 정보를 확인하는데 유용하게 사용된다.

dockerignore

dockerignore 파일은 도커 이미지 빌드 시 제외할 파일이나 디렉토리를 정의하는 파일로, .dockerignore 파일을 빌드 디렉토리 최상위 경로에 생성하고 이 파일에 제외할 파일 또는 디렉토리를 기술하면 된다. 예를 들면 다음과 같다.

# 이 디렉토리 및 그 하위 디렉토리는 모두 제외
node_modules/
# 다음과 같은 파일들은 모두 제외
README.md
*.log

dockerignore 파일의 패턴에 따라 해당 파일들은 이미지 빌드 시 제외되므로, 명령어에 대한 중복 입력 없이 빌드 시간을 단축할 수 있다. 그리고 생성되는 이미지의 용량도 감소하게 된다. 또한 기본적으로 컨테이너 생성 시 dockerignore로 설정하지 않아도 .git 폴더와 dockerfile 자체적으로 무시한다.

환경변수 & .env 파일 작업

도커는 환경변수를 사용하는 방법 중 하나로 .env 파일을 사용하는 방법이 있다. .env 파일의 사용은 컨테이너에 환경변수를 자동으로 로드하고 관리하기 위해 사용된다. .env 파일은 다음과 같이 구성된다.

# 이 라인은 주석으로 기록된 환경변수 이름과 값으로 구성된다.
ENV_VAR_1=value1
ENV_VAR_2=value2
ENV_VAR_3=value3

docker run 명령어를 사용하여 컨테이너를 실행할 때, --env-file 옵션을 사용하면 .env 파일로 연결된 환경변수들이 자동으로 컨테이너에 로드된다. 다음과 같이 환경변수를 컨테이너에 로드하는 예제는 다음과 같다.

$ docker run --env-file .env <my_image>

또한 이러한 명령어를 통해서도 env 를 설정하는 것이 가능하다.

$ docker run -e ENV_VAR_1=value1 -e ENV_VAR_2=value2 -e ENV_VAR_3=value3 <my_image>
$ docker run --env ENV_VAR_1=value1 --env ENV_VAR_2=value2 --env ENV_VAR_3=value3 <my_image>

dockerfile 에 직접 설정하는 법도 있다.

ENV ENV_VAR_1=value1
ENV ENV_VAR_2=value2
ENV ENV_VAR_3=value3

단, 이러한 경우나 별도의 파일을 통해 가져오는 경우는 외부에 오픈되어도 괜찮은 환경변수 정보만 사용할 것을 권장한다. 해당 이미지를 사용하는 다른 이들이 docker history 명령어를 통해 해당 환경 변수 값을 읽어볼 수 있기 때문이다. 자격 증명, 개인 키 등은 확실히 피해야 한다.

빌드 인수(ARG) 사용하기

빌드 인수는 dockerfile 에서 빌드 시 사용할 수 있는 인수를 정의하는 방법이다. ARG 명령어를 사용하여 인수를 정의할 수 있고, 해당 인수는 도커 빌드 명령어를 통해 전달하는 인수 값으로 대체된다. 인수는 다음과 같이 정의할 수 있다.

ARG ARG_NAME=default_value

도커 빌드 시 ARG_NAME 인수를 통해 기본 값이 아닌 다른 값을 전달할 수 있다.

$ docker build --build-arg ARG_NAME=value <my_image>

빌드 시 전달할 값이 도커 빌드 명령어에 직접 입력되지 않는 경우, 빌드 인수를 통해 인수의 값을 전달할 수 있다. 이는 빌드 시마다 다른 인수 값을 전달하는 것이 가능하기 때문에, 동일한 이미지를 여러 개 빌드하고 각각 다른 인수 값과 함께 사용하는 것 등이 가능해진다.

profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.

0개의 댓글