GNU/Linux >> Linux の 問題 >  >> Linux

Buildahを使用したコンテナイメージビルドの高速化

数か月前、私はコンテナー内のコンテナー構築の高速化に関する記事を書きました。この記事では、コンテナイメージのプル速度と、ホストからのボリュームマウントと、Buildahの「追加ストア」の概念を使用してイメージストアを事前入力するさまざまな方法に焦点を当てました。

Buildahは、Open Container Initiativeと互換性のある(つまり、DockerとKubernetesと互換性のある)イメージをすばやく簡単に構築するためのコマンドラインツールです。 Buildahは、スクリプトへの組み込みとパイプラインの構築が簡単であり、何よりも、イメージを構築するために実行中のコンテナデーモンを必要としません。

この記事では、dnfを使用する場合のビルド速度に関する2番目の問題について説明します。 / yum コンテナ内のコマンド。この記事では、dnfという名前を使用することに注意してください 一部のダウンストリームが使用するもの(yum)の代わりに(アップストリーム名) )これらのコメントは、両方のdnfに適用されます およびyum

ダウンロード速度

dnf -y updateを実行すると時々気付くことがありますか またはdnf -y install 久しぶりに、RPMのプルダウンを開始する前に、コマンドが長時間一時停止しますか?何が起こっているのですか?

dnfの最初のもの 巨大なキャッシュファイルをダウンロードします。これらのファイルはXMLで記述されており、パッケージに関する多くのデータを含む、リモートリポジトリ内のすべてのパッケージが含まれています。パッケージ内のすべてのパスも含まれています。このデータは、dnf -y install /usr/bin/httpdのようなものを実行できるようにするために必要です。 次に、dnf インストールするパッケージを把握します。多くのパッケージには、(requires: /usr/bin/sendmailのようなコマンドが含まれています )この機能を利用して、dnfを許可します ニーズを満たすために適切なパッケージを引き出すため。

これらの巨大なファイルをプルすること、そしてさらに重要なことに、これらのファイルを処理することは、1分以上かかることがあります。このデータはlibsolvによって使用されます 、したがって、solvに変換する必要があります 遅いフォーマット。ホストで定期的にこれを行う場合、速度は大きな問題ではありませんが、コンテナの構築に関しては、これははるかに大きな問題です。

Dockerfile構文

Buildahを使用すると、シェルで直接コンテナーイメージを構築できますが、ほとんどの場合、DockerfilesとContainerfilesを使用してコンテナーを構築し、再現可能なイメージレシピを定義します。 Buildahは、デフォルトでContainerfileを検索します およびDockerfile 今。それぞれが同じ構文を共有しているので、Containerfileを使用します このドキュメントの残りの部分について。

Containerfileで行う一般的なこと 次のような構文を使用することです:

FROM ubi8  
RUN dnf -y update; dnf -y install nginx; dnf -y clean all  
…  
RUN dnf -y install jboss; dnf -y clean all  

dnfを調べてみましょう 行。最初のdnf 行:

dnf -y update; dnf -y install nginx; dnf -y clean all ):

  1. コンテナ内のすべてのパッケージを更新します。
  2. 選択したパッケージnginxをインストールします 。
  3. すべてをクリーンアップします。

ubi8以降 画像はおそらく少し前に作成されたものであり、その/var/cache/dnf コンテナイメージdnf内にディレクトリが存在しない可能性があります XMLキャッシュファイルをプルダウンして処理する必要があります。次に、dnf dnf -y clean allの前に実際のパッケージをインストールします 以前のコマンドがログやキャッシュファイルなどの画像に配置した余分なデータをすべて削除します。

clean allを実行することをお勧めします 画像をできるだけ小さく保つため。各RUN コマンドは新しいレイヤーを作成し、後でRUNでコンテンツを削除した場合でも コマンドを実行すると、最初のレイヤーにすべてのコンテンツが含まれます。これは、イメージをプルするすべての人がログとキャッシュファイルをプルすることになることを意味します。ここで、Containerfile 1つ以上のdnfが含まれています コマンドを実行すると、価格を何度も支払うことになります。それだけでなく、このイメージを再構築するたびに、その価格をもう一度支払うことになります。ビルドサーバーを使用している場合、ビルドするすべてのコンテナイメージは、これらのXMLファイルを何度もダウンロードし、大量のリソースと時間を浪費します。

オーバーレイマウントを備えたBuildah

上記の問題を見て、これをより適切に処理できると考えました。 XMLデータをホストにプルし、ホストで処理して、コンテナーにボリュームマウントするだけでは不十分でしょうか。おそらく、cronジョブまたはsystemdを設定できます。 dnf makecacheを実行するタイマー コンテナイメージを構築するOSのバージョンごとに1回ですか?このジョブをホストで1日に1回または複数回実行してから、すべてのコンテナビルダーに適切なキャッシュをbuildahコンテナにボリュームマウントさせることができます。

Buildahは、ホストからコンテナへのボリュームマウントディレクトリをサポートしています。それは問題を解決するはずです、そしてそれはそうします。ただし、キャッシュを更新する必要がある場合、コンテナはこのディレクトリに書き込みたいことが多いため、キャッシュをコンテナの読み取り/書き込みにマウントする必要があります。これは大きなセキュリティホールを引き起こします。敵対的なコンテナビルドが、後のコンテナビルダーが読み取るコンテンツをこのキャッシュに書き込んだ状況を想像してみてください。 2番目のコンテナをだましてハッキングされたソフトウェアをインストールさせる可能性があります。コンテンツがコンテナにマウントされ、コンテナで書き込むことはできないが、コンテナの観点からは書き込むことができるソリューションが必要です。これが基本的にオーバーレイマウントポイントです。

オーバーレイファイルシステムはlowerをマウントします ディレクトリを作成してから、upperを添付します mergedへのディレクトリ マウントポイント。プロセスが新しいファイルをmergedに書き込むとき ディレクトリの場合、新しいファイルはupperに書き込まれます ディレクトリ。プロセスがlowerの既存のファイルを変更するとき ディレクトリ、カーネルはlowerからファイルをコピーします upperへのディレクトリ ディレクトリを作成し、プロセスがupper内のファイルを変更できるようにします ディレクトリ。

Buildahにオーバーレイマウントの概念を導入しました。これで、ビルドを実行できます

buildah bud -v /var/cache/dnf:/var/cache/dnf:O -f /tmp/Containerfile /tmp  

Dnf コンテナの内部は、リポジトリに新しいコンテンツがあるかどうかを確認し、存在する場合はコンテンツをプルダウンします。ただし、ホスト上のコンテンツが最新の場合、ホストのキャッシュをすばやく使用します。ホストのキャッシュを少なくとも1日に1回更新することをお勧めします。

Buildahオーバーレイマウントに追加した機能の1つは、upperを破棄することです。 すべてのRUNのディレクトリ 指令。この例では、複数のRUNを使用したことを思い出してください。 それぞれがdnf -y clean allを実行していたコマンド 。 dnf -y clean all コマンドはupperを引き起こします 下から削除されたものとしてすべてのコンテンツを表示するディレクトリ。次のdnf コマンドは前のアッパーを共有し、キャッシュが空であると見なし、XMLデータストアをプルダウンして処理する必要があります。 upperを削除する ディレクトリとは、各dnf コマンドは再びlowerを表示します ホストからディレクトリを作成し、引き続きホストキャッシュを共有します。

速度差

簡単なContainerfileを作成します 2つのdnfを含む コマンドを実行します。

FROM fedora:31  
RUN dnf -y install net-utils; dnf -y clean all  
RUN dnf -y install iputils; dnf -y clean all  

これをFedora31ボックスでローカルに実行する

# time -f "Elapsed Time: %E" buildah bud -f Containerfile .  
STEP 1: FROM fedora:31  
STEP 2: RUN dnf -y install procps-ng; dnf -y clean all  
Fedora Modular 31 - x86_64 2.0 MB/s | 5.2 MB 00:02  
Fedora Modular 31 - x86_64 - Updates 1.6 MB/s | 4.0 MB 00:02  
Fedora 31 - x86_64 - Updates 4.2 MB/s | 19 MB 00:04  
Fedora 31 - x86_64 1.8 MB/s | 71 MB 00:39  
Last metadata expiration check: 0:00:01 ago on Wed Feb 5 13:55:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
procps-ng x86_64 3.3.15-6.fc31 fedora 326 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 326 k  
Installed size: 966 k  
Downloading Packages:  
procps-ng-3.3.15-6.fc31.x86_64.rpm 375 kB/s | 326 kB 00:00  
--------------------------------------------------------------------------------  
Total 218 kB/s | 326 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : procps-ng-3.3.15-6.fc31.x86_64 1/1  
Running scriptlet: procps-ng-3.3.15-6.fc31.x86_64 1/1  
Verifying : procps-ng-3.3.15-6.fc31.x86_64 1/1

Installed:  
procps-ng-3.3.15-6.fc31.x86_64

Complete!  
33 files removed  
STEP 3: RUN dnf -y install iputils; dnf -y clean all  
Fedora Modular 31 - x86_64 741 kB/s | 5.2 MB 00:07  
Fedora Modular 31 - x86_64 - Updates 928 kB/s | 4.0 MB 00:04  
Fedora 31 - x86_64 - Updates 3.8 MB/s | 19 MB 00:05  
Fedora 31 - x86_64 7.9 MB/s | 71 MB 00:08  
Last metadata expiration check: 0:00:01 ago on Wed Feb 5 13:57:13 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 252 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 141 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
33 files removed  
STEP 4: COMMIT  
Getting image source signatures  
Copying blob ac0b803c5612 skipped: already exists  
Copying blob 922380d685bc done  
Copying config 566e2afbb4 done  
Writing manifest to image destination  
Storing signatures  
566e2afbb417f0119109578a87950250b566a3b4908868627975a4c7428accfb  
566e2afbb417f0119109578a87950250b566a3b4908868627975a4c7428accfb

Elapsed Time: 2:15.00  

この実行には、2つの新しいパッケージを使用して新しいコンテナイメージを作成するのに2分15秒かかりました。

それでは、ホストからのオーバーレイマウントでこれを試してみましょう。

# dnf -y makecache  
# time -f "Elapsed Time: %E" buildah bud -v /var/cache/dnf:/var/cache/dnf:O -f Containerfile .  
STEP 1: FROM fedora:31  
STEP 2: RUN dnf -y install procps-ng; dnf -y clean all  
Last metadata expiration check: 0:02:34 ago on Wed Feb 5 13:51:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
procps-ng x86_64 3.3.15-6.fc31 fedora 326 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 326 k  
Installed size: 966 k  
Downloading Packages:  
procps-ng-3.3.15-6.fc31.x86_64.rpm 496 kB/s | 326 kB 00:00  
--------------------------------------------------------------------------------  
Total 245 kB/s | 326 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : procps-ng-3.3.15-6.fc31.x86_64 1/1  
Running scriptlet: procps-ng-3.3.15-6.fc31.x86_64 1/1  
Verifying : procps-ng-3.3.15-6.fc31.x86_64 1/1

Installed:  
procps-ng-3.3.15-6.fc31.x86_64

Complete!  
285 files removed  
STEP 3: RUN dnf -y install iputils; dnf -y clean all  
Last metadata expiration check: 0:02:41 ago on Wed Feb 5 13:51:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 556 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 222 kB/s | 141 kB 00:00  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
285 files removed  
STEP 4: COMMIT  
Getting image source signatures  
Copying blob ac0b803c5612 skipped: already exists  
Copying blob 524bb3b83d61 done  
Copying config 0f82aa6064 done  
Writing manifest to image destination  
Storing signatures  
0f82aa6064814ff3dcb603c34c75e516e00817811681b83b8632f3e9b694e518  
0f82aa6064814ff3dcb603c34c75e516e00817811681b83b8632f3e9b694e518  
Elapsed Time: 0.17.44  

オーバーレイマウントを使用すると、2分15秒ではなく、17秒で2つの追加パッケージを使用して新しいイメージを作成できました。これは、同じコンテナイメージを構築するのにほぼ8倍高速です。

これは、dnfを持つホストオペレーティングシステムでイメージをビルドする場合を示しています。 メタデータが事前にキャッシュされているため、インストール速度を大幅に向上させることができます。しかし、ビルドシステムが他のバージョンのOS用のイメージをビルドする場合はどうなるでしょうか。 Fedora30とFedora31のイメージをビルドしたいとします。注:これはRHEL8システムでも機能し、RHEL7およびおそらくRHEL6イメージをビルドしたい場合があります。
Dnf> --releaseverを使用して、コンテンツをプルするときにさまざまなリリースを指定できるクールな機能が含まれています オプション。 Dnf また、cachedirを配置するための代替ディレクトリを指定することもできます。--setopt=cachedir

次の例では、ホスト上の2つのキャッシュをプルダウンしてから、コマンドラインモードでBuildahを使用します。

# dnf -y makecache --releasever=31 --setopt=cachedir=/var/cache/dnf/31  
# dnf -y makecache --releasever=30 --setopt=cachedir=/var/cache/dnf/30  
# ctr31=$(buildah from fedora:31)  
# time -f 'Elapsed Time: %E' buildah run -v /var/cache/dnf/31:/var/cache/dnf:O ${ctr31} dnf -y install iputils  
Last metadata expiration check: 0:00:15 ago on Wed Feb 5 14:17:41 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 192 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 107 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
Elapsed Time: 0:06.85

# ctr30=$(buildah from fedora:30)  
# time -f 'Elapsed Time: %E' buildah run -v /var/cache/dnf/30:/var/cache/dnf:O ${ctr30} dnf -y install iputils  
Last metadata expiration check: 0:00:15 ago on Wed Feb 5 14:17:47 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20180629-4.fc30 fedora 123 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 123 k  
Installed size: 351 k  
Downloading Packages:  
iputils-20180629-4.fc30.x86_64.rpm 370 kB/s | 123 kB 00:00  
--------------------------------------------------------------------------------  
Total 138 kB/s | 123 kB 00:00  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20180629-4.fc30.x86_64 1/1  
Running scriptlet: iputils-20180629-4.fc30.x86_64 1/1  
Verifying : iputils-20180629-4.fc30.x86_64 1/1

Installed:  
iputils-20180629-4.fc30.x86_64

Complete!  
Elapsed Time: 0:08.88  

ご覧のとおり、dnfを使用してBuildahコンテナーを実行できました。 同じビルドホストからのFedoraの2つの異なるリリースからのキャッシュとFedora31のコンテナーは6秒以上かかり、Fedora30ビルドは8秒以上かかりました。

注:/var/cache/dnfのサブディレクトリを選択しました キャッシュファイルの場合、SELinuxラベルが正しいことを確認します。 dnf clean allを実行するだけです /var/cache/dnf/31はクリーンアップされません 。 dnf clean all --setopt=cachedir=/var/cache/dnf/31を実行する必要があります リポジトリにキャッシュされたファイルを適切にクリーンアップしますが、アーティファクトの一部は残ります(gpgキー、空のディレクトリ)。

ここで、オーバーレイマウントなしでFedora31でビルドを実行するのにかかる時間を確認します。

# ctr31=$(buildah from fedora:31)  
# time -f 'Elapsed Time: %E' buildah run ${ctr31} dnf -y install iputils  
Fedora Modular 31 - x86_64 1.2 MB/s | 5.2 MB 00:04  
Fedora Modular 31 - x86_64 - Updates 875 kB/s | 4.0 MB 00:04  
Fedora 31 - x86_64 - Updates 2.4 MB/s | 19 MB 00:07  
Fedora 31 - x86_64 1.7 MB/s | 71 MB 00:41  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 279 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 129 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
Elapsed Time: 1:29.85  

この場合、同じコンテナーを実行するのに約1.5分かかりました。オーバーレイマウントを備えたBuildahは14倍速く実行されました。

ルートレスコンテナ

これまでの私の例はすべて、Containerfilesを使用してビルドを実行してきました。 ルートとして。ただし、これはルートレスコンテナでも実行できます。次のいくつかの例では、buildah runを使用してBuildahでコンテナを実行します。 キャッシュの使用を示す構文。

実行中

$ buildah run -v /var/cache/dnf/30:/var/cache/dnf:O ${ctr30} dnf -y install iputils  

正常に動作します。ユーザーが/var/cache/dnf/30を読み取ることができる限り ディレクトリ、lower ディレクトリを読み取ることができます。ただし、キャッシュを定期的に更新するには、ホスト上の何かに依存する必要があります。

ユーザーが望む場合は、dnfを使用することもできます ホームディレクトリにキャッシュを作成します。

$ dnf -y makecache --releasever=30 --setopt=cachedir=$HOME/dnfcache  
$ chcon --reference /var/cache/dnf -R $HOME/dnfcache  
$ ctr30=$(buildah from fedora:30)  
$ buildah run -v $HOME/dnfcache:/var/cache/dnf:O ${ctr30} dnf -y install iputils  

$HOME/dnfcacheのSELinuxラベルを変更する必要があることに注意してください SELinuxがコンテナがlowerを読み取れるようにするためのディレクトリ オーバーレイマウントのディレクトリ。

結論

コンテナーの構築を高速化するには、パッケージをインストールするときに何が起こっているのかを理解する必要があります。 dnfの事前キャッシュ ホスト上のデータとオーバーレイマウントを使用してBuildahを使用してキャッシュをコンテナにマウントすると、ビルドの速度が大幅に向上し、ビルドファームをサポートするために必要なリソースの数を減らすことができます。

Buildahはシンプルさに匹敵しますが、Overlay mountsなどの優れた機能も備えています。 およびadditional stores これは、コンテナイメージのビルドを高速化するのに役立ちます。

[コンテナは初めてですか? Containers Primerをダウンロードして、Linuxコンテナーの基本を学びます。 ]


Linux
  1. Linuxで独自のコンテナを構築する

  2. サーバーイメージングでタスク状態を使用する

  3. webp による画像の最適化

  1. mysql コンテナーにデータをコミットする

  2. dd を使用して ISO イメージを USB にコピーする方法

  3. 特権 Docker コンテナを使用したカーネル チューニング

  1. Dockerコンテナからカスタムイメージを作成する方法

  2. DISMを使用してシステムイメージを修復する

  3. 検索ですべてのグラフィック イメージ ファイルを一覧表示しますか?