なぜDockerコンテナーイメージが非常に大きいのですか?


177

FedoraのDockerfileを使用して単純なイメージを作成しました(最初は320 MB)。

Nano(1 MBサイズのこの小さなエディター)を追加し、画像のサイズが530 MBに増加しました。私はその上にGit(30 ish MB)を追加した後、私の画像サイズは830 MBに急増しました。

それは正気ではないですか?

コンテナーをエクスポートおよびインポートして、履歴/中間イメージを削除しようとしました。この作業で最大25 MB節約できました。現在の画像サイズは804 MBです。また、1つ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 2014年

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

レイヤーがコミットされる前に、実行ごとにそれを行うことが重要です。そうしないと、削除しても実際にはデータが削除されません。つまり、ユニオン/コピーオンライトファイルシステムでは、実際のデータがすでに下位層にコミットされているため、最後にクリーニングしてもファイルシステムの使用量は実際には減少しません。これを回避するには、各レイヤーをクリーニングする必要があります。

$ 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)。それらの古いレイヤーを削除/削除/破壊することは可能ですか?具体的には:(例に基づいて)画像を完全に削除したいと思います:172743bd5d60、3f2fed40e4b0、fd241224e9cf、511136ea3c5aの履歴から、仮想画像のサイズは最終的な画像のサイズと同じではなく、ここでは260MBです。
Zen

(1つのコメントには長すぎます)仮想イメージのサイズがHDD上のイメージの実際のサイズと関係がない場合を除きますか?この場合、画像の実際のサイズを確認する方法/場所を教えてください。
Zen

できますdocker exportし、docker importもう一度。それは層を平らにするでしょう。サイズが小さくなるとは思いませんが、間違いかもしれません。
アンディ

10
ええ、でもエクスポートしてもあまり効果はありません。それにもかかわらず、私はDockerで観察できるのは仮想画像サイズであることをWeb経由で読むことができました。公式情報に関してdocker ps -sは、私の場合はHDDの実際のサイズが表示されているため、HDDの実際のサイズは不思議に思え-1Bます。それは合理的に聞こえますが、マイナス1バイトです。HDDの容量が増えました...正当なようです。
Zen

@Zen申し訳ありません。だから仮想サイズとディスクサイズは2つの異なるものですか?仮想サイズは正確に何を測定しますか?
Jason

63

Dockerイメージは大きくはありません。大きなイメージを構築するだけです。

scratch画像は0Bであり、あなたは、静的なバイナリにあなたのコードをコンパイルすることができれば、あなたのコードをパッケージ化することを使用することができます。たとえば、Goプログラムをコンパイルしてパッケージ化しscratch、5 MB未満の完全に使用可能なイメージを作成できます。

重要なのは、公式のDockerイメージを使用しないことです。イメージが大きすぎます。スクラッチもそれほど実用的ではないので、ベースイメージとしてAlpine Linuxを使用することをお勧めします。それは約5MBで、アプリに必要なものだけを追加します。Microcontainersに関するこの投稿では、Alpineをベースにした非常に小さなイメージを構築する方法を説明します。

更新:公式のDockerイメージは現在アルパインに基づいているため、すぐに使用できます。


2
優れたソリューション!、無駄をなくし、安全性を維持することが非常に重要です--->コードが少ない->心配が少なくて済みます。
Ran Davidovitz、2016

1
ありがたいことに、Docker OfficialのイメージもAlpineベースを使用するように移行しているため、iron.ioのバージョンに依存する代わりに、通常のイメージを使用することがますます増えています。brianchristner.io/docker-is-moving-to-alpine-linux
Martijn Heemelsを

@Travis R、マイクロコンテナに関する投稿へのリンクが別の場所に移動したようです。あるこれはあなたがリンクに意味のポスト?
アレクサンダーF.

@AlexanderF。リンクを修正しました。お知らせいただきありがとうございます。
Travis Reeder 2017

28

ここでは、さらにいくつかのことを実行できます

  • RUN可能な場合は、複数のコマンドを使用しないでください。可能な限り多くのことを1つのRUNコマンドに入れる(を使用&&
  • wgetやgitなどの不要なツールをクリーンアップします(これらはダウンロードまたはビルドにのみ必要ですが、プロセスを実行するためには必要ありません)。

これらの両方と、@ Andyおよび@michauからの推奨事項を使用して、nodejsイメージのサイズを1.062 GBから542 MBに変更できました。

編集:もう1つ重要なこと: 「各Dockerfileコマンドがデルタを含む新しいコンテナーを作成することを本当に理解するのにしばらく時間がかかりました。[...]後のコマンドでファイルをrm -rfするかどうかは関係ありません。それらはいくつかの中間層コンテナに存在し続けます。」 だから今、私は入れて管理しapt-get installwgetnpm install(gitの依存関係を持つ)とapt-get remove単一にRUN今、私の画像のみ438メガバイトを持って、コマンド。

2017年6月29日編集

Docker v17.06にはDockerfilesの新機能があります。1 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

最初のステップのnodejsベースイメージと/ var / my-projectのコンテンツのみが含まれるイメージになりますが、ruby、python、git、openssh、gccは含まれません。


22

はい、それらのサイズはばかげている、そして私は本当にそれを気づく人がほとんどいないので、本当にわからない。

(他のいわゆる「最小」イメージとは異なり)実際には最小のUbuntuイメージを作成しました。呼び出さtextlab/ubuntu-essentialれて60 MBあります。

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

上記の画像は、nanoをインストールした後の82 MBです。

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

Gitにはさらに多くの前提条件があるため、イメージは大きくなり、約192 MBになります。それでも、ほとんどの画像の初期サイズよりは小さくなります。

また、Docker用の最小限のUbuntuイメージを作成するために私が作成たスクリプトを確認することもできます。おそらくFedoraに適合させることができますが、どれだけアンインストールできるかわかりません。


13

以下は私を大いに助けました:

コンテナー内の未使用のパッケージ(例:redis 1200 mb freed)を削除した後、次のことを行いました。

  1. docker export [containerID] -o containername.tar
  2. docker import -m "commit message here" containername.tar imagename:tag

レイヤーは平坦になります。上記のようにコンテナからパッケージを削除したため、新しいイメージのサイズは小さくなります。

これを理解するには長い時間がかかりました。そのため、コメントを追加しました。


両方のステップを1つのステップに組み合わせることができますdocker export <CONTAINER ID> | docker import - some-image-name:latest
Anuj Kumar

8

Dockerfile内のすべてのRUN命令がイメージ内に新しいレイヤーを書き込み、すべてのレイヤーがディスク上に追加のスペースを必要とするため、ベストプラクティスとして、単一のRUNコマンドを実行する必要があります。レイヤー数を最小限に抑えるには、インストール、移動、抽出、削除などのファイル操作を1つのRUN命令で行うのが理想的です。

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

4

Docker Squashはこれに対する本当に素晴らしいソリューションです。あなたができる$packagemanager clean最後のステップではなく、すべての行で、その後、ちょうど層の全てを取り除くためにドッカスカッシュを実行します。

https://github.com/jwilder/docker-squash


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.