Docker 컨테이너 이미지가 왜 그렇게 큰가요?


177

Fedora의 Dockerfile (초기 320MB)을 통해 간단한 이미지를 만들었습니다.

Nano (1MB 크기의이 작은 편집기)가 추가되었으며 이미지 크기가 530MB로 증가했습니다. Git을 30MB 이상으로 추가 한 다음 이미지 크기가 830MB로 급상승했습니다.

미쳤어?

기록 / 중간 이미지를 제거하기 위해 컨테이너를 내보내고 가져 오려고했습니다. 이 노력은 최대 25MB를 절약했으며 이제 이미지 크기는 804MB입니다. 또한 하나 RUN에서 많은 명령을 실행하려고 했지만 여전히 동일한 초기 830MB를 얻습니다.

Docker를 전혀 사용할 가치가 있는지 의심 스럽습니다. 나는 거의 아무것도 설치하지 않았고 1GB를 초과했습니다. 데이터베이스와 같은 심각한 것들을 추가해야 할 경우 디스크 공간이 부족할 수 있습니다.

어리석은 크기의 이미지로 고통받는 사람이 있습니까? 어떻게 처리합니까?

내 Dockerfile이 끔찍하게 잘못되지 않는 한?

FROM fedora:latest
MAINTAINER Me NotYou <email@dot.com>
RUN yum -y install nano
RUN yum -y install git

그러나 여기서 무엇이 잘못 될 수 있는지 상상하기는 어렵습니다.


컨테이너의 크기와 위치를 어떻게 측정합니까? yum clean all크기에 영향을 미칩니 까 ?
xeor

2
이미지는 이미지, 부모 이미지 및 기본 이미지의 누적이므로 적절한 크기가 될 것으로 예상하십시오. 또한 yum은 해당 앱뿐만 아니라 해당 종속성도 설치합니다. docs.docker.com/terms/container
rexposadas

2
글쎄, 나의 "측정"은 docker images마지막 열에서 830MB가 넘는 실행 입니다. docker images 명령 에이 830MB가 가상 크기라고 표시되어 있기 때문에 실제로 이미지의 실제 크기가 무엇인지 알지 못할 수 있습니다. 그러나 다시, 실제 이미지 크기는 얼마입니까?
Zen

답변:


118

@rexposadas가 말했듯이 이미지에는 모든 레이어가 포함되고 각 레이어에는 설치 한 항목에 대한 모든 종속성이 포함됩니다. 또한 기본 이미지 (예 : fedora:latest매우 베어 본인 경향이 있음)에 유의해야합니다 . 설치된 소프트웨어의 종속성 수에 놀라실 수 있습니다.

yum -y clean all각 줄 에 추가하여 설치를 크게 줄일 수있었습니다 .

FROM fedora:latest
RUN yum -y install nano && yum -y clean all
RUN yum -y install git && yum -y clean all

계층이 커밋되기 전에 각 RUN에 대해 수행해야합니다. 그렇지 않으면 삭제시 실제로 데이터가 제거되지 않습니다. 즉, UNION / Write-Write 파일 시스템에서 실제 데이터가 이미 하위 계층에 커밋되어 있기 때문에 결국 정리해도 파일 시스템 사용이 실제로 줄어들지는 않습니다. 이 문제를 해결하려면 각 층을 청소해야합니다.

$ docker history bf5260c6651d
IMAGE               CREATED             CREATED BY                                      SIZE
bf5260c6651d        4 days ago          /bin/sh -c yum -y install git; yum -y clean a   260.7 MB
172743bd5d60        4 days ago          /bin/sh -c yum -y install nano; yum -y clean    12.39 MB
3f2fed40e4b0        2 weeks ago         /bin/sh -c #(nop) ADD file:cee1a4fcfcd00d18da   372.7 MB
fd241224e9cf        2 weeks ago         /bin/sh -c #(nop) MAINTAINER Lokesh Mandvekar   0 B
511136ea3c5a        12 months ago                                                       0 B

1
사례를 조사해 주셔서 감사합니다. 예, 이미지 크기를 약 635MB로 줄일 수있었습니다 (이 실행 후 가상 이미지 크기로 docker images표시됨). 오래된 레이어를 제거 / 삭제 / 파기 할 수 있습니까? 더 구체적으로 말하면 : (예제에 따라) 이미지를 완전히 제거하고 싶습니다. .
Zen

(1 개의 댓글이 너무 깁니다.) 가상 이미지 크기가 HDD의 실제 이미지 크기와 관련이 없다면? 이 경우 이미지의 실제 크기를 확인하는 방법 / 장소는 무엇입니까?
Zen

당신은 할 수 docker exportdocker import다시. 그것은 층을 평평하게 할 것입니다. 크기가 줄어들 것이라고 생각하지 않지만 잘못 될 수 있습니다.
Andy

10
네,하지만 수출은 크게 절약되지 않습니다. 그럼에도 불구하고 도커에서 관찰 할 수있는 것은 가상 이미지 크기라는 것을 웹을 통해 읽을 수있었습니다. HDD의 실제 크기는 공식 정보와 관련하여 docker ps -sHDD의 실제 크기를 보여 주기 때문에 미스터리 한 것 같습니다 -1B. 그것은 1 Byte 빼기 합리적으로 들립니다 . HDD에서 약간의 공간을 확보했습니다 ... 합법적 인 것 같습니다.
Zen

@Zen 죄송합니다. 다음에 오지 않습니다. 가상 크기와 디스크 크기가 서로 다른 두 가지입니까? 가상 크기는 정확히 무엇을 측정합니까?
Jason

63

도커 이미지는 크지 않고 단지 큰 이미지를 작성하고 있습니다.

scratch이미지가 0B이고 정적 바이너리로 코드를 컴파일 할 수 있다면 당신은 당신의 코드를 패키지로 그것을 사용할 수 있습니다. 예를 들어 Go 프로그램을 컴파일 하고 맨 위에 패키지하여scratch 5MB 미만의 완전히 사용 가능한 이미지를 만들 수 있습니다.

열쇠는 공식 Docker 이미지를 사용하지 않는 것입니다. 이미지가 너무 큽니다. 스크래치는 그다지 실용적이지 않으므로 Alpine Linux를 기본 이미지로 사용하는 것이 좋습니다. ~ 5MB이며 앱에 필요한 것만 추가하십시오. 마이크로 컨테이너 에 대한이 게시물 에서는 알파인을 기반으로 매우 작은 이미지를 만드는 방법을 보여줍니다.

업데이트 : 공식 Docker 이미지는 알파인을 기반으로하므로 지금 사용하는 것이 좋습니다.


2
훌륭한 솔루션!, 낭비를 막고 더 안전하게 유지하는 것이 중요합니다.
란 다비도 비츠

1
고맙게도 Docker Official 이미지도 알파인베이스를 사용하도록 움직이고 있으므로 iron.io 버전에 따라 대신 일반 이미지를 사용할 수 있습니다. brianchristner.io/docker-is-moving-to-alpine-linux
Martijn Heemels

@Travis R, 마이크로 컨테이너 관련 게시물 링크가 다른 곳으로 이동 한 것 같습니다. 인가 이것은 당신이 링크에 의미 포스트?
Alexander F.

@AlexanderF. 알려 주셔서 감사합니다.
Travis Reeder

28

할 수있는 일이 더 있습니다 :

  • 가능한 여러 RUN명령을 피하십시오 . 하나의 RUN명령 에 가능한 한 많이 넣습니다 (을 사용하여 &&)
  • wget 또는 git과 같은 불필요한 도구 정리 (다운로드 또는 빌드에만 필요하지만 프로세스는 실행하지 않아야 함)

@Andy 및 @michau의 AND와 권장 사항을 모두 사용하여 nodejs 이미지의 크기를 1.062GB에서 542MB로 조정할 수있었습니다.

편집 : 한 가지 더 중요한 점 : "각 Dockerfile 명령이 델타를 사용하여 새 컨테이너를 작성한다는 사실을 이해하는 데 시간이 조금 걸렸습니다. [...] 이후 명령에서 파일을 rm rf로 작성해도 문제가되지 않습니다. "일부 중간 레이어 컨테이너에 계속 존재합니다." 그래서 지금은 넣어 관리 apt-get install, wget, npm install(자식 종속성)와 apt-get remove단일로 RUN이제 내 이미지는 438메가바이트을 가지고, 명령.

29/06/17 수정

Docker v17.06에는 Dockerfile에 대한 새로운 기능이 있습니다. FROM하나의 Dockerfile 내에 여러 명령문을 사용할 수 있으며 마지막 내용 만 FROM최종 Docker 이미지에 있습니다. 이미지 크기를 줄이는 데 유용합니다. 예를 들면 다음과 같습니다.

FROM nodejs as builder
WORKDIR /var/my-project
RUN apt-get install ruby python git openssh gcc && \
    git clone my-project . && \
    npm install

FROM nodejs
COPY --from=builder /var/my-project /var/my-project

이미지가 가진 발생합니다 것은 단지는 기본 이미지와 첫 단계에서의 / var / 내 프로젝트에서 콘텐츠를 nodejs -하지만 하지 않고 루비, 파이썬, 자식, OpenSSH의 및 GCC!


22

예, 그 크기는 말도 안되며, 왜 그렇게 적은 사람들이 그 사실을 알지 못합니다.

다른 "최소"이미지와 달리 실제로는 최소 인 Ubuntu 이미지를 만들었습니다. 호출 textlab/ubuntu-essential되며 60MB가 있습니다.

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano

위 이미지는 nano를 설치 한 후 82MB입니다.

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano git

Git에는 더 많은 전제 조건이 있으므로 이미지가 약 192MB 커집니다. 그것은 여전히 ​​대부분의 이미지의 초기 크기보다 적습니다.

Docker 용 최소 우분투 이미지를 만들기 위해 작성한 스크립트를 살펴볼 수도 있습니다 . Fedora에 적용 할 수 있지만 얼마나 제거 할 수 있는지 잘 모르겠습니다.


13

다음은 많은 도움이되었습니다.

컨테이너 내부에서 사용하지 않는 패키지 (예 : redis 1200 mb freed)를 제거한 후 다음을 수행했습니다.

  1. 도커 내보내기 [containerID] -o containername.tar
  2. docker import -m "커밋 메시지"containername.tar imagename : tag

층이 평평 해집니다. 위에서 설명한 것처럼 컨테이너에서 패키지를 제거했기 때문에 새 이미지의 크기가 더 작아집니다.

이것은 이것을 이해하는 데 많은 시간이 걸렸으므로 이것이 내 의견을 추가 한 이유입니다.


두 단계를 하나의 단계로 결합 할 수 있습니다docker export <CONTAINER ID> | docker import - some-image-name:latest
Anuj Kumar

8

Dockerfile의 모든 RUN 명령어는 이미지에 새 레이어를 작성하고 모든 레이어에는 디스크에 추가 공간이 필요하므로 최상의 연습을 위해서는 단일 RUN 명령을 실행해야합니다. 숫자 레이어를 최소로 유지하려면 단일 RUN 명령으로 설치, 이동, 추출, 제거 등과 같은 파일 조작이 이상적이어야합니다.

FROM fedora:latest
RUN yum -y install nano git && yum -y clean all


0

예, 레이어 시스템은 매우 놀랍습니다. 기본 이미지가 있고 다음을 수행하여 증가시키는 경우 :

# Test
#
# VERSION       1

# use the centos base image provided by dotCloud
FROM centos7/wildfly
MAINTAINER JohnDo 

# Build it with: docker build -t "centos7/test" test/

# Change user into root
USER root

# Extract weblogic
RUN rm -rf /tmp/* \
    && rm -rf /wildfly/* 

이미지의 크기는 정확히 같습니다. 즉, 소프트웨어를 설치했을 때 이미지를 작게 만들려면 많은 추출, 설치 및 정리 마법을 실행 단계에 포함시켜야합니다.

이것은 인생을 훨씬 어렵게 만듭니다 ...

dockerBuild에 커밋없이 RUN 단계가 누락되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.