도커 이미지 "레이어"란 무엇입니까?
저는 도커가 처음이고 도커 이미지가 무엇인지 정확히 이해하려고 노력하고 있습니다.도커 이미지의 모든 단일 정의는 "레이어"라는 용어를 사용하지만 레이어가 의미하는 바를 정의하지는 않는 것 같습니다.
공식 도커 문서에서:
도커 이미지는 도커 컨테이너가 시작되는 읽기 전용 템플릿임을 이미 확인했습니다.각 이미지는 일련의 레이어로 구성됩니다.도커는 유니온 파일 시스템을 사용하여 이러한 계층을 단일 이미지로 결합합니다.유니온 파일 시스템을 사용하면 분기라고 하는 별도의 파일 시스템의 파일과 디렉터리를 투명하게 중첩하여 하나의 일관된 파일 시스템을 구성할 수 있습니다.
그래서 저는 (정확히는) 층이 무엇인지 묻습니다. 누가 그들의 구체적인 예를 몇 가지 들어줄 수 있을까요?그리고 이 층들이 어떻게 "스냅샷"을 하여 이미지를 형성합니까?
제가 늦을지도 모르지만, 여기 제 10센트가 있습니다. (히슈타인의 대답을 보완합니다.)
기본적으로 레이어 또는 이미지 레이어는 이미지 또는 중간 이미지의 변경입니다.지정하는 모든 명령(FROM
,RUN
,COPY
도커 파일에서 등)을 사용하면 이전 이미지가 변경되어 새 계층이 생성됩니다.git를 할 때의 스테이징 변경이라고 생각하시면 됩니다.파일의 변경 사항을 추가하고, 다른 파일을 추가한 다음, 다른 변경 사항을 추가할 수 있습니다.
다음 도커 파일을 고려합니다.
FROM rails:onbuild
ENV RAILS_ENV production
ENTRYPOINT ["bundle", "exec", "puma"]
이미지를 합니다.rails:onbuild
그것은 차례로 많은 층을 가지고 있습니다.시작 이미지 위에 다른 레이어를 추가하여 환경 변수를 설정합니다.RAILS_ENV
ENV
지휘권그리고 도커에게 도망치라고 합니다bundle exec puma
(레일 서버를 부팅합니다.)그것은 또 다른 층입니다.
레이어의 개념은 이미지를 작성할 때 유용합니다.레이어는 중간 이미지이므로 도커 파일을 변경하면 도커는 변경된 레이어와 그 이후의 레이어만 재구성합니다.이를 계층 캐싱이라고 합니다.
당신은 여기에서 그것에 대해 더 읽을 수 있습니다.
도커 컨테이너 이미지는 도커 파일을 사용하여 생성됩니다.도커 파일의 모든 줄은 도면층을 작성합니다.다음 더미 예를 생각해 보십시오.
FROM ubuntu #This has its own number of layers say "X"
MAINTAINER FOO #This is one layer
RUN mkdir /tmp/foo #This is one layer
RUN apt-get install vim #This is one layer
이렇게 하면 총 레이어 수가 X+3인 최종 이미지가 생성됩니다.
그들은 예를 들어 제게 가장 의미가 있습니다.
도커 디프를 사용하여 자체 빌드의 레이어를 검사하는 중
도커 파일의 조작된 예를 들어 보겠습니다.
FROM busybox
RUN mkdir /data
# imagine this is downloading source code
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
RUN chmod -R 0777 /data
# imagine this is compiling the app
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/two
RUN chmod -R 0777 /data
# and now this cleans up that downloaded source code
RUN rm /data/one
CMD ls -alh /data
의 그들각각.dd
명령은 디스크에 1M 파일을 출력합니다.임시 컨테이너를 저장하기 위해 추가 플래그를 사용하여 이미지를 빌드합니다.
docker image build --rm=false .
출력에서 실행 중인 각 명령이 자동으로 삭제되는 대신 현재 보관 중인 임시 컨테이너에서 수행되는 것을 볼 수 있습니다.
...
Step 2/7 : RUN mkdir /data
---> Running in 04c5fa1360b0
---> 9b4368667b8c
Step 3/7 : RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
---> Running in f1b72db3bfaa
1024+0 records in
1024+0 records out
1048576 bytes (1.0MB) copied, 0.006002 seconds, 166.6MB/s
---> ea2506fc6e11
를 실행하는 경우docker diff
에 어떤 할 수 .
$ docker diff 04c5fa1360b0 # mkdir /data
A /data
$ docker diff f1b72db3bfaa # dd if=/dev/zero bs=1024 count=1024 of=/data/one
C /data
A /data/one
$ docker diff 81c607555a7d # chmod -R 0777 /data
C /data
C /data/one
$ docker diff 1bd249e1a47b # dd if=/dev/zero bs=1024 count=1024 of=/data/two
C /data
A /data/two
$ docker diff 038bd2bc5aea # chmod -R 0777 /data
C /data/one
C /data/two
$ docker diff 504c6e9b6637 # rm /data/one
C /data
D /data/one
각 줄 앞에 다음과 같은 기호가 붙습니다.A
하는 중입니다.C
기존 파일에 대한 변경을 나타냅니다.D
삭제를 나타냅니다.
다음은 TL;DR 부분입니다.
위의 각 컨테이너 파일 시스템 diff는 이미지를 컨테이너로 실행할 때 조립되는 하나의 "레이어"로 이동합니다.변경이이 각 의 레이어에 있습니다.chmod
명령은 권한 비트만 변경해도 전체 파일이 다음 계층으로 복사됩니다.삭제된 /data/one 파일은 실제로 3번이나 이전 계층에 남아 있으며 이미지를 풀하면 네트워크를 통해 복사되어 디스크에 저장됩니다.
기존 이미지 검사
를 사용하여 기존 이미지의 레이어를 생성하는 데 사용되는 명령을 볼 수 있습니다.docker history
지휘권또한 다음을 실행할 수 있습니다.docker image inspect
RootFS 섹션 아래의 레이어 목록을 참조하십시오.
위 이미지의 기록은 다음과 같습니다.
IMAGE CREATED CREATED BY SIZE COMMENT
a81cfb93008c 4 seconds ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "ls -… 0B
f36265598aef 5 seconds ago /bin/sh -c rm /data/one 0B
c79aff033b1c 7 seconds ago /bin/sh -c chmod -R 0777 /data 2.1MB
b821dfe9ea38 10 seconds ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
a5602b8e8c69 13 seconds ago /bin/sh -c chmod -R 0777 /data 1.05MB
08ec3c707b11 15 seconds ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
ed27832cb6c7 18 seconds ago /bin/sh -c mkdir /data 0B
22c2dd5ee85d 2 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:2a4c44bdcb743a52f… 1.16MB
최신 도면층이 맨 위에 나열됩니다.주목할 점은, 아래쪽에 꽤 오래된 두 개의 층이 있습니다.그것들은 그 자체로 부터 온 것입니다.이미지를 는 하의이미빌때에는지이서모다상에 합니다.FROM
인과 됩니다. 또한 이미지 메타데이터에 대한 변경을 위해 추가되는 레이어가 있습니다.CMD
실행 더 사용됩니다. 공간을 거의 차지하지 않으며 실행 중인 이미지에 적용되는 설정을 기록하기 위해 더 많이 사용됩니다.
왜 겹치지?
레이어에는 몇 가지 이점이 있습니다.첫째, 그들은 불변입니다.생성된 후에는 sha256 해시로 식별되는 계층이 변경되지 않습니다.이러한 불변성을 통해 이미지를 안전하게 구축하고 서로 분리할 수 있습니다.두 도커 파일이 동일한 초기 줄 집합을 가지고 있고 동일한 서버에 구축된 경우, 동일한 초기 계층 집합을 공유하여 디스크 공간을 절약합니다.즉, 도커 파일의 마지막 몇 줄만 변경된 상태에서 이미지를 재구축할 경우 해당 계층만 재구축하면 되고 나머지는 계층 캐시에서 재사용할 수 있습니다.이렇게 하면 도커 이미지를 매우 빠르게 재구성할 수 있습니다.
컨테이너 내부에는 이미지 파일 시스템이 표시되지만 해당 파일 시스템은 복사되지 않습니다.컨테이너는 이러한 이미지 계층 위에 자체 읽기-쓰기 파일 시스템 계층을 마운트합니다.파일의 모든 읽기는 삭제 표시를 한 계층에 도달하거나 해당 계층에 파일의 복사본이 있거나 검색할 계층이 모두 소진될 때까지 계층을 통과합니다.모든 쓰기는 컨테이너별 읽기-쓰기 계층에서 수정됩니다.
레이어 블랏 감소
계층의 한 가지 단점은 파일을 복제하거나 나중에 삭제된 파일을 전송하는 이미지를 구축하는 것입니다.은 종종 입니다.RUN
기존 파일을 삭제할 때 이러한 .특히 기존 파일을 수정하거나 파일을 삭제할 때는 이러한 단계를 처음 만들 때와 동일한 명령으로 실행해야 합니다.위의 도커 파일을 다시 쓰면 다음과 같습니다.
FROM busybox
RUN mkdir /data \
&& dd if=/dev/zero bs=1024 count=1024 of=/data/one \
&& chmod -R 0777 /data \
&& dd if=/dev/zero bs=1024 count=1024 of=/data/two \
&& chmod -R 0777 /data \
&& rm /data/one
CMD ls -alh /data
결과 영상을 비교하면 다음과 같습니다.
- 사용 중인 상자: ~1MB
- 첫 번째 이미지: ~6MB
- 두 번째 이미지: ~2MB
작성된 예제에서 몇 개의 선을 병합하는 것만으로도 이미지에 동일한 내용이 표시되고 이미지가 5MB에서 최종 이미지에 표시되는 1MB 파일로 축소되었습니다.
Docker v1.10 이후 컨텐츠 주소 지정 가능 스토리지가 도입되면서 '계층'의 개념이 상당히 달라졌습니다.계층은 이미지에 대한 개념이 없거나 이미지에 속해 있지 않으며, 이미지 간에 공유할 수 있는 파일 및 디렉토리의 모음일 뿐입니다.레이어와 이미지가 분리되었습니다.
예를 들어, 기본 이미지에서 로컬로 빌드된 이미지에 대해 다음과 같이 가정합니다.ubuntu:14.04
,docker history
명령을 실행하면 이미지 체인이 생성되지만 빌드 기록이 더 이상 로드되지 않기 때문에 일부 이미지 ID가 '누락'으로 표시됩니다.그리고 이러한 이미지를 구성하는 레이어는 다음을 통해 찾을 수 있습니다.
docker inspect <image_id> | jq -r '.[].RootFS'
는 도층내저위에 됩니다./var/lib/docker/aufs/diff
항목이 리지드선택이버인 aufs
그러나 계층 이름은 임의로 생성된 캐시 ID로 지정되어 있으며, 계층과 해당 캐시 ID 간의 링크는 보안상의 이유로 Docker Engine에만 알려져 있는 것 같습니다.나는 아직도 그들을 찾을 방법을 찾고 있습니다.
- 영상과 해당 합성 레이어 사이의 해당 관계
- 디스크의 실제 위치 및 계층 크기
이 블로그는 많은 통찰력을 제공했습니다.
이미지는 레이어로 구성됩니다.각 계층은 파일 시스템 변경 사항의 집합입니다.계층에는 환경 변수 또는 기본 인수와 같은 구성 메타데이터가 없습니다. 이는 특정 계층이 아닌 이미지 전체의 속성입니다.
따라서 기본적으로 계층은 파일 시스템에 대한 일련의 변경 사항일 뿐입니다.
저는 공식 문서가 꽤 자세한 설명을 한다고 생각합니다: https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/ .
(출처: docker.com )
파일에서 되며, 의 각 은 새로운하며, 그생성됩니다. 도커 파일의 각 라인은 새 레이어를 생성하고 결과는 폼으로 표시되는 이미지입니다.repo:tag
,맘에 들다ubuntu:15.04
.
자세한 내용은 위의 공식 문서를 읽어보십시오.
저는 그것들이 이전 층의 차이와 같다고 생각하곤 했습니다.여기에 나와 있는 답변 중 일부를 읽고도 확신할 수 없었습니다. 파일 시스템에 대한 일련의 변경 사항으로 설명되어 있습니다.Docker 파일을 작성하여 Diff에 가깝다는 것을 보여주었습니다. 즉, 이전 계층에 의존합니다.
이 두 개의 도커 파일이 주어지면,
FROM bash
RUN mkdir /data
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/two
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/three
그리고.
FROM bash
RUN mkdir /data
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/three
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/two
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
동일한 계층 집합이 파일 시스템의 변경에 관한 것이라면 예상할 수 있지만, 이는 그렇지 않습니다.
$ docker history img_1
IMAGE CREATED CREATED BY SIZE
30daa166a9c5 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
4467d16e79f5 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
c299561fd031 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
646feb178431 6 minutes ago /bin/sh -c mkdir /data 0B
78664daf24f4 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B
<more missing...>
그리고.
$ docker history img_2
IMAGE CREATED CREATED BY SIZE
f55c91305f8c 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
29b3b627c76f 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
18360be603aa 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
646feb178431 6 minutes ago /bin/sh -c mkdir /data 0B
78664daf24f4 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B
<more missing...>
파일 시스템에 대한 변경사항이 두 경우 모두 동일하더라도 순서가 어떻게 중요한지 확인할 수 있습니다.
@David Castillo씨에게 유용한 정보를 주셔서 감사합니다.레이어는 쉽게 실행하거나 실행 취소할 수 있는 이미지의 바이너리 변경 또는 명령이라고 생각합니다.계층의 계층과 동일하게 단계적으로 수행되므로 "계층"이라고 부릅니다.
자세한 내용은 다음과 같은 "도커 기록"을 참조하십시오.
도커 이미지 --트리경고: '--tree'는 더 이상 사용되지 않습니다. 곧 제거됩니다.용법을 참조하십시오. ◦-511136ea3c5a 가상사이즈: 0B 태그: 스크래치: 최신◦-59e359cb35ef 가상 크기: 85.18MB◦-e8d37d9e3476 가상 크기: 85.18MB 태그: 데비안: wheezy◦-c58b36b8f285 가상 크기: 85.18MB◦-90ea6e05b074 가상사이즈:118.6MB◦-5dc74cffc471 가상 크기: 118.6MB 태그: vim: 최신
제 개인적인 이해는 우리가 도커 레이어를 github commit과 비교할 수 있다는 것입니다.기본 이미지(신선한 마스터 repo)의 경우 여러 커밋을 수행하고, 모든 커밋은 마스터 상태를 변경하며, 도커에서는 동일하며, 모든 계층은 이전 중간 계층을 기반으로 일부 작업을 수행합니다.그리고 나서, 이 층은 다음 층의 새로운 중간층이 됩니다.
제가 이 질문 스레드에 추가할 수 있는 것은 git를 메타포로 사용하여 레이어, 이미지 및 컨테이너의 개념을 이해할 수 있다는 것입니다.
방법은 다음과 같습니다.
- Git repo는 이미지에 대응합니다.
- 도면층을 추가하기 위해 상호 응답을 gitrepo로 커밋합니다.
- 는 깃레포로 합니다.
git init
는 른한편이빌시작다니됩드가로 시작합니다.FROM
다단계 빌드에서 여러 개를 사용할 수 있지만 마지막 빌드만 사용되므로 개념은 동일하게 유지됩니다. - Git repo는 일련의 명령/레이어에 의해 이미지가 구축되는 동안 업데이트되거나 일련의 커밋을 기반으로 합니다(단,
CMD
각 명령이 이미지의 새 레이어를 생성합니다.
- 는 깃레포로 합니다.
- 합니다(Git repo 복를실행것는같것시습다과니작는하를너테컨이은제하하고▁cloningg▁(같▁the다▁starting습▁container니▁and▁a▁cor것o▁running▁to과o를itrespondsit▁rep시).
CMD
. 따라서 Git repo를 복제할 때 일반적으로 최신 커밋을 복제하는 반면 도커는 시작할 때 이미지의 최신 생성 계층을 사용합니다().docker run ...
마지막으로, 계층을 이해하기 위해서는 고립된 개념이라고 생각하기 어렵고, 구성 요소 또는 컨테이너/이미지를 작동시키는 구성 요소 중 하나로 접근합니다. 가지로찬마,로,commit
는 git 버전 관리 시스템의 구성 요소 중 하나이며, commit을 선택하는 동안 아무 것이나 부를 수 있습니다 :).
계층은 이미지를 구축한 결과로 생성된 파일 및 폴더를 포함하는 폴더입니다.
예:
FROM alpine:3.14 # Layer 1
RUN apk add --no-cache tree # Layer 2
COPY test.txt /tmp/ # Layer 3
ENTRYPOINT ["tree"]
이 Docker 파일은 세 개의 폴더를 생성한 다음 호스트 시스템에 복사하여 함께 "통합"하여 Union Filesystem이라고 합니다.실제로 폴더는 물리적으로 병합되지 않지만 Union Mount를 사용하여 실제로 병합된 것처럼 착각합니다.
위의 예에서는 다음이 있습니다.
# Layer 1
/var/lib/docker/overlay2/1d06...35310/diff
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
# Layer 2
/var/lib/docker/overlay2/23wgom2anm2uysvg988r3tw9c/diff
etc lib usr var
bin
tree
# Layer 3
/var/lib/docker/overlay2/41htpkg76b3zwg29kqsb103of/diff
tmp
test.txt
그런 다음 위에서 언급한 마운트 명령을 사용하여 모든 폴더를 "병합"하여 최종 리눅스 파일 시스템을 만들고, 실행 중인 프로세스(일명 컨테이너)의 루트 디렉터리로 설정합니다(이 경우 chroot 명령 또는 유사한 명령을 사용합니다).
자세한 내용은 여기에서 확인할 수 있습니다: https://martinheinz.dev/blog/44
언급URL : https://stackoverflow.com/questions/31222377/what-are-docker-image-layers
'programing' 카테고리의 다른 글
커밋된 트랜잭션 롤백 (0) | 2023.07.29 |
---|---|
선형 레이아웃을 스크롤 가능하게 하려면 어떻게 해야 합니까? (0) | 2023.07.29 |
VSCODE에서 "sudo"로 프로그램을 디버깅하는 방법 (0) | 2023.07.24 |
작은 Ajax JavaScript 라이브러리 (0) | 2023.07.24 |
행에서 공통 값을 찾으려면 SQL 쿼리에 도움말이 필요합니다. (0) | 2023.07.24 |