自分自身を信じた小さな Docker イメージ*

[アメリカの子供向け童話「The Little Engine That Could」を参照 - 約レーン]*

自分自身を信じた小さな Docker イメージ*

ニーズに合わせて小さな Docker イメージを自動的に作成する方法

異常な執着

ここ数か月間、私は Docker イメージをどれだけ小さくしてもアプリケーションを実行できるかということに夢中になってきました。

わかります、その考えは奇妙です。

詳細や技術的な内容に入る前に、この問題がなぜ私をそれほど悩ませているのか、そしてそれがどのようにあなたに関係しているのかを説明したいと思います。

サイズが重要な理由

Docker イメージの内容を減らすことで、脆弱性のリストが減ります。 さらに、イメージにはアプリケーションの実行に必要なものだけが含まれるため、イメージがよりクリーンになります。

もう XNUMX つ小さな利点があります。画像のダウンロードが少し速くなりますが、私の意見では、これはそれほど重要ではありません。

注意: サイズが気になる場合は、アルパインのルックス自体が小さいため、フィットする可能性があります。

ディストロレス画像

プロジェクト・ディストロレス では、基本的な「ディストロレス」イメージのセレクションが提供されていますが、これらには、コマンド ラインで見慣れているパッケージ マネージャー、シェル、その他のユーティリティは含まれていません。 その結果、次のようなパッケージ マネージャーを使用します。 pip и apt 動作しないでしょう:

FROM gcr.io/distroless/python3
RUN  pip3 install numpy

Python 3 distroless イメージを使用した Dockerfile

Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
 ---> 556d570d5c53
Step 2/2 : RUN  pip3 install numpy
 ---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found

ピップは画像にありません

通常、この問題は複数段階のビルドによって解決されます。

FROM python:3 as builder
RUN  pip3 install numpy

FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/

多段階組み立て

結果として、サイズが 130MB のイメージが作成されます。 悪くない! 比較のために: デフォルトの Python イメージの重さは 929MB で、「より薄い」イメージ (3,7-slim) - 179MB、高山イメージ (3,7-alpine) は 98,6MB ですが、この例で使用されているベースの distroless イメージは 50,9MB です。

前の例ではディレクトリ全体をコピーしていることを指摘するのは当然です。 /usr/local/lib/python3.7/site-packages必要のない依存関係が含まれている可能性があります。 ただし、既存のすべての Python ベース イメージのサイズの違いが異なることは明らかです。

この記事の執筆時点では、Google distroless は多くのイメージをサポートしていません。Java と Python はまだ実験段階にあり、Python は 2,7 と 3,5 に対してのみ存在します。

小さな画像

小さな画像を作成することへの私の執着に戻ります。

一般に、私は distroless イメージがどのように構築されるかを知りたかったのです。 distroless プロジェクトは Google のビルド ツールを使用します bazel。 ただし、Bazel をインストールして独自のイメージを作成するには、多くの作業が必要でした (そして正直に言うと、車輪の再発明は楽しくて勉強になります)。 小さな画像の作成を簡素化したいと考えました。画像を作成する行為は非常に単純である必要があります。 平凡な。 そのため、設定ファイルは必要なく、コンソールには次の XNUMX 行だけが表示されます。 просто собрать образ для <приложение>.

したがって、独自のイメージを作成したい場合は、このような独自の Docker イメージがあることを知っておいてください。 scratch。 Scratch は「空の」イメージで、中にはファイルがありませんが、デフォルトで重さはあります - すごい! - 77バイト。

FROM scratch

スクラッチ画像

スクラッチ イメージの考え方は、依存関係をホスト マシンからそのイメージにコピーし、それらを Dockerfile 内で使用できるということです (これは、依存関係を Dockerfile にコピーするようなものです) apt 最初からインストールする)、または後で Docker イメージが具体化されるときに実行します。 これにより、Docker コンテナの内容を完全に制御できるため、イメージのサイズも完全に制御できます。

次に、これらの依存関係を何らかの方法で収集する必要があります。 などの既存のツール apt パッケージをダウンロードできますが、それらは現在のマシンに関連付けられており、結局のところ Windows や MacOS をサポートしません。

そこで私は、可能な限り小さいサイズの基本イメージを自動的に構築し、任意のアプリケーションを実行できる独自のツールを構築することにしました。 私は Ubuntu/Debian パッケージを使用し、選択を行い (リポジトリからパッケージを直接取得)、それらの依存関係を再帰的に見つけました。 このプログラムは、セキュリティ リスクを可能な限り最小限に抑えるために、パッケージの最新の安定バージョンを自動的にダウンロードすることになっていました。

ツールに名前を付けました fetchy、なぜなら彼は... 必要なものを見つけて持ってくるからです [英語から「取ってくる」、「持ってくる」 - 約。 レーン]。 このツールはコマンド ライン インターフェイスを通じて動作しますが、同時に API も提供します。

を使用してイメージを組み立てるには fetchy (今回は Python イメージを取得しましょう)、次のように CLI を使用するだけです。 fetchy dockerize python。 ターゲットのオペレーティング システムとコード名を尋ねられる場合があります。 fetchy 現在、Debian と Ubuntu に基づくパッケージのみを使用しています。

これで、(このコンテキストでは) まったく必要のない依存関係を選択し、それらを除外できるようになりました。 たとえば、Python は Perl に依存していますが、Perl がインストールされていなくても正常に動作します。

結果

コマンドを使用して作成された Python イメージ fetchy dockerize python3.5 重さはわずか 35MB です (将来的にはさらに軽量化できると確信しています)。 ディストリビューションのないイメージからさらに 15 WW を削り取ることができたことがわかりました。

これまでに集めた画像をすべて見ることができます ここで.

プロジェクト - ここで.

不足している機能がある場合は、リクエストを作成してください - 喜んでお手伝いします :) さらに、私は現在、他のパッケージ マネージャーを fetchy に統合することに取り組んでいます。これにより、複数段階のビルドが必要なくなります。

出所: habr.com

コメントを追加します