Dockerイメージサイズを最適化する一般的な方法

Dockerイメージサイズを最適化する一般的な方法

通常、私たちが構築する Docker イメージはサイズが大きく、多くのディスク領域を占有します。コンテナを大規模に展開すると、貴重な帯域幅リソースも浪費されます。この記事では、Docker イメージのサイズを最適化するための一般的な方法をいくつか紹介します。ここでは、公式 Docker Hub の Redis イメージを例として使用します。

手動管理

直接的に考えられる方法は、公式の Redis イメージの Dockerfile ファイルを直接変更し、コンテナの実行後に不要なコンポーネントを手動で削除して、新しいイメージを再構築することです。この方法は理論的には実行可能ですが、エラーが発生しやすく、効果も特に明らかではありません。主な問題は、公式ミラーとリアルタイムで同期できないことです。

多段階ビルド

この問題を解決するために、Docker はバージョン 17.05 以降、マルチステージ ビルド機能を提供しています。このアプローチは、中間層を破棄し、中間層を使用して最終イメージとそのコンテンツの作成方法に関する情報を提供することで実現されます。コンテナ化されたアプリケーションに必要なコンポーネントのみを保持する必要があります。より高いレベルでの実装は次のとおりです。

  • いくつかの画像を基に構築する
  • 通常通りコマンドを実行してアプリケーションをビルドします
  • 必要なアーティファクトを別のイメージにコピーする

ディストロレス

Google はコンテナ化技術、特に Docker に大きく依存してきたため、肥大化したイメージを使用することの欠点を長い間認識してきました。そこで彼らは、この問題に対する独自の解決策、つまり distroless イメージを提供しました。一般的な Linux ベース イメージ (多くのソフトウェアがバンドルされている) とは異なり、distroless でアプリケーションを Docker 化すると、最終イメージにはアプリケーションとそのランタイム依存関係のみが含まれます。パッケージ マネージャーやシェルなど、ほとんどの Linux ディストリビューションに含まれている標準ソフトウェアは除外されます。同様に、Google の distroless イメージを使用するには、次のように、前述のマルチステージ ビルドを使用する必要があります。

redis:latest ASビルドから 
引数タイムゾーン 
mkdir -p /opt/etc && \ を実行します。 
 cp -a --parents /lib/x86_64-linux-gnu/libm.so.* /opt && \ 
 cp -a --parents /lib/x86_64-linux-gnu/libdl.so.* /opt && \ 
 cp -a --parents /lib/x86_64-linux-gnu/libpthread.so.* /opt && \ 
 cp -a --parents /lib/x86_64-linux-gnu/libc.so.* /opt && \ 
 cp -a --parents /usr/local/bin/redis-server /opt && \ 
 cp -a --parents /usr/local/bin/redis-sentinel /opt && \ 
 cp /usr/share/zoneinfo/${TIME_ZONE:-UTC} /opt/etc/localtime 
 
gcr.io/distroless/base より 
コピー --from=build /opt / 
ボリューム/データ 
ワークディレクトリ /データ 
エントリポイント ["redis-server"]

redis:latest をベース イメージとして使用し、必要なバイナリ (redis-server バイナリと関連するすべての依存関係) を保持し、distroless イメージをビルドする最終イメージのベースとして使用します。opt ディレクトリの内容をイメージ ディレクトリにコピーします。

次に、イメージを再構築するだけです。

$ docker build -t redis:distroless .$ docker imagesリポジトリタグイメージID作成サイズredis distroless 7d50bd873bea 15秒前 28.2MBredis latest 1319b1eaa0b7 3日前 104MB

画像サイズが 104 MB から 28.2 MB に削減され、大幅に削減されたことがわかります。

注: Linux では、 $ ldd $(which redis-server) などの ldd ツールを使用して、指定されたバイナリ ファイルに必要な依存関係を見つけることができます。

ディストロレス イメージを使用して Docker イメージのサイズを縮小することは非常に効果的な方法ですが、明らかな欠点もあります。最終イメージにはシェル プログラムがないため、Docker コンテナーのデバッグが非常に困難になります。もちろん、これによりアプリケーション攻撃のリスクも軽減され、セキュリティも向上します。アプリケーションを Kubernetes クラスターにデプロイする場合、kubectl-debug などのツールを使用してアプリケーションのデバッグを支援できます。

アルパイン・リナックス

もう 1 つの一般的な方法は、最小限の Docker イメージを作成するのに特に適したディストリビューションである Alpine Linux に基づいてアプリケーション イメージを構築することを選択することです。 Apline Linux は、glibc の代わりに小さい musl C ライブラリを使用し、それを静的にリンクします。つまり、musl 用にコンパイルされたプログラムは再配置可能なバイナリになり、共有オブジェクトを含める必要がなくなり、イメージのサイズを大幅に削減できます。

redis:alpine イメージは約 30MB です。欠点は、musl は通常 glibc ほどパフォーマンスが良くないことです。もちろん、もう 1 つ利点があります。上記の distroless と比較すると、Alpine は基本的なシェル アクセスを提供する成熟した Linux ディストリビューションであり、Docker コンテナー アプリケーションのデバッグが容易になります。また、Redis、Nginx、MySQL など、ほぼすべての一般的なソフトウェアの Alpine バージョンも Docker Hub で見つけることができます。

GNU ギックス

最後に、Docker イメージを作成する機能を備えた多目的パッケージ管理ツールである GNU Guix を使用します。 Guix はパッケージのランタイム依存関係とビルド依存関係を区別するため、Guix でビルドされた Docker イメージには、distroless アプローチと同様に、明示的に指定されたプログラムとそのランタイム依存関係のみが含まれます。しかし、プログラムの実行時依存関係を自分で確認する必要がある (そしてもちろん Dockerfile を作成する) distroless とは異なり、Guix では、 $ guix pack -f docker redis という 1 つのコマンドを実行するだけで済みます。

上記のコマンドで作成された Redis イメージのサイズは約 70 MB で、元のイメージと比較すると大幅に削減されています。distroless および Alpine 方式で作成されたイメージよりもわずかに大きいですが、Guinx を使用すると他の利点もいくつかあります。たとえば、最終イメージに Alpine のようなデバッグ用のシェルを含める場合は、Guxi をパッケージ化するときにのみ指定する必要があります: $ guix pack -f docker redis bash 。他のソフトウェアを含める場合は、後から追加し続けることができます。

Guix の機能により、パッケージ ビルドは 100% 再利用可能であるため、CI/CD パイプラインに Guix サポートを追加して、ビルド プロセスを非常にスムーズにすることができます。

Guix はかっこいいと思う人もいるかもしれませんが、小さな Docker イメージを作成するためだけに別のツールをダウンロードしてインストールしたくないと思う人もいるでしょう。さらに、Guix は Linux でしか動作しません。多くの開発者は依然として MacOS ユーザーであるため、Guix の設定は面倒です。実は、これについては心配する必要はありません。Guix 自体も Docker Hub に Docker イメージがあるので、使い方はそれほど複雑ではありません。シンプルな $ docker run guix コマンドを使用するだけで済みます。

Guix に加えて、Nix と呼ばれるパッケージ管理ツールがあることに言及する価値があります。Guix について言及されているすべてのことは、Nix にも同様に有効であり、適用できます。

上記は、Docker イメージのサイズを最適化する一般的な方法の詳細です。Docker イメージのサイズの最適化の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Docker マルチステージビルドを使用してイメージサイズを縮小する方法
  • Dockerイメージのサイズを縮小する6つの方法

<<:  テキストの展開と折りたたみの効果を実現するJavaScript

>>:  React プロジェクトで eslint の Baidu スタイルを使用する詳細な説明

推薦する

MySQL テーブル結合クエリでグループ化と重複排除を実装する例

目次ビジネスロジックデータテーブル構造クエリロジックSQL スクリプトスクリプトの説明ビジネスロジッ...

CSS3で作成した画像スクロール効果

成果を達成する実装コードhtml <base href="https://s3-us...

Linux で Oracle データベースをバックアップするためのスケジュールされたタスクの設定に関するチュートリアル

1. データベースの文字セットを確認するデータベースの文字セットは、Linux で設定された環境変数...

winx64 での mysql5.7.19 の基本的なインストール プロセス (詳細)

1. ダウンロード参考: https://www.jb51.net/softs/451120.ht...

Linux でマウントされたファイルシステムの種類を表示する方法

序文ご存知のとおり、Linux は ext4、ext3、ext2、sysfs、securityfs、...

入力ボックスのカーソルサイズの表示が一貫していない問題の解決方法

入力ボックス内のカーソルのサイズが一定ではありませんIE7とChromeの違いは非常に明白ですまず、...

Dockerの国内イメージソースを変更する方法

Dockerデーモンのアクセラレータを構成する設定ファイルから Docker を起動し、/etc/d...

フロントエンドとバックエンド分離プロジェクトのDockerデプロイメントの実装例

目次1. 環境整備2. イメージを実行する問題を解決するRedis のインストールNginx のイン...

ナビゲーションデザインと情報アーキテクチャ

<br />ナビゲーションについて話すときは、ほとんどの場合、ナビゲーションがコンテンツ...

Web 開発チュートリアル クロスドメイン ソリューションの詳細な説明

序文この記事では、主にWeb開発のためのクロスドメインソリューションを紹介し、参考と学習のために共有...

MySQLの7種類のログの概要

MySQL には次のログ ファイルがあります。 1: 再実行ログ2: ロールバックログ(元に戻すログ...

VUE でタブページを切り替える 4 つの方法

目次1. 静的実装方法: 2. 第2のシミュレーション動的方法3. 3番目の動的データ方式4. 動的...

ネイティブJavaScriptカルーセル実装方法

この記事では、JavaScriptカルーセルの実装方法を参考までに紹介します。具体的な内容は次のとお...

スライダーを作成するためのネイティブ js ドラッグ アンド ドロップ機能のサンプル コード

ドラッグ アンド ドロップはフロントエンドでよく使われる機能であり、多くのエフェクトで js のドラ...

Reactの簡単な紹介

目次1. CDNの紹介1.1 react (最初にインポート) 1.2 react-dom(後ほど紹...