Docker - File System & Storage

유현수·2024년 3월 8일
0
post-thumbnail

우리는 도커를 사용해 이미지를 빌드하고 컨테이너를 생성하고 볼륨을 마운트합니다. 도커는 이미지, 컨테이너, 볼륨과 관련된 파일을 어디에 어떻게 저장하고 있을까요? 한 번 자세히 알아봅시다.

도커의 파일 시스템

우선 도커가 파일을 어디에 저장하는지 알아봅시다. 터미널에서 docker info 명령어를 날려볼까요.

$ docker info | grep 'Docker Root Dir'
 Docker Root Dir: /var/lib/docker

/var/lib/docker 경로에 파일을 저장하고 있는 것을 알 수 있습니다. 도커를 설치하면 기본적으로 /var/lib/docker 를 루트 디렉토리로 설정하고 모든 파일을 이 경로에 저장합니다.

하위 디렉토리를 보면 컨테이너, 이미지, 볼륨이 저장되고 있는걸 볼 수 있습니다.

/var/lib/docker
├── aufs
├── containers
├── image
├── volumes
├── ...

그렇다면 도커는 정확히 어떻게 이미지와 컨테이너를 저장할까요? 이를 이해하려면 도커의 계층 구조(Layered architecture)를 이해해야 합니다.

도커의 계층 구조

이미지 빌드 과정으로 알아보는 도커의 계층 구조

Dockerfile로 이미지를 빌드하면 어떤 일이 일어날까요? Dockerfile의 각 명령문은 도커 이미지에 새로운 레이어를 생성하고 변경사항을 저장합니다.

1

위 이미지를 보면 첫번째 명령문에서 첫 레이어가 생성되고, 우분투 이미지 120MB가 저장됩니다. 두번째 명령문에서 두번째 레이어가 생성되고, 설치한 apt 패키지 306MB가 저장됩니다. 이전 레이어에서 새롭게 추가된 apt 패키지만 저장되는 것이죠. 이런 식으로 각 레이어는 이전 레이어에서 새롭게 변경된 내용만 저장됩니다.

도커 계층 구조의 장점

도커는 왜 계층 구조를 채택하게 되었을까요? 앞서 예시로 본 Dockerfile과 거의 비슷한 Dockerfile2 이미지 빌드 과정을 보며 알아봅시다.

2

도커는 레이어를 캐싱합니다. 따라서 3번째줄까지는 이전 Dockerfile과 동일하기 때문에 이전에 만들어둔 레이어를 재사용합니다. 그리고 변경된 부분만 새로운 레이어를 만들어 사용하죠.

계층 구조를 사용해 각 빌드 단계를 캐싱할 수 있고 덕분에 빌드 시간을 단축할 수 있습니다.

이미지 레이어와 컨테이너 레이어

이미지를 빌드하고 docker run 커맨드로 컨테이너를 생성하면 아래 이미지처럼 컨테이너 레이어가 생성됩니다.

3

이미지 레이어는 읽기만 가능한 반면 컨테이너 레이어는 읽기, 쓰기가 모두 가능합니다. 애플리케이션이 동작하면서 남기는 로그 파일, 임시 파일 등이 저장되겠죠.

하지만 이 레이어는 컨테이너 실행 중에만 유지됩니다. 컨테이너가 중지되면 이 레이어 또한 삭제되죠.

스토리지 드라이버

이 모든 과정을 수행하는 주체는 무엇일까요? 계층 구조를 유지하고 레이어를 생성하고, 레이어를 가로질러 파일을 파일을 복사해 읽기, 쓰기가 가능하게 하는 주체는 스토리지 드라이버입니다.

대표적인 스토리지 드라이버는 다음과 같은 종류가 있습니다.

  • AUFS
  • ZFS
  • BTRFS
  • Device Mapper
  • Overlay
  • Overlay2

스토리지 드라이버는 어떤 OS를 사용하느냐에 따라 달라집니다. 도커는 OS에 따라 최적의 스토리지 드라이버를 채택합니다. 스토리지 드라이버는 각기 다른 성능과 안정성, 특징이 있습니다.

스토리지 드라이버는 아래 명령어로 확인할 수 있습니다.

$ docker info | grep 'Storage Driver`
Storage Driver: overlay2

볼륨

만약 컨테이너가 중지되더라도 애플리케이션에서 생성한 데이터, 파일을 유지하고 싶다면 어떻게 해야할까요? 대표적으로 DB 컨테이너를 실행할 때, 컨테이너가 중지되더라도 DB 데이터 파일은 지워지지 않도록 어딘가에 남겨둬야겠죠. 이 때 볼륨을 사용하게 됩니다.

볼륨을 생성하고 마운트하는 과정을 보다 구체적으로 알아봅시다.

볼륨 마운트 시 일어나는 일

다음 명령어로 볼륨을 생성하면

$ docker volume create data_volume

/var/lib/docker/volume 디렉토리 하위에 data_volume 디렉토리가 생성됩니다.

4

그리고 아래 명령어를 실행하면

$ docker run -v data_volume:/var/lib/mysql mysql

5

새로운 컨테이너를 생성하고 지정한 경로에 볼륨을 마운트합니다. 컨테이너에서 /var/lib/mysql에 저장하는 모든 파일은 도커 호스트의 볼륨에 저장되죠. 컨테이너가 중지돼도 데이터는 볼륨에 남아있게 됩니다.

Tip!
볼륨을 먼저 생성하지 않고 docker run -v my_volume:/var/lib/mysql mysql과 같은 명령어를 바로 실행해도 괜찮습니다. 도커가 알아서 my_volme이라는 이름의 볼륨을 생성하고 컨테이너와 마운트 시키기 때문입니다.

바인드 마운트

만약 도커 호스트에 이미 있는 파일을 컨테이너에 마운트시키고 싶다면 어떻게 해야할까요?

예를 들어 도커 호스트의 /data/mysql 경로에 이미 데이터가 있는 상태이고 이를 컨테이너에 마운트 시키고 싶은 것이죠.

이럴때는 바인드 마운트를 사용합니다. 마운트 시킬 경로를 직접 입력하면 됩니다.

$ docker run -v /data/mysql:/var/lib/mysql mysql

6

Tip!
볼륨 마운트 시 -v 옵션보다는 --mount 옵션을 보다 선호하는 추세라고 합니다. key-value 형태를 사용해 보다 자세하게 옵션을 명시할 수 있기 때문이죠.

$ docker run -v /data/mysql:/var/lib/mysql mysql
$ docker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql

볼륨 드라이버

볼륨은 볼륨 드라이버 플러그인에 의해 관리됩니다. 스토리지 드라이버는 볼륨을 관리하지 않습니다.

가장 기본적인 볼륨 드라이버는 Local입니다. Local 볼륨 드리이버는 도커 호스트에 볼륨 생성하는 일, 데이터를 /var/lib/docker/volume 디렉토리 하위에 저장하는 일 등을 처리합니다.

이외에도 수많은 볼륨 드라이버가 있습니다. 이들을 사용해 타사 솔루션에서 볼륨을 생성할 수 있죠.

$ docker run -it \
    --name mysql
    --volme-driver rexray/ebs
    --mount src=ebs-vol,target=/var/lib/mysql
    mysql

예를 들어 AWS EBS에 볼륨을 생성하기 위해 rexray/ebs 같은 특정 볼륨 드라이버를 사용할 수 있습니다.

profile
"Life isn't about finding yourself. Life is about creating yourself."

0개의 댓글