documentation は、このトピックについて詳しく説明していません。それは言います:
レイヤーの数を最小限に抑える
Docker 17.05より前、さらにDocker 1.10より前では、画像のレイヤー数を最小限に抑えることが重要でした。以下の改善により、この必要性が緩和されました。
Docker 1.10以降では、RUN、COPY、およびADD命令のみがレイヤーを作成します。他の命令は一時的な中間イメージを作成し、ビルドのサイズを直接増加させなくなりました。
Docker 17.05以降では、マルチステージビルドのサポートが追加され、必要なアーティファクトのみを最終的なイメージにコピーできます。これにより、最終イメージのサイズを増やすことなく、ツールとデバッグ情報を中間ビルドステージに含めることができます。
最新のDockerバージョンでは、多くのレイヤーを処理する問題を解決できないようです。彼らはむしろ最終的な画像の数を減らすよう努めています。最も重要なことは、ドキュメントは多くのレイヤーが悪いということをwhyとは言わないことです。
42層の AUFS制限 を知っています。広く使用されている画像の場合、レイヤーの上に構築された他の画像が制限に適合するので、レイヤーの数を少なくすることは理にかなっています。ただし、他の目的のために別のストレージドライバーとイメージがあります。
また、明らかな理由で画像を小さく保つことは良いことです-ディスク領域とネットワーク帯域幅を占有します。ただし、 連鎖RUNステートメント とは思わないため、多くのレイヤーを1つに押しつぶすことは一般に役立ちます。異なるRUNがファイルシステムの異なる部分を更新する場合、1つのレイヤーと多くのレイヤーを合わせてほぼ同じサイズにする必要があります。
一方、多くのレイヤーでは、キャッシュを使用してイメージを再構築することができます。それらも並行してプルされます。
私は、プライベートDockerレジストリを使用して小さなチームで働いています。 42層の制限に対応することはなく、パフォーマンスと開発速度を重視します。
その場合、ドッカーレイヤーの数を最小限に抑える必要がありますか?
私は、プライベートDockerレジストリを使用して小さなチームで働いています。 42層の制限に対応することはなく、パフォーマンスと開発速度を重視します。
その場合、ドッカーレイヤーの数を最小限に抑える必要がありますか?
あなたの場合、いいえ。
最小化する必要があるのはビルド時間です。つまり、次のことを意味します。
つまり、 あなたが言及したドキュメント は docker/docker.github.io
、正確に PR 4992 および PR 4854 、 docker build LABEL
セクション 。
したがって、このセクションはLABEL
についての同様の発言の後にあり、レイヤーを作成するコマンドを強調しています。
再び、あなたの場合、それは重要ではないでしょう。
複数のRUNで作成されたイメージと、1つのRUN連結コマンドで作成されたイメージの2つのイメージの違いを確認したかっただけです。
最初のケースでは、画像は些細な操作(ファイルの作成と削除)を行っています。
「シングル」レイヤー画像のコンテンツ:
FROM busybox
RUN echo This is the 1 > 1 \
&& rm -f 1 \
&& echo This is the 2 > 2 \
&& rm -f 2 \
# ... for about 70 commands
複数レイヤーの画像のコンテンツ:
FROM busybox
RUN echo This is the 1 > 1
RUN rm -f 1
RUN echo This is the 2 > 2
RUN rm -f 2
# ... for about 70 layers
ビルド時間は大きく異なります(複数:0m34,973s、単数:0m0,568s)。コンテナの起動時間も異なりますが、目立ちません(複数:0m0,435s、単数:0m0,378s)。画像を異なる時間で実行しましたが、時間はそれほど変わりません。
スペースに関しては、マルチレイヤーの場合の最悪のケースを意図的に調べましたが、予想どおり、マルチレイヤーイメージはシングルレイヤーよりも大きくなっています。
別のテストでは、画像にコンテンツのみを追加するレイヤーを連結しました。ビルド時間は前の場合と変わりませんが、実行時の場合は少し異なります。マルチレイヤーイメージは、シングルレイヤーイメージよりも起動が高速です。スペースに関しては、同じ結果です。
私はこれが何かを証明するとは思わないが、私はそれをやって楽しんでいた:P
レイヤーの数を減らすことは、目標そのものではありません。むしろ、集中する必要があるのは、ビルド時間を短縮し、イメージサイズを縮小することです。
Dockerfileの最上部またはベースイメージ内でほとんど変更されない一般的なレイヤーを保持することにより、ビルド時間を短縮します。これにより、レイヤーをキャッシュし、後のビルドで再利用できます。これは、レイヤーの数を減らすことではなく、レイヤーを適切に順序付けることです。
イメージサイズを小さくすると、レジストリシステムでのディスク使用量を減らすのに役立ちます。レジストリサーバーでは、CIシステムのビルドごとにイメージが保存されるときにディスクに大きなヒットが発生します。また、イメージを転送するためのネットワーク時間も短縮されます。大きな一時ファイルをダウンロードする1つのレイヤーがあり、それを別のレイヤーで削除すると、ファイルが最初のレイヤーに残され、ネットワーク経由で送信されてディスクに保存されます。コンテナ。ファイルのアクセス許可を変更すると、ファイルが新しいアクセス許可で現在のレイヤーにコピーされ、そのファイルのディスク容量とネットワーク帯域幅が倍になります。
上記のシナリオで画像サイズを縮小する標準的なソリューションは、RUN
コマンドを連鎖させて、一時ファイルが画像レイヤーに保存されないようにすることです。これには、画像レイヤーの数を減らすという副作用があります。
最後の問題が1つあります。それは過剰なキャッシュです。これは、Debianイメージのapt-get update
およびapt-get install ...
コマンドでよく見られます。これらのコマンドを連結しない場合、apt-get install
コマンドの更新により、以前のレイヤーapt-get update
コマンドの古いキャッシュが再利用され、数か月後に必要なパッケージが見つからない場合に失敗します。したがって、ビルド時間が長くなる場合でも、これらのコマンドをチェーンする必要があります。他のオプションは、将来ビルドが失敗するためです。
したがって、必要なのはレイヤーを減らすことの副作用であり、レイヤーを減らすために必ずしもレイヤーを減らすわけではありません。