Docker マルチステージビルドを使用してイメージサイズを縮小する方法

Docker マルチステージビルドを使用してイメージサイズを縮小する方法

この記事では、Docker のマルチステージ ビルド機能を使用してイメージ サイズを大幅に削減する方法について説明します。これは、Dockerfile でプログラム (javac など) をビルドする必要があり、コンパイル ツール チェーンのインストールが必要なイメージに適しています。 (Javaなど)

まずは単語を覚えましょう(この記事では中国語の語彙を使用しています。外国の文書を調べる必要がある場合は、この語彙リストを参照してください。理論的には、私は個人的に用語を翻訳することに賛成しません)。

  • 多段階
  • 建てる
  • 画像
  • ステージ

効果を見てみましょう。当初は 1 億 1,000 万以上でしたが、現在は 9,200 万です。

Dockerfileを比較する

最適化前の Dockerfile:

openjdk:8u171-jdk-alpine3.8 から

./app を追加する
ワークディレクトリ /app

apk add maven を実行 \
  && mvn クリーンパッケージ \
  && Maven の apk \
  && mv target/final.jar / \
  && CD / \
  && rm -rf /app \
  && rm -rf /root/.m2

エントリポイント java -jar /final.jar

最適化された Dockerfile:

openjdk:8u171-jdk-alpine3.8 からビルダーとして

./app を追加する
ワークディレクトリ /app

apk add maven を実行 \
  && mvn クリーンパッケージ \
  && Maven の apk \
  && mv ターゲット/final.jar /

環境としてopenjdk:8u181-jre-alpine3.8から
ワークディレクトリ /
--from=builder /final.jar にコピーします。
エントリポイント java -jar /final.jar

明らかに、最適化された Dockerfile には FROM AS コマンドが追加され、2 つの FROM が表示されます。これは多段階のビルドです。

マルチステージビルドについて学ぶ

マルチステージ ビルドは Docker 17.05 の新機能であり、Dockerfile 内で複数の FROM ステートメントを使用して複数のステージを作成できます。各ステージは独立しており (ソース要求)、他のステージのファイルは COPY --from を通じて取得できます。最終的なイメージを料理(ピーマンのフライ)に例えてみましょう。生のピーマンを揚げたら出来上がりです。

# 比較リストミラー -> 料理第一段階 -> 炒め物第二段階 -> 盛り付ける

2 つのステージの目標は、最終的な料理 (画像) を作成 (生成) することです。私たちがすべきことは、最初の段階で「揚げた」食べ物を提供することです。私たちの目標は、できるだけ軽い皿(盛り付け用および中間製品)で料理を作ることです。

視覚化プロセスは次のとおりです。

# 調理プロセス...材料を省略-> [第一段階-炒める] # この時、皿の上には炒め物、炒め物、中間製品があります # この時、第二段階を開始し、炒め物だけを残し、他のものは必要ありません。
-> 炒めた結果-> [盛り付け開始、結果のみ保存] # 炒めたピーマン(COPY --from)を取り、他は取らない-> 完成した料理は一品です。

これで、マルチステージ ビルド プロセスの概要を理解できたはずです。マイクを Java に渡して、Dockerfile のコンパイル ツールを使用して JAR をビルドし、ビルドされた JAR とランタイムのみを保持して Image に渡し、残りを破棄する方法を見てみましょう。

# フェーズ 1 - コンパイル (フライ)
FROM openjdk:8u171-jdk-alpine3.8 as builder # 組み込みコンパイルツール ADD ./app
ワークディレクトリ /app

実行...コンパイルとクリーンアップをスキップ...

# これで、JAR がリリースされました。 JDK は不要になったため、イメージ内に残すことはできません。
# そこで、第2段階(デスクトップ上で実行)を開始し、第1段階のすべてのファイル(コンパイルツールを含む)を破棄します。
FROM openjdk:8u181-jre-alpine3.8 as environment # ランタイムのみ# 現時点では、前段階のコンパイル ツールなどは放棄されています。現在のイメージでは、実行時にのみ、前の段階 (揚げる) の結果を取得する必要があり、他の段階は必要ありません。
--from=0 /final.jar をコピーします。

# これで、イメージには必要なランタイムと JAR のみが含まれるようになりました。
エントリポイント java -jar /final.jar

以上が多段階施工の紹介です。

マルチステージビルドの使用

マルチステージビルドのコアコマンドは FROM です。多くの戦いを経験してきたあなたにとって、FORM についてはあまり説明する必要はありません。マルチステージ ビルドでは、各 FROM によって新しいステージが開始されます。これは、他のステージ (環境変数も含む) から分離された新しいイメージ (正確性は低い、ソース要求) として表示されます。イメージには最後の FROM のみが含まれます。

簡単なマルチステージビルドの例を作ってみましょう。

# ステージ1
アルパインから:3.8
WORKDIR /デモ
RUN echo "Hello, stage 1" > /demo/hi-1.txt

# ステージ2
アルパインから:3.8
WORKDIR /デモ
RUN echo "Hello, stage 2" > /demo/hi-2.txt

この Dockerfile を自分でビルドし、 docker save <tag> > docker.tar を実行して内容を確認することができます。何も問題がなければ、/demo/hi-2.txt と Alpine のみが存在するはずです。

この Dockerfile では、 2 つのステージを作成しました。最初のステージでは hi-1.txt が作成され、2 番目のステージでは hi-2.txt が作成されます。最終イメージには 2 番目のステージが追加されますが、他のステージは追加されません。

ファイルのコピー - ステージ間の橋渡し

ステージが互いに完全に分離されている場合、複数のステージを持つ意味はありません。前のステージの結果は完全に破棄され、次の完全に新しいステージに入ります。

COPY コマンドを使用して、他のステージからファイルを取得できます。複数のステージで COPY を使用する方法は通常のアプリケーションとまったく同じで、 --form ` を追加するだけです。次に、最終画像に 2 つのステージの成果物が含まれるように前の例を変更します。

# ステージ1
アルパインから:3.8
WORKDIR /デモ
RUN echo "Hello, stage 1" > /demo/hi-1.txt

# ステージ2
アルパインから:3.8
WORKDIR /デモ
コピー --from=0 /demo/hi-1.txt /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

再構築して保存(保存)すると、hi-1.txt を含む追加のレイヤーが見つかります。

ステージ名 - 迅速な識別

記憶力が 7 秒しかない私たちにとって、ステージ インデックスを毎回使用するのはあまり良いことではありません。このとき、ステージに名前を付けて識別しやすくしておくといいでしょう。

ステージに名前を追加するのは簡単です。FROM の後に <name> を追加するだけです。

ここで、Dockerfile を更新してステージに名前を付け、その名前を使用して COPY します。

# ステージ 1、名前は「build1」です
alpine:3.8 から build1 へ
WORKDIR /デモ
RUN echo "Hello, stage 1" > /demo/hi-1.txt

# ステージ 2、名前は「build2」です
alpine:3.8 から build2 へ
WORKDIR /デモ
# インデックスは使用しなくなりました
コピー --from=build1 /demo/hi-1.txt /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

再構築して保存すると、結果は前回と同じになるはずです。

一部のステージのみを構築 - デバッグが簡単

Docker は、ステージの一部のみをビルドするという非常に便利なデバッグ方法も提供します。特定の段階でビルドを停止し、後続の段階をビルドしないようにすることができます。これにより、デバッグが容易になり、本番環境、開発環境、テスト環境を区別できるようになります。

最後の Dockerfile を引き続き使用しますが、ビルドには --target <stage> パラメータを使用します。

ビルドを --target として実行します。

もう一度保存すると、build1 の内容だけが見つかります。

要約する

マルチステージビルドについては以上です。冒頭の 2 つの Dockerfile に戻って比較してみましょう。最適化前のイメージのどこが太っているのかわかりますか?

当然、コンパイル時にのみ動作し、コンパイル後は役に立たない、役に立たない JDK が含まれています。必要なのは JRE だけです。したがって、マルチステージ ビルドを使用すると、コンパイル ステージと実行ステージを分離してイメージの最適化を実現できます。

参考文献

https://docs.docker.com/develop/develop-images/multistage-build/#ビルドステージ名

https://yeasy.gitbooks.io/docker_practice/image/multistage-builds.html

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Dockerイメージサイズを最適化する一般的な方法
  • Dockerイメージのサイズを縮小する6つの方法

<<:  jsはjQueryをカプセル化する簡単な方法とチェーン操作の詳細な説明を実装します

>>:  MySQLトリガーの使用例の詳細

推薦する

Vue ユニットテストに関する予備調査

目次序文なぜユニットテストを導入するのですか?ユニットテストの概要テスト開発パターン1. テスト駆動...

Windows 10 での Tomcat のインストールと展開に関する詳細なチュートリアル

目次1 Java環境の設定2 tomcatのインストールと展開Tomcat をインストールして展開す...

MYSQL の解凍版における中国語の文字化け問題の解決方法

MYSQLの解凍バージョンがインストールされます1: 解凍後、my.ini ファイルをコピーし、バイ...

Vueでフォーム検証を実装する方法

1. インストールと使用まず、Vue プロジェクトにインストールします。 npm インストール --...

Vue で Axios カプセル化を使用するための完全なチュートリアル

序文現在、プロジェクトでは、Axios ライブラリが HTTP インターフェース リクエストによく使...

MySQL 5.7 の同時レプリケーションにおける暗黙のバグの分析

序文当社の MySQL オンライン環境のほとんどはバージョン 5.7.18 を使用しています。このバ...

VueのVuexの4つの補助機能について

目次1. 補助機能2. 例1. mapState と mapGetters 2. mapMutati...

MySQL マスタースレーブレプリケーションの詳細な分析

序文: MySQL では、マスター/スレーブ アーキテクチャが最も基本的かつ最も一般的に使用されるア...

Vueグローバルカスタム命令の実践 モーダルドラッグ

目次背景実装のアイデア成果を達成する背景最近取り組んでいるプロジェクトは、Vue2 で構築されたプロ...

Linux で MySQL スケジュール タスク バックアップ データを実装する方法

序文バックアップは災害復旧の基礎であり、システム操作エラーやシステム障害によるデータ損失を防ぐために...

MySQLはライブラリ内の主キーなしでテーブルインスタンスコードを素早く取得します

概要MySQL データベースで主キーのないテーブルを表示するための SQL ステートメントをいくつか...

LINUX ポートが占有されているかどうかを確認します

ポートが占有されているかどうかは、これまで一度もわかりませんでした。多くの人に尋ねて、ようやくわかり...

MySQL の無効な左結合の問題を解決する方法とその使用上の注意

MySQLの左結合が無効であり、その使用方法今日SQLを書いていたとき、左結合を使用すると左のテーブ...

React Native JSIはRNとネイティブ通信のサンプルコードを実装します

目次JSIとはJSIの違いiOS で JSI を使用するiOS 設定RN側の構成jsはパラメータ付き...

HTML ページをスクロールするときに一部のコンテンツを固定位置に固定する方法

この記事では主に、レイアウトに役立つ、HTML ページ内の一部のコンテンツを固定してスクロール時にス...