数か月前、私はコンテナー内のコンテナー構築の高速化に関する記事を書きました。この記事では、コンテナイメージのプル速度と、ホストからのボリュームマウントと、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
):
- コンテナ内のすべてのパッケージを更新します。
- 選択したパッケージ
nginx
をインストールします 。 - すべてをクリーンアップします。
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コンテナーの基本を学びます。 ]