Docker 아키텍처에서 실제 실행 가능한 프로그램 코드는 어디에 있습니까?

Docker 아키텍처에서 실제 실행 가능한 프로그램 코드는 어디에 있습니까?

저는 Docker를 처음 접했기 때문에 어리석은 질문처럼 보이지만 이해할 수 없습니다. Docker 이미지에는 애플리케이션을 실행하는 데 필요한 압축 라이브러리와 종속성이 포함되어 있으며 이러한 이미지에서 컨테이너가 생성된다는 것을 배웠습니다.

그러나 내가 이해하지 못하는 것은 이미지의 압축 코드가 컨테이너 내부에서 어떻게 실행되는지입니다. 이전 연구에서 저는 컨테이너의 파일 시스템에 이 코드의 복사본이 포함되어 있고 실행될 수 있도록 이 코드에 쓰기 계층을 추가한다는 사실을 발견했습니다. 그렇기 때문에 실제로 이미지가 기반으로 하는 컨테이너의 전체 파일 시스템보다 훨씬 더 많은 저장 공간을 차지한다는 사실이 이상하다고 생각합니다. 컨테이너의 파일 시스템에 포함된 압축 해제 코드로 인해 이러한 컨테이너가 이미지보다 훨씬 클 것으로 예상할 수 있습니다.

아마도 나는 docker가 어떻게 작동하는지 완전히 오해하고 있지만 누구든지 나를 도울 수 있습니까? 미리 감사드립니다!

답변1

도커 이미지는아스팔트tar 파일이 포함된 파일입니다!

예를 들어 매우 간단한 도커 컨테이너가 있다고 가정해 보겠습니다.

% cat Dockerfile
FROM scratch
COPY hello /
CMD ["/hello"]

이를 사용하여 빌드하면 docker build -t hello .결과 이미지의 압축을 풀 수 있습니다.

% mkdir /tmp/container
% cd /tmp/container
% docker save hello | tar xvf -
1cb4c0f3e212f5abfb4b0b74d36a6ace8b7fad164b3e460d8cbf7fb1c3905270.json
59aef640ce511eadb6169072a6d8cefd95a3d1b14b73b92bd86fcb7e0b67618e/
59aef640ce511eadb6169072a6d8cefd95a3d1b14b73b92bd86fcb7e0b67618e/VERSION
59aef640ce511eadb6169072a6d8cefd95a3d1b14b73b92bd86fcb7e0b67618e/json
59aef640ce511eadb6169072a6d8cefd95a3d1b14b73b92bd86fcb7e0b67618e/layer.tar
manifest.json
tar: manifest.json: implausibly old time stamp 1970-01-01 00:00:00
repositories
tar: repositories: implausibly old time stamp 1970-01-01 00:00:00

layer파일 의 내용

% tar tf 59aef640ce511eadb6169072a6d8cefd95a3d1b14b73b92bd86fcb7e0b67618e/layer.tar
hello

COPY 명령이 여러 개인 경우 여러 레이어가 표시됩니다.

% cat Dockerfile
FROM scratch
COPY hello /
COPY lib64/ /lib64/
CMD ["/hello"]

결과:

% docker save hello-twolayers | tar xvf -
10e6ef63539659eef459b5b0795ad1d91e44b4d3d6b5cf369f026cabbef333f4/
10e6ef63539659eef459b5b0795ad1d91e44b4d3d6b5cf369f026cabbef333f4/VERSION
10e6ef63539659eef459b5b0795ad1d91e44b4d3d6b5cf369f026cabbef333f4/json
10e6ef63539659eef459b5b0795ad1d91e44b4d3d6b5cf369f026cabbef333f4/layer.tar
1f5263a466b60441b1569ae0bf6d059f6a866d721bde8c8e795313116400fb4f/
1f5263a466b60441b1569ae0bf6d059f6a866d721bde8c8e795313116400fb4f/VERSION
1f5263a466b60441b1569ae0bf6d059f6a866d721bde8c8e795313116400fb4f/json
1f5263a466b60441b1569ae0bf6d059f6a866d721bde8c8e795313116400fb4f/layer.tar
6d706ccc02fc6c6ead9b6913b8bd21f15a34abcb09b5deb8e5407af5f4203f14.json
manifest.json
tar: manifest.json: implausibly old time stamp 1970-01-01 00:00:00
repositories
tar: repositories: implausibly old time stamp 1970-01-01 00:00:00

각 COPY 명령은 새로운 "레이어"를 생성합니다.

% tar tf 10e6ef63539659eef459b5b0795ad1d91e44b4d3d6b5cf369f026cabbef333f4/layer.tar
hello

% tar tf 1f5263a466b60441b1569ae0bf6d059f6a866d721bde8c8e795313116400fb4f/layer.tar
lib64/
lib64/ld-linux-x86-64.so.2
lib64/libc.so.6

manifest파일은 레이어 순서를 설명합니다.

% jq '.[] | [ .Layers ]' < manifest.json
[
  [
    "10e6ef63539659eef459b5b0795ad1d91e44b4d3d6b5cf369f026cabbef333f4/layer.tar",
    "1f5263a466b60441b1569ae0bf6d059f6a866d721bde8c8e795313116400fb4f/layer.tar"
  ]
]

Debian 기반 컨테이너와 같은 보다 일반적인 컨테이너를 사용하는 경우:

% cat Dockerfile
FROM debian:latest
COPY hello /
CMD ["/hello"]

이제 콘텐츠를 보면 두 개의 레이어를 볼 수 있는데, 그 중 하나에는 8259개의 파일이 있습니다!

% docker save hello-debian | tar xf -
tar: manifest.json: implausibly old time stamp 1970-01-01 00:00:00
tar: repositories: implausibly old time stamp 1970-01-01 00:00:00

% for a in */layer.tar; do print -n "$a: " ; tar tf $a | wc -l ; done
7a83b1430fe3eaed26ecd9b011dcd885c6f04e45bee3205734fea8ce7382a01e/layer.tar: 1
a1ae6cd0978a7d90aea036f11679f31e1a3142b1f40030fb80d4c8748b0a6a01/layer.tar: 8259

(이 예제는 다음에서 가져온 것입니다.https://www.sweharris.org/post/2017-06-18-buildcontainer/따라서 데비안 이미지는 6년 전이지만 개념은 동일합니다.)

이제 각 레이어에는 "a1ae6cd0978a7d90aea036f11679f31e1a3142b1f40030fb80d4c8748b0a6a01"과 같은 긴 숫자가 있습니다. 이는 레이어의 sha256 해시입니다. 두 개의 서로 다른 컨테이너가 동일한 Debian 이미지를 기반으로 하는 경우 일관된 레이어를 갖게 되므로 docker 데몬은 이를 백엔드에 한 번만 저장합니다.

컨테이너가 실행되면 일반적으로 docker 데몬이피복층(읽기 전용) 이러한 레이어는 추가 디스크 공간을 사용하지 않습니다.

예를 들면 다음과 같습니다.

% grep docker /proc/mounts | head -1
overlay /var/lib/docker/overlay2/c520fff24fdac7d341e240f62e64a8301f8da9c0d44c5bb5fc62a419efdf6a67/merged overlay rw,relatime,lowerdir=/var/lib/docker/overlay2/l/QVO5L3KITI4IVHIF3CSS7A55ZP:/var/lib/docker/overlay2/l/CB5FLU2Q5C4WAHSSNNA7IA2LOB:/var/lib/docker/overlay2/l/K2DP5JPIRNFNMEREPMNX7QOHO7:/var/lib/docker/overlay2/l/APTRCOCNEYQROETHW7VZJ7AVIJ:/var/lib/docker/overlay2/l/K53M4VNLYJ3VWSMVOBS67TCUYZ:/var/lib/docker/overlay2/l/DKUICFXQR7PSTEBCBMXBFUNTIX:/var/lib/docker/overlay2/l/YQZ5RLIO5FR6W5MVDDMZNWZRRS:/var/lib/docker/overlay2/l/OPZULDPCI2FQPL4H2ENNKBUB3C:/var/lib/docker/overlay2/l/SHZQ6FNTIP3O5T2NUTHL3CR2GA:/var/lib/docker/overlay2/l/ZOAGXZVNGH2DY76LIBZUPN3NWZ,upperdir=/var/lib/docker/overlay2/c520fff24fdac7d341e240f62e64a8301f8da9c0d44c5bb5fc62a419efdf6a67/diff,workdir=/var/lib/docker/overlay2/c520fff24fdac7d341e240f62e64a8301f8da9c0d44c5bb5fc62a419efdf6a67/work 0 0

/var/lib/docker/overlay2/c520fff24fdac7d341e240f62e64a8301f8da9c0d44c5bb5fc62a419efdf6a67/merged컨테이너의 디렉토리와 이를 작동시키기 위해 함께 작동하는 모든 레이어를 볼 수 있습니다 .

관련 정보