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トリガーの使用例の詳細

推薦する

MySQL はどのようにしてマスターとスレーブの同期を実現するのでしょうか?

マスタースレーブ同期 (マスタースレーブレプリケーションとも呼ばれる) は、マスタースレーブデータの...

CSS3はアニメーション効果を実現するためにvar()とcalc()関数を使用する。

ナレッジポイントをプレビューします。アニメーションフレーム背景グラデーションvar() と calc...

Element-ui レイアウト (行と列コンポーネント) の実装

目次基本的な手順と使用方法行コンポーネントの分析レンダリング機能ソースコード分析Col成分の分析コン...

MySQL DATEDIFF 関数を使用して 2 つの日付間の時間間隔を取得する方法

説明する2 つの日付間の時間間隔を返します。文法DateDiff(間隔、日付1、日付2 [、週の最初...

JavaScript フロントエンドのタイムアウト非同期操作に最適なソリューション

目次コードの実行に長い時間がかかる場合はどうなりますか? Axiosにはタイムアウト処理機能が搭載さ...

誰もが登録できるようにJiedaibaoを宣伝するにはどうすればよいでしょうか? ジエダイバオのプロモーション方法とスキル

借財宝は最近人気が出ている携帯電話ローンソフトウェアプラットフォームです。知人同士の貸し借りが特徴で...

Linux システムをバックアップする docker コマンドの詳細な説明

tar バックアップ システム sudo tar cvpzf backup.tgz --exclud...

JavaScript でロジック判定コードを最適化する方法

序文日常生活で使用する論理的判断文には、if...else...、switch...case...、...

Vue の高度なコンポーネント機能コンポーネントの使用シナリオとソースコード分析

目次導入使用シナリオソースコード分析要約する導入Vue は、コンポーネントをステートレスかつインスタ...

Linux環境でIPV6接続をサポートするようにmysql5.6を設定する方法

導入:この記事では主に、Linux システムで IPV6 接続をサポートするように MySQL を構...

マインスイーパゲームを実装するための jQuery プラグイン (2)

この記事では、jQueryプラグインを使用してマインスイーパゲームを実装する2番目の記事を参考までに...

さまざまな MySQL テーブルソートルールのエラーの分析

MySQL が複数のテーブルを結合するときに、次のエラーが報告されます: [Err]1267 – 操...

Mysql トランザクションで Update を実行するとテーブルがロックされますか?

2つのケース: 1. 索引あり 2. 索引なし前提条件:方法: コマンドラインを使用してシミュレー...

Vue はインターフェースのスライド効果を実装します

この記事では、インターフェースのスライド効果を実現するためのVueの具体的なコードを例として紹介しま...

Gearman + MySQL による永続化操作例

この記事では、gearman+mysql メソッドを使用して永続化操作を実装します。ご参考までに、詳...