✔️ 이미지 레이어
httpd:latest의 레이어를 확인해보자.
vagrant@docker ~ docker image inspect httpd --format '{{ .RootFS.Layers }}'
[sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e sha256:1d1a2486e901871ad1257512d588eebb30ae0605d8353abb6635e2d313b2187c sha256:ec02eb7f3cf4dd78bc518d3a8ccf57f57336ceacb9638303891787ff2ec2e96f sha256:67bb571b5bd2b65cbdf2c93c6f9dc8e89414055dd7444df617b23466996f3be7 sha256:e83f42350a11889083536c5af330dcf15fd3624f8e956f4086e1f0cfb07ff246]
1, 2, 3, 4, 5 다섯개의 레이어가 합쳐져서 이미지로 만들어졌다. 이미지의 레이어는 모두 read-only이다.
이 이미지로 컨테이너를 띄우고 변경을 하면 추가 rw 레이어가 생긴다. 그리고 commit하여 다시 이미지로 만든다.
myhttpd:latest
vagrant@docker ~ docker image inspect myhttpd:latest --format '{{ .RootFS.Layers }}'
[sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e sha256:1d1a2486e901871ad1257512d588eebb30ae0605d8353abb6635e2d313b2187c sha256:ec02eb7f3cf4dd78bc518d3a8ccf57f57336ceacb9638303891787ff2ec2e96f sha256:67bb571b5bd2b65cbdf2c93c6f9dc8e89414055dd7444df617b23466996f3be7 sha256:e83f42350a11889083536c5af330dcf15fd3624f8e956f4086e1f0cfb07ff246 sha256:16483f52cc100df0a06a7d2739b057112f9c70bbc6f29092db92dff338830f05]
앞서 5개의 레이어에서 변경을 위한 rw 레이어가 추가되어 6개의 레이어가 되었다.
마지막으로 추가된 rw 레이어는 이미지로 생성되면서 read-only 상태로 바뀐다.
✔️ docker history
이미지 생성 로그 확인
docker history <IMAGE>
✔️ 예시
vagrant@docker ~ docker history httpd
IMAGE CREATED CREATED BY SIZE COMMENT
c30a46771695 2 weeks ago /bin/sh -c #(nop) CMD ["httpd-foreground"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 2 weeks ago /bin/sh -c #(nop) COPY file:c432ff61c4993ecd… 138B
<missing> 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGWINCH 0B
<missing> 2 weeks ago /bin/sh -c set -eux; savedAptMark="$(apt-m… 60.6MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PATCHES= 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_SHA256=d0bbd112… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_VERSION=2.4.53 0B
<missing> 2 weeks ago /bin/sh -c set -eux; apt-get update; apt-g… 2.63MB
<missing> 2 weeks ago /bin/sh -c #(nop) WORKDIR /usr/local/apache2 0B
<missing> 2 weeks ago /bin/sh -c mkdir -p "$HTTPD_PREFIX" && chow… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV PATH=/usr/local/apach… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PREFIX=/usr/loc… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:8b1e79f91081eb527… 80.4MB
missing은 로컬 저장소에 없다는 뜻이다.
레이어를 쌓으면서 사용된 명령어들이 적혀있다. 우리가 가진 이미지는 최상단의 c30a46771695
이미지이다.
사이즈가 있다는 것은 파일이 변경되거나 추가되었다는 의미이다.
vagrant@docker ~ docker history myhttpd:latest
IMAGE CREATED CREATED BY SIZE COMMENT
26cb7321f015 2 hours ago httpd-foreground 93B # 우리가 커밋한 작업 (index.html 변경 작업)이 나타난다.
c30a46771695 2 weeks ago /bin/sh -c #(nop) CMD ["httpd-foreground"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 2 weeks ago /bin/sh -c #(nop) COPY file:c432ff61c4993ecd… 138B
<missing> 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGWINCH 0B
<missing> 2 weeks ago /bin/sh -c set -eux; savedAptMark="$(apt-m… 60.6MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PATCHES= 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_SHA256=d0bbd112… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_VERSION=2.4.53 0B
<missing> 2 weeks ago /bin/sh -c set -eux; apt-get update; apt-g… 2.63MB
<missing> 2 weeks ago /bin/sh -c #(nop) WORKDIR /usr/local/apache2 0B
<missing> 2 weeks ago /bin/sh -c mkdir -p "$HTTPD_PREFIX" && chow… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV PATH=/usr/local/apach… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PREFIX=/usr/loc… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:8b1e79f91081eb527… 80.4MB
커스텀한 이미지를 보면 최상단의 c30a46771695
이미지 위에 하나의 레이어가 더 쌓인 것을 볼 수 있다.
ubuntu:focal Base Image에 레이어를 2번 쌓아보자
vagrant@docker ~ docker run -itd ubuntu:focal
7f9a063ee6e980e67d58dc5260fc5a7fe7a4af5910f01c2caf1b21d3255f5417
vagrant@docker ~ echo "hello a" > a.txt
vagrant@docker ~ echo "hello b" > b.txt
vagrant@docker ~ docker cp a.txt 7f:/root
vagrant@docker ~ docker diff 7f
C /root
A /root/a.txt
vagrant@docker ~ docker commit 7f ubuntu:focal-v1
sha256:d96aee93881a9996d00c1982c32207041cb08ed0ce1f74ad1079df3c6716fe75
vagrant@docker ~ docker run -itd ubuntu:focal-v1
5dcde2068c57cd112eb16284bdc40104bc3b0766a1aafb7051ad26112377191c
vagrant@docker ~ docker cp b.txt 5d:/root
vagrant@docker ~ docker commit 5d ubuntu:focal-v2
sha256:c7e71d9715dec4a9e6e00b06ddf8441056238d784879d1adb020e57579548c32
vagrant@docker ~ docker image inspect ubuntu:focal --format '{{ .RootFS.Layers }}'
[sha256:bf8cedc62fb3ef98ad0dff2be56ca451dd3ea69abd0031ad3e0fe5d9f9e4dfff]
vagrant@docker ~ docker image inspect ubuntu:focal-v1 --format '{{ .RootFS.Layers }}'
[sha256:bf8cedc62fb3ef98ad0dff2be56ca451dd3ea69abd0031ad3e0fe5d9f9e4dfff sha256:fb29363a57e520197dc08bf2005d5f10f6d75fb6d7303ffa4e4778f48ed60a56]
vagrant@docker ~ docker image inspect ubuntu:focal-v2 --format '{{ .RootFS.Layers }}'
[sha256:bf8cedc62fb3ef98ad0dff2be56ca451dd3ea69abd0031ad3e0fe5d9f9e4dfff sha256:fb29363a57e520197dc08bf2005d5f10f6d75fb6d7303ffa4e4778f48ed60a56 sha256:6fb85e8ee42d03362523630547b4404c86e119694d17b137f2738f3041497927]
vagrant@docker ~ docker history ubuntu:focal-v2
IMAGE CREATED CREATED BY SIZE COMMENT
c7e71d9715de About a minute ago bash 8B
d96aee93881a 2 minutes ago bash 8B
53df61775e88 10 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 10 days ago /bin/sh -c #(nop) ADD file:7009ad0ee0bbe5ed7… 72.8MB
ubuntu:focal 이미지는 1개의 레이어로 구성된다.
a.txt를 추가해 하나의 레이어가 추가된 ubuntu:focal-v1 이 되었으며
b.txt를 추가해 하나의 레이어가 더 추가된 ubuntu:focal-v2 이미지가 되었다.
✔️ overlay2 파일 시스템
overlay2 : 파일 시스템
우리가 사용하는 이미지, 컨테이너, 볼륨 등이 overlay2라는 파일 시스템에 의해서 만들어지고 관리된다.
레이어드 파일 시스템의 종류는 다양하며 그 중 하나가 overlay2이고 도커에서 사용하는 표준 파일 시스템이다.
union file system 개념은 블록 장치가 여러개 있을 때 각각의 블록 장치를 하나의 장치인 것 처럼 만들어주는 것이다.
a.txt, b.txt, c.txt 각각 세개의 파일이 따로 있을 때 이를 합쳐 하나의 블록안에 세개의 파일이있는 것처럼 사용할 수 있도록 해주는 방식이 레이어드 파일 시스템이며 그 근원이되는 것이 union file system이다.
aufs라는 파일 시스템은 docker가 만든 것이며 실제 리눅스 커널에 포함되어 있지 않은 파일 시스템이었다.
RH 계열의 리눅스에서는 aufs를 기본적으로 포함시키지 않아 사용할 수 없었고 패키지로도 설치가 불가능했다.
리눅스 배포판마다 사용하는 레이어드 시스템의 파편화가 발생했고 새롭게 표준으로 만든 것이 overlay2 파일 시스템이다.
레이어드 파일 시스템이라는 것은 여러개의 레이어를 합쳐서 하나의 이미지나 컨테이너로 제공하는 것이다.
하지만 다른 방향에서 생각해보면 레이어의 사용에는 그 이유가 있지 않을까 ?
결론적으로 레이어를 여러개 가지는 이유는 데이터 저장의 효율성을 위해서이다.
레이어를 분리시키면 동일한 레이어가 있는 경우에는 해당 레이어를 받지 않아도 된다.
즉, 중복되는 레이어는 별도로 저장할 필요가 없다.
베이스 이미지가 있고 a.txt를 추가하는 레이어, b.txt를 추가하는 레이어가 있는 것이 좋을지 아니면 하나의 레이어에 a.txt, b.txt가 모두 있는 것이 좋을 지는 상황에 따라 전략적으로 생각해야한다.
사용할 이미지의 a.txt, b.txt에 변경 요소가 적다면 하나의 레이어를 사용하는 편이 좋을 것이다.
하지만 a.txt에는 변경 요소가 적으나 b.txt는 자주 변경된다고 하면 레이어를 분리시켜놓는 편이 좋을 것이다.
하나의 레이어에 구성해놓으면 b.txt 파일 하나때문에 레이어 전체가 바뀌어야 하기 때문이다.
✔️ 레이어의 추가 과정
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/d2a0cba6ba410e5ef204c61a3504ab315788adbe829124242e15f151fda4f9f5-init/diff:/var/lib/docker/overlay2/2b83d614d22eaa31ac36f9dfd9d5b688c0df924b4bf23f4d3b7a016b831ea365/diff",
"MergedDir": "/var/lib/docker/overlay2/d2a0cba6ba410e5ef204c61a3504ab315788adbe829124242e15f151fda4f9f5/merged",
"UpperDir": "/var/lib/docker/overlay2/d2a0cba6ba410e5ef204c61a3504ab315788adbe829124242e15f151fda4f9f5/diff",
"WorkDir": "/var/lib/docker/overlay2/d2a0cba6ba410e5ef204c61a3504ab315788adbe829124242e15f151fda4f9f5/work"
},
"Name": "overlay2"
},
"/var/lib/docker/overlay2/d2a0cba6ba410e5ef204c61a3504ab315788adbe829124242e15f151fda4f9f5-init/diff: # 첫번째 레이어
/var/lib/docker/overlay2/2b83d614d22eaa31ac36f9dfd9d5b688c0df924b4bf23f4d3b7a016b831ea365/diff", # rw 레이어
우분투 이미지는 layer가 1개이다. 컨테이너를 만들면 그 위에 레이어가 하나 더 만들어진다.
처음에는 레이어의 상태가 read-only, read/write 였다가 commit하는 순간 ro, ro로 변경된다.
즉, 컨테이너를 생성하면 rw 레이어가 하나 추가되며 해당 레이어에 변경 사항을 기록하고 commit하면 ro 레이어가 되는 것이다.
✔️ 기존 레이어는 변경 가능한가 ?
기존의 레이어는 절대 변경할 수 없다.
파일을 지우면 실제로 파일이 지워지는 것이 아니라 그 파일을 지운 기록이 있는 레이어가 만들어지는 것이다.
2MB 크기를 가지는 a라는 파일이 있다. 이 a 파일을 지우려고 한다면 "지웠다"라고 하는 정보를 가지는 레이어가 필요하다.
그래야 두 레이어를 결합했을 때 a 파일이 보이지 않는다. (지워진 척 할 수 있다.)
하지만 실제로 지워진 것이 아니므로 이미지의 용량에는 a 파일의 용량도 포함되어 있다.
✔️ docker export
docker export <CONTAINER> -o <TARFILE>
docker save : image → .tar archive
docker export : 컨테이너 → .tar archive
vagrant@docker ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8b4ab3f3480 wordpress:5-apache "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 80/tcp upbeat_archimedes
vagrant@docker ~ docker export a8 -o httpd.tar
vagrant@docker ~ ls
a.txt b.txt centos7 centos7.tar contents focal-v2 focal-v2.tar hello-world.tar httpd.conf httpd.tar image-build
vagrant@docker ~ mkdir httpd
vagrant@docker ~ tar xf httpd.tar -C httpd
vagrant@docker ~ cd httpd
vagrant@docker ~/httpd ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
컨테이너 전체 파일 시스템을 아카이브 한 것이므로 따로 레이어로 보이지 않는다.
컨테이너에 어떤 내용이 있는지 궁금할 때 export로 확인하는 방법도 있다.
✔️ docker import
docker import <TARFILE> <IMAGE>:<TAG>
docker import : 아카이브 파일 → 이미지
docker load : 아카이브 파일 → 컨테이너
vagrant@docker ~ docker import httpd.tar a:v1
sha256:7f0cd5ee12ac89b326abdf61db192726b176649ad2f6cdf7d8a58646bfaa7b6d
vagrant@docker ~ docker image ls
vagrant@docker ~ docker image inspect a:v1
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:84ae61c301d976f0d107a2c0e831d4f43e1edec2d85e4ba9f175b953f7bf117d"
]
},
하나의 레이어만이 존재한다.
레이어가 여러 층일 때 레이어를 하나로 만들고 싶을 때 사용할 수도 있다.
'DevOps > Docker' 카테고리의 다른 글
[Docker] Shell(쉘) 변수 (0) | 2022.05.11 |
---|---|
[Docker] Dockerfile로 이미지 빌드하기 (0) | 2022.05.11 |
[Docker] docker commit 명령을 이용하여 이미지 빌드하기 (0) | 2022.05.10 |
[Docker] Netfilter의 역할 (0) | 2022.05.10 |
[Docker] Docker Network - 2 (0) | 2022.05.10 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!