Engineering/Docker

[Docker] Overlay에 대해서 알아보자. (feat. OverlayFS)

[앙금빵] 2024. 9. 1.

 

devicemapper 유형의 스토리지 관리방식이 25 버전부터는 deprecate됨에 따라 overlay2 방식적용에 대하여 검토가 필요해졌다. 이에 대하여 Overlay2 스토리지 드라이버에 대해 이해하는 것을 목적으로 둔다.


Background

(1) 운영체제는 효율적인 데이터 관리를 위해 데이터를 조직적으로 저장하고 관리한다. 이를 파일시스템이라 부른다.
(예. ext4, NTFS, XFS)

 

(2) 여기서 니온 파일 시스템은 여러 파일 시스템 레이어를 하나로 결합하여 단일 파일 시스템처럼 보여주는 기술이다.  이 기술은 여러 해 동안 존재했지만, 널리 사용되지는 않았다. 그러나 컨테이너 기술에서 유니온 파일 시스템이 채택됨에 따라 AUFS, OverlayFS 등의 유니온 파일 시스템 구현체가 주요 역할을 자리매김하게 되었다.

<그림 1. 유니온 파일시스템>

 

<그림 2. 유니온 파일시스템 종류>

출처: https://github.com/jquast/docker/blob/master/docs/userguide/storagedriver/selectadriver.md#overlay-vs-overlay2

 

(3) OverlayFS 방식은 간단한 설계 덕분에 성능과 유지 관리 측면에서 유리한 장점을 지녔으며 리눅스 커널 3.18 버전부터 메인라인에 포함되어 졌고 현재는 Docker와 같은 컨테이너화 기술에서 많이 사용되어지고 있다.


OverlayFS

OverlayFS에서는 단일 리눅스 호스트에서 이미지 레이어와 컨테이너 레이어를 하나의 통합 뷰로 제공한다.

 

이미지 레이어 (Image Layer)

  • Docker 이미지의 구성 요소로, 애플리케이션 및 그 의존성을 포함한 정적인 파일 시스템 스냅샷이다.
  • 읽기 전용(read-only)이며, 여러 레이어가 쌓여서 하나의 Docker 이미지를 구성한다.

 

컨테이너 레이어(Container Layer)

  • Container Layer는 Docker 컨테이너가 실행될 때 생성되는 쓰기 가능한(writeable) Layer이다.
  • Image Layer 위에 위치하며, 컨테이너 실행 중 발생하는 모든 파일 시스템 변경 사항(파일 생성, 삭제, 수정 등)이 기록된다.

 

이미지 레이어는 영구적으로 존재하며 여러 컨테이너에서 재사용될 수 있는 반면, 컨테이너 레이어는 컨테이너의 수명 동안만 존재하며, 컨테이너가 삭제되면 함께 삭제되어진다.

 

아래 그림은 Docker 이미지와 컨테이너가 어떻게 레이어링 되는 것을 보여준다. 여기서 이미지 레이어는 "lowerdir"이고, 컨테이너 레이어는 "upperdir"이다. 통합된 뷰는 "merged"라는 디렉토리를 통해 노출되며, 이는 컨테이너의 마운트 포인트이다.

  • Image Layer와 Container Layer에서 동일한 파일이 존재하는 경우 Container Layer가 우선순위를 가진다.

참고: https://github.com/jquast/docker/blob/master/docs/userguide/storagedriver/overlayfs-driver.md

 

여기서, 우리가 새로운 도커 이미지를 생성하는 경우 컨테이너 레이어(upperdir)를 스냅샷으로 만든 뒤 새로운 이미지 레이어로서 추가하는 방식이다. 각 이미지 레이어는 /var/lib/docker/overlay 디렉토리 아래에 자체 디렉토리로 구현된다.

 

또한, Docker가 이미지의 레이어들 간에 데이터를 효율적으로 공유하기 위해 하드 링크를 사용한다. 다시말해, 동일한 파일이 여러 레이어에 걸쳐 존재하더라도, 실제로는 하나의 파일 데이터만 저장되며, 각 레이어는 이 파일을 참조하는 하드 링크만을 가지게 된다.

 

Overlay 예시

아래 예시는 ubuntu 이미지를 docker pull 명령어를 통해 다운로드 받는 상황이다. 여기서 다운받은 도커 이미지는 5개의 레이어를 가지고 있음을 시사한다.

$ sudo docker pull ubuntu

Using default tag: latest
latest: Pulling from library/ubuntu

5ba4f30e5bea: Pull complete
9d7d19c9dc56: Pull complete
ac6ad7efd0f9: Pull complete
e7491a747824: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4
Status: Downloaded newer image for ubuntu:latest

 

 

앞서 언급한 내용과 같이 각 이미지 레이어는 /var/lib/docker/overlay 디렉토리 아래에 자체 디렉토리로 구현된 결과를 확인할 수 있다. (이미지 layer ID와 디렉토리 이름이 일치하지 않는것은 Docker 1.10이후에서는 정상적인 상황이다.)

 

$ ls -l /var/lib/docker/overlay2

total 24
drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b
drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1
drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5
drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed
drwx------ 2 root root 4096 Jun 20 07:36 l

 

또한, 앞서 언급하였듯이 Docker가 이미지의 레이어들 간에 데이터를 효율적으로 공유하기 위해 하드 링크를 사용하며 동일한 파일을 가리키는 여러 하드 링크는 동일한 inode 번호를 가지게 되어진다.

Inode: 파일의 메타데이터를 저장하는 파일 시스템의 데이터 구조

 

즉, 하드 링크가 있는 모든 파일 경로는 동일한 inode를 참조하여 동일한 데이터를 가리키게 된다. 

아래 예시는 두 파일의 inode 번호가 동일(19793696)하다는 것을 보여주며 두 경로가 동일한 파일 데이터를 가리키고 있다는 것이다.

$ ls -i /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls
19793696 /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls

$ ls -i /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls
19793696 /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls

 

이 결과의 시사점은 Docker의 여러 이미지 레이어가 동일한 파일을 공유하더라도, 하드 링크를 사용함으로써, 동일한 파일 데이터는 실제로 한 번만 디스크에 저장되어진다. 

즉, 디스크 공간은 최소한으로 사용하고 중복된 파일저장을 피할 수 있다는 것이다.


Reference

https://github.com/jquast/docker/blob/master/docs/userguide/storagedriver/overlayfs-driver.md

https://blog.naver.com/alice_k106/221530340759

https://jvns.ca/images/overlay.jpeg

https://velog.io/@lom/Docker-overlay2

 

댓글