그들은 예를 들어 나에게 가장 의미가 있습니다 ...
docker diff로 자신의 빌드 레이어 검사
독창적 인 Dockerfile 예제를 보자.
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
각 컨테이너 ID에서 를 실행하면 해당 컨테이너에서 어떤 파일이 생성되었는지 확인할 수 있습니다.
$ 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 부분은 다음과 같습니다.
위의 각 컨테이너 파일 시스템 차이는 이미지를 컨테이너로 실행할 때 조립되는 하나의 "계층"으로 들어갑니다. 추가 또는 변경이있을 때 전체 파일은 각 레이어에 있습니다.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 해시로 식별되는 해당 계층은 절대 변경되지 않습니다. 이러한 불변성은 이미지가 서로 안전하게 빌드되고 포크 될 수있게합니다. 두 개의 도커 파일이 동일한 초기 라인 세트를 갖고 동일한 서버에 빌드 된 경우 동일한 초기 레이어 세트를 공유하여 디스크 공간을 절약합니다. 즉, Dockerfile의 마지막 몇 줄만 변경되어 이미지를 다시 빌드하는 경우 해당 레이어 만 다시 빌드하면되고 나머지는 레이어 캐시에서 재사용 할 수 있습니다. 이렇게하면 도커 이미지를 매우 빠르게 재구성 할 수 있습니다.
컨테이너 내부에는 이미지 파일 시스템이 표시되지만 해당 파일 시스템은 복사되지 않습니다. 이러한 이미지 레이어 위에 컨테이너는 자체 읽기 / 쓰기 파일 시스템 레이어를 마운트합니다. 파일의 모든 읽기는 파일을 삭제하도록 표시 한 레이어에 도달하거나 해당 레이어에 파일의 사본이 있거나 읽기에 레이어가 부족하여 검색 할 때까지 레이어를 통과합니다. 모든 쓰기는 컨테이너 특정 읽기 / 쓰기 레이어를 수정합니다.
레이어 팽창 감소
레이어의 한 가지 단점은 파일을 복제하거나 이후 레이어에서 삭제 된 파일을 배송하는 이미지를 만드는 것입니다. 해결책은 종종 여러 명령을 단일 RUN
명령 으로 병합하는 것 입니다. 특히 기존 파일을 수정하거나 파일을 삭제하는 경우 해당 단계가 처음 작성된 동일한 명령으로 실행되기를 원합니다. 위의 Dockerfile을 다시 작성하면 다음과 같습니다.
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 파일로 축소했습니다.