연재 시리즈

도커이미지레이어 1편 - 이미지 레이어

악분 2021. 11. 30. 23:20
반응형

 

1편에서는 도커 이미지 레이어를 설명합니다. 이 글은 영상으로도 만나 볼 수 있습니다. 

https://youtu.be/StsgkD71028

 

1. 준비

Dockerfile을 한번이라도 써봤다는 전제로 글을 설명합니다.

 

2. 레이어란?

도커 이미지는 레이어(layer)와 메타정보로 구성되어 있습니다. docker insepect명령어로 도커 이미지가 어떤 레이어로 구성되어 있는지 확인할 수 있습니다.

 

실습을 위해 docker pull을 이용해서 busybox:1.34.1 도커 이미지를 다운로드 받습니다. 

docker pull busybox:1.34.1

 

docker inspect명령어로 busybox 이미지 메타정보를 확인합니다.

docker inspect busybox:1.34.1

 

RootFS.Layers필드에 busybox:1.34.1 도커 이미지가 어떤 레이어를 가지고 있는지 확인할 수 있습니다. 총 1개 레이어를 가지고 있습니다. docker inspect에서 sha256으로 시작하는 숫자는 레이어 메타정보 id입니다.

docker 이미지 layer확인

 

도커 이미지 레이어 메타정보는 /var/lib/image/<storage-driver>/layerdb/sha256디렉터리에 저장됩니다. 도커는 default로 overlay2를 사용합니다.

docker 이미지 layer메타정보 위치

 

3. 도커 레이어 데이터(digest) 위치

도커 레이어 데이터를 digest(정확히 표현하면 레이어 데이터를 해시한 결과를 digest라고 합니다)라고 부릅니다. 레이어 digest 저장위치는 /var/lib/docker/<storage-driver>디렉터리에 저장됩니다. 레이어 메타정보에서 cache-id파일에 레이어 digest가 있습니다.

layer 데이터 위치

 

4. 중간정리

지금까지 내용을 정리하면 도커 이미지는 레이어로 구성되어 있고 레이어 메타정보와 레이어 데이터를 따로 관리합니다.

docker 이미지와 layerid, layer digest관계 요약

 

5. 레이어 읽기/쓰기 속성

레이어는 읽기/쓰기 속성이 있습니다. 도커 이미지 레이어는 읽기속성만 가지고 있습니다

 

컨테이너 이미지가 생성되면 컨테이너 레이어가 생성되고 쓰기 속성을 갖습니다. 쓰기 속성이 있는 이유는 컨테이너가 작업하는 데이터(파일, 디렉터리)를 저장하기 위해서입니다. 컨테이너가 종료되면 컨테이너 레이어가 삭제됩니다. 컨테이너에서 작업한 데이터가 날아간 이유가 바로, 컨테이너 레이어가 삭제되기 때문입니다.

 

지금까지 설명한 내용은 공식문서[1]에서 그림으로 쉽게 설명하고 있습니다.

 

6. 컨테이너 layer생성 확인

도커 컨테이너를 생성하면 컨테이너 레이어가 실제로 생성되는지 확인해보겠습니다.

 

도커 컨테이너 실행 전 /var/lib/docker/overlay2 디렉터리를 확인합니다. busybox 이미지의 레이어 digest만 있습니다.

docker 컨테이너 실행 전 layer digest확인

 

docker run명령어로 docker 컨테이너를 실행합니다.

docker run --rm -it busybox:1.34.1 /bin/sh

 

다시 /var/lib/docker/overlay2 디렉터리를 확인하면 2개의 도커 레이어 digest가 생성된 것을 확인 할 수 있습니다. 새로 생성된 레이어가 컨테이너 레이어이고 쓰기 속성을 가지고 있습니다. init으로 끝나는 digest는 초기화에 사용되는 레이어입니다. init이 안붙은 digest가 컨테이너 레이어입니다.

docker 컨테이너 실행 후 layer digest확인

 

7. 레이어 digest에 데이터 작업

여기서 재미있는 실험을 해보겠습니다. 레이어 digest에 파일을 생성하면 도커 컨테이너 쉘에서 생성한 파일을 볼 수 있을까요? 정답은 잘 보입니다. 

 

컨테이너 레이어 디렉터리 안에 merged 디렉터리로 위치를 변경해보세요.

cd <digest>/merged

 

그리고 hello.txt파일을 생성하고 파일내용을 작성합니다.

# vi hello.txt
helloworld

 

6번 챕터에서 생성한 컨테이너 쉘에서 ls명령어를 입력하면 레이어 digest에서 작성한 hello.txt가 보입니다. 

 

8. 유니온 파일 시스템(Union file system)

컨테이너가 실행되면 도커 이미지 레이어를 참조하고 컨테이너 레이어를 생성합니다. 결과적으로 2종류의 레이어가 생성됩니다. 2종류의 레이어는 도커 컨테이너에 합쳐서 파일 시스템으로 마운트 됩니다.

도커 컨테이너 파일 시스테 마운트

 

더 상세하게 살펴보면 유니온 파일시스템을 이용하여 컨테이너에 마운트합니다. 유니온 파일 시스템의 정의는 https://blog.naver.com/alice_k106/221530340759에 자세히 설명되어 있습니다. lowerdir에 도커 이미지 레이어가 위치하고 읽기전용으로 설정됩니다. 그리고, upperdir에는 컨테이너 이미지가 위치하고 쓰기 속성으로 됩니다. lowerdir과 upperdir은 합쳐져셔 merged로 관리됩니다. 만약, 같은 파일을 작업할 경우 upperdir이 우선순위를 갖습니다. (upperdir이 우선순위를 갖을 때, lowerdir 데이터는 훼손되지 않습니다.)

 

챕터7에서 merged디렉터리에 작업한 결과가 컨테이너 쉘에서 보였던 이유가 파일 시스템으로 마운트 되기 때문입니다.

 

9. 마치며

이번 글에서는 도커 이미지 구조의 핵심인 레이어에 대해 살펴봤습니다. 추가로 컨테이너가 실행 될 때 도커 이미지 레이어와 컨테이너 레이어 두개가 파일 시스템으로 마운트 되는 것을 확인했습니다.

 

레이어 구조를 공부하면 일에 어떤 부분에 적용할 수 있을까요? 바로 이미지 크기를 최소화 할 때 사용할 수 있습니다. 각 레이어는 0바이트 이상 크기를 갖습니다. 실무에서는 도커 이미지 크기를 최대한 줄이기 위해 레이어크기를 줄입니다. 디스크 용량이 제한되어 있으니까요! 시간이 된다면 이미지 레이어를 활용하여 어떻게 이미지 크기를 줄일 수 있는지 과정을 다루려고 합니다.

 

참고자료

[1] docker storage 공식문서: https://docs.docker.com/storage/storagedriver/

[2] 44bits: https://www.44bits.io/ko/post/building-docker-image-basic-commit-diff-and-dockerfile

[3] dockerfile 공식문서: https://docs.docker.com/engine/reference/builder/

[4] 44bit: https://www.44bits.io/ko/post/how-docker-image-work

[5] 도커 이미지 디자인: https://gist.github.com/aaronlehmann/b42a2eaf633fc949f93b

[6] 이전 도커 이미지 디자인 설명: https://blog.naver.com/alice_k106/221149596996

[7] 도커 이미지 생성과정 설명: https://darkrasid.github.io/docker/container/image/create/2017/04/19/docker-image-create.html

[8] 도커 공식문서: https://docs.docker.com/storage/storagedriver/overlayfs-driver/#how-the-overlay-driver-works

[9] 유니온 파일시스템: https://blog.naver.com/alice_k106/221530340759

반응형