본문 바로가기
프로그래밍/도커

도커의 Image layer

by Hwan2 2023. 3. 13.
728x90
반응형

이 글을 작성하게 된 계기는 Container를 띄울 때 Container에 생성한 파일과 디렉토리들이 어디에 저장되고 관리되는지

궁금해서 찾다가 작성하게 되었습니다.

 

우리는 Docker를 사용할 때 아무생각 없이 Image를 pull받아서 Docker container를 실행합니다.

Docker Image를 받아오면 sha 256으로된 hash값들이 보이고 이를 pull하면서 받오게 됩니다.

mysql image를 받아오는 중입니다.

저런 hash값들의 정체가 무엇인지, Container에서 파일과 디렉토리를 생성하면 어디에 저장되는지 등을 알아보려 합니다.

 

1. Docker image layer

Docker image는 layer로 이루어져 있으며, 각 layer 계층은 모두 Read only로 구성됩니다.

그 후 마지막 layer 위에 Container read/write 부분의 layer가 얹어지고 실행됩니다.

이 layer에 Container에서 write된 모든 데이터들이 저장됩니다.

 

https://docs.docker.com/storage/storagedriver/

각 Read only layer들은 모든 Container가 공유하게 됩니다.

따라서 같은 image를 사용해 run을 하면 모두 동일한 Container를 얻을 수 있게되는 것입니다.

또한 동일한 image를 run할 때 image를 새로 받아오지 않는 이유도 다 이 때문입니다.

 

https://docs.docker.com/storage/storagedriver/

그럼 write layer를 찾고 실제 그 값이 있는지 확인해보겠습니다.

 

  • Docker 안에서 파일 생성
[root@ip-172-31-11-2 overlay2]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                 NAMES
9b771db5bd22   mysql     "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes   3306/tcp, 33060/tcp   reverent_hypatia

[root@ip-172-31-11-2 overlay2]# docker exec -it 9b77 /bin/bash
bash-4.4# ls
bin  boot  dev  docker-entrypoint-initdb.d  entrypoint.sh  etc  home  lib  lib64  media  mnt  mysql_test  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

bash-4.4# mkdir mysql_test
mkdir: cannot create directory 'mysql_test': File exists
bash-4.4#

mysql_test라는 것을 미리 만들었습니다.

 

  • Docker diff확인
[root@ip-172-31-11-2 /]# cd /var/lib/docker/overlay2/
[root@ip-172-31-11-2 overlay2]# find . -name mysql_test
./cce3680e3378e4360ffb0191c7e58399e88f41eeba9526d247ca67e423fc743c/diff/mysql_test
./cce3680e3378e4360ffb0191c7e58399e88f41eeba9526d247ca67e423fc743c/merged/mysql_test

[root@ip-172-31-11-2 overlay2]# cd cce3680e3378e4360ffb0191c7e58399e88f41eeba9526d247ca67e423fc743c
[root@ip-172-31-11-2 cce3680e3378e4360ffb0191c7e58399e88f41eeba9526d247ca67e423fc743c]# cd diff
[root@ip-172-31-11-2 diff]# ls
mysql_test  root  run  tmp

생성한 mysql_test라는 폴더가 있습니다. 그럼 여기서 파일을 하나 만들고 도커 안에서 확인해보겠습니다.

 

[root@ip-172-31-11-2 diff]# ls
mysql_test  root  run  tmp
[root@ip-172-31-11-2 diff]# cd mysql_test/
[root@ip-172-31-11-2 mysql_test]# touch test.txt
[root@ip-172-31-11-2 mysql_test]# echo "hi hwan" >> test.txt

### docker
bash-4.4# cd mysql_test/
bash-4.4# ls
  test.txt

bash-4.4# cat test.txt
hi hwan

이렇게 적용되는걸 확인할 수 있습니다.

 

2. OverlayFS

이러한 Docker image layer구조는 OverlayFS방식으로 만들어 집니다.

OverlayFS 는 Linux 용 유니온 마운트 파일 시스템 구현 입니다. 여러 기본 마운트 지점을 하나로 결합하여 모든 소스의 기본 파일과 하위 디렉토리를 포함하는 단일 디렉토리 구조를 만듭니다. 

 

OverlayFS구조는 Docker의 GraphDriver의 구조와 같습니다.

[root@ip-172-31-11-2 overlay2]# docker inspect mysql --format='{{json .GraphDriver.Data}}' | jq
{
  "LowerDir": "/var/lib/docker/overlay2/aebbcb0830285b9c9bd00a7dbc5745ea0b48d7895979715515b76ed02a6a8d63/diff:/var/lib/docker/overlay2/7201cbff4d6dc8978d334698ee233f321acc7b4d69b4634f018e42e9099261f1/diff:/docker/overlay2/b40d888c3f7a8c558beb73d5e5a9f4c4bce4e851bbc62b281357115017ce282c/diff:/var/lib/docker/overlay2/e724909d3ed46f213a3a78053b3fff56950c8c5b55154cdaa93c789445339d9e/diff:/var/lib/docker/overlay2/2b011ffc46cddd7f6dee1c7fc92c47ff222bcc023cff40dfdf3babf0/diff:/var/lib/docker/overlay2/5f6258f78fb8660ec71bccd9f9ceb4f2456d9479cce9cc5bcbec0dbcf4771ed2/diff:/var/lib/docker/overlay2/1cbe395e249ebc7c0e592913e50983bfdc067fde255b029075ca21fa/diff:/var/lib/docker/overlay2/8930ac15d0e2fb62a4fe424e1e0b0a7f4a4e3219eec024b337cfa4b2bc6154a3/diff:/var/lib/docker/overlay2/56ba0f5f1f018bf473ca4eec4873414517257dad28e02891a553948b/diff:/var/lib/docker/overlay2/5772c70728a464d170afa8e64c79f47c45cec05570e763d0392b39144491d0ab/diff",
  "MergedDir": "/var/lib/docker/overlay2/a1327e15354615cd6dd21d4577caed5a0342968556237f51f302b0dcb98bc752/merged",
  "UpperDir": "/var/lib/docker/overlay2/a1327e15354615cd6dd21d4577caed5a0342968556237f51f302b0dcb98bc752/diff",
  "WorkDir": "/var/lib/docker/overlay2/a1327e15354615cd6dd21d4577caed5a0342968556237f51f302b0dcb98bc752/work"
}

각 dir은 목적을 가집니다.

  • lower dir: 아래쪽에 위치한 디렉토리 레이어. 여기에 위치한 entry들은 read-only로 마운트되며, 만약 수정될 경우, upper dir에 COW로 적용되고 만약 삭제될 경우 특별히 삭제됨을 표시하는 whiteout이라는 특별한 파일을 통해서 삭제됨을 기록한다.
  • upper dir: 최종적으로 write권한이 있는 맨 최상위 레이어로써, 모든 수정사항, 즉 삭제와 파일의 수정은 이 upper dir에 기록된다. upper dir에서 마스킹하는 디렉토리는 하위 디렉토리에 위치해 있더라도 무시된다.
  • merge dir: 모든 upper dir + lower dir이 표시되는 환경
  • work dir : 통합 뷰의 원자성을 보장하기 위해 존재하는 중간 계층. Overlay를 직접 사용할 때는 크게 중요하지 않다.
mount -t overlay overlay -o lowerdir=lower1/,upperdir=upper/,workdir=work/ merge/

 

이렇게 mount하게 되면 다음과 같은 디렉토리 구조를 확인할 수 있습니다.

[root@ip-172-31-11-2 overlay]# tree . -I work
.
├── lower1
├── merge
└── upper

[root@ip-172-31-11-2 overlay]# touch merge/a
[root@ip-172-31-11-2 overlay]# tree . -I work
.
├── lower1
├── merge
│   └── a
└── upper
    └── a

overlay로 mount 후 merge에 a라는 파일을 생성하면 upper에도 생성이 됩니다.

Docker image도 이러한 방식으로 적용되며, docker diff, docker commit 명령어를 통해서 위와 같은 동작을 확인할 수 있습니다.

 

Docker image를 만들땐 이러한 방식으로 layer가 추가됩니다.

 

 

Reference

https://www.44bits.io/ko/post/how-docker-image-work#overlayfs-%EC%A7%81%EC%A0%91-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B3%A0-%EC%9E%84%EC%9D%98%EC%9D%98-%EC%9C%84%EC%B9%98%EC%97%90-%EB%8F%84%EC%BB%A4-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A7%88%EC%9A%B4%ED%8A%B8%ED%95%98%EA%B8%B0

 

만들면서 이해하는 도커(Docker) 이미지: 도커 이미지 빌드 원리와 OverlayFS

도커 이미지는 유니온 마운트 기술을 활용해 계층화된 레이어들로 구성되며, 도커 레지스트리를 사용해 쉽고 효율적인 공유를 가능하게 해줍니다. 이 글에서는 도커 이미지가 저장되는 방식과

www.44bits.io

http://emal.iptime.org/noriwiki/index.php/Overlayfs

 

Overlayfs - noriwiki

개요 Overlayfs은 union mount의 한 구현 방식으로 여러 디렉토리들을 마치 하나의 디렉토리처럼 사용할 수 있도록 해주는 기법을 말한다. 마치 drawing program - clip studio의 레이어 시스템 처럼 파일 시스

emal.iptime.org

https://docs.docker.com/storage/storagedriver/

 

About storage drivers

 

docs.docker.com

 

반응형

댓글


스킨편집 -> html 편집에서