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

推薦する

JavaScript データ プロキシとイベントの詳細な分析

目次データブローカーとイベントObject.defineProperty メソッドのレビューデータブ...

Linux 環境変数とプロセス アドレス空間の概要

目次Linux 環境変数とプロセスアドレス空間コードを通じて環境変数を取得するプロセスアドレス空間な...

CocosCreator スケルトンアニメーション ドラゴンボーン

CocosCreator バージョン 2.3.4ドラゴンボーンアニメーションキールアニメーションを ...

Linux学習におけるmkdirコマンドの詳しい説明

目次序文1. ファイルの概念に関する基礎知識2. mkdir コマンド序文最近、Linux にますま...

MySQLデータベースのSYNフラッディング問題を解決する

Syn 攻撃は、最も一般的で最も簡単に悪用される攻撃方法です。TCP プロトコルの欠陥を利用して、偽...

ウェブフォーム送信方法の詳細な概要

まず、フォームを送信するいくつかの方法を見てみましょう。 1. <!--一般的な送信ボタン--...

MySQL コマンドを使用してインデックスを作成、削除、およびクエリする方法の紹介

MySQL データベース テーブルでは、インデックスを作成、表示、再構築、削除できるため、クエリ速度...

MySQL マスタースレーブの原理と構成の詳細

MySQLのマスタースレーブ構成と原理、参考までに具体的な内容は以下のとおりです。 1. 環境の選択...

Xmeter APIインターフェーステストツールの使用状況の分析

XMeter API は、以下のサービスを含む、JMeter に基づくワンストップのオンライン イン...

CSSとHTMLを組み合わせる4つの方法

(1)各HTMLタグには属性スタイルがあり、CSSとHTMLを組み合わせている。 <div s...

HTML+CSS マージテーブル境界線サンプルコード

table タグと td タグに境界線を追加すると、デフォルトでは次のように二重境界線が使用されます...

jQueryをベースにカルーセル効果を実現する

この記事では、カルーセルマップの効果を実現するためのjQueryの具体的なコードを参考までに共有しま...

MySQL はどのようにしてマスターとスレーブの一貫性を確保するのでしょうか?

目次MySQLマスタースレーブの基本原理3つのbinlog形式の比較混合形式のバイナリログが存在する...

Windows10システムにMySQL 5.7.17をインストールする

オペレーティング システム win10 MySQL は、公式 Web サイトからダウンロードした 6...

ウェブページの画像の回転を実現するjs

この記事では、Webページの画像の回転を実現するためのjsの具体的なコードを参考までに共有します。具...