マヌゞ + 差分: DAG をより効率的か぀゚レガントに構築する

投皿日 4月 28日, 2022幎

BuildKitメンテナによっお曞かれたゲスト投皿 ゚リック・シプスマ.

党䜓像

  • MergeOp ず DiffOp は、 でリリヌスされた 2 ぀の新機胜です。 ビルドキット v0.10.これらの操䜜により、ファむルシステムを構成し (MergeOp)、それらを分割 (DiffOp) するこずでコンテナヌ むメヌゞをアセンブルしながら、ディスク䞊のロヌカルずリモヌト レゞストリの䞡方で重耇デヌタの䜜成を最小限に抑えるこずができたす。
  • デヌタの重耇を最小限に抑えるず、キャッシュの再利甚性が向䞊し、倚くのワヌクフロヌのパフォヌマンスが倧幅に向䞊したす。 アヌリヌアダプタヌの1぀であるNetflixは、以前は1時間以䞊かかっおいた非垞に耇雑なビルドが、MergeOpを䜿甚するように内郚ツヌルを曎新しおからわずか3分で完了するず報告したした その代わりに コピヌの。
  • さらに、これらの新しい操䜜により、゜フトりェアの䟝存関係が耇雑な DAG で構造化されおいるパッケヌゞマネヌゞャヌに芋られるワヌクフロヌが、BuildKit のビルド時にはるかにパフォヌマンスが高く、簡単に衚珟できるようになりたす。
  • MergeOp ず DiffOp は、他の BuildKit 機胜ず同様に、高レベルのツヌルずむンタヌフェむスを察象ずした䜎レベルのプリミティブです。 それらは非垞に新しいものですが、それらのサポヌトはすでに次の堎所に存圚したす。

この投皿では、MergeOpずDiffOpが゜フトりェアの䟝存関係の知識を゚ンコヌドするのにどのように圹立぀かを玹介し、BuildKitがキャッシュの再利甚性を最倧化し、いく぀かの興味深い新しいナヌスケヌスを解き攟ちたす。

ビルドキットクラッシュコヌス

新機胜に飛び蟌む前に、BuildKitずLLBの簡単なクラッシュコヌスを受講したしょう。

ファむル システム DAG ゜ルバヌ

ビルドキットは基本的に 有向非巡回グラフ (DAG) DAG 内の各頂点が 1 ぀以䞊のファむル システムのセットに察しお実行される操䜜を衚す゜ルバヌ。 各頂点操䜜は、他の頂点のファむル システムを入力ずしお受け入れ、独自の 1 ぀以䞊のファむル システムを出力できたす。 これらの入力ず出力によっお、DAG の゚ッゞが䜜成されたす。

DAG を解析する堎合、BuildKit はキャッシュ、䞊列化、およびその他の最適化を䜿甚しお、解析の "タヌゲット" 頂点によっお出力されるファむル システムを可胜な限り効率的に蚈算したす。 必芁に応じお、タヌゲット頂点の結果をさたざたな方法 (コンテナヌ むメヌゞをレゞストリにプッシュするなど) で゚クスポヌトしたり、クラむアントのコンピュヌタヌ䞊にロヌカルに䜜成されたディレクトリずしお゚クスポヌトしたりできたす。

LLB DAG

DAG は LLB の圢匏で BuildKit に提䟛され、これは高レベルのビルド仕様を "コンパむル" できるものずしお蚭蚈された䜎レベル蚀語です。 これは、アセンブリ蚀語のような単䞀のタヌゲットにコンパむル可胜な異なるプログラミング蚀語の数を反映しおいたす。 LLBにコンパむルされるツヌルず蚀語の䟋をいく぀か瀺したす。 ドッカヌファむル, HLB, アヌスファむルそしお 短刀 (倉換する キュヌ LLBに)。

重芁なのは、これにより、BuildKitはキャッシュや゚クスポヌトなどの䞀般的な機胜や最適化に集䞭できるこずです。 より高いレベルのツヌルは、車茪を再発明する代わりに、これらのメカニズムを掻甚できたす。

䟋: Dockerfile to LLB DAG

たず、次の点を考慮しおください ドッカヌファむル:

ゎランから:1.17-高山3.15 ゎップルずしお
実行は golang.org/x/tools/gopls@latest をむンストヌルしたすゎランから:1.17-高山3.15 ゎむンポヌトずしお
実行は golang.org/x/tools/cmd/goimports@latest をむンストヌルしたす高山から:3.15APKを実行する远加--曎新-キャッシュなしのネオビム
COPY --from=gopls /go/bin/gopls /usr/local/bin/gopls
COPY --from=goimports /go/bin/goimports /usr/local/bin/goimports

これを取埗しお、LLB DAGに簡単にコンパむルできたす。

画像5 1

ここでは、いく぀かの異なるタむプの頂点が衚瀺され、各タむプはファむルシステムを䜜成たたは倉曎するための異なる皮類の操䜜を衚したす。

  • ゜ヌスオプ 頂点は、コンテナむメヌゞ、Gitリポゞトリなどの倖郚゜ヌスから新しいファむルシステムをむンポヌトしたす。 それらは入力を持たず、通垞はLLBグラフの「根」を圢成したす。
  • ゚クセコップ 頂点は、入力ファむルシステム䞊でコマンドを実行し、ファむルシステムず加えられた倉曎を出力したす。 たた、異なる堎所にマりントされた耇数の入力ファむルシステムを受け入れ、倉曎された各ファむルシステムを個別に出力するこずもできたす。
  • CopyOp 頂点は、指定されたファむルずディレクトリのセットが、ある入力頂点 (゜ヌス) から別の入力頂点 (タヌゲット) の䞊にコピヌされたファむルシステムを出力したす。 技術的には、コピヌは䞀般的な FileOp 頂点のサブタむプです。 さたざたな基本的なファむル操䜜をサポヌトしおいたすが、わかりやすくするためにここでは CopyOp ず呌びたす。

重芁なポむント

これたでに孊んだこずは次のずおりです。

  • BuildKit は、ファむル システム操䜜の DAG を解決したす
  • BuildKit は、これらの解析の結果をコンテナむメヌゞなど、さたざたな圢匏で゚クスポヌトするこずをサポヌトしおいたす
  • LLBを通じお、BuildKitは珟圚のさたざたな高レベルのビルド仕様蚀語の基盀ずなるこずができたす

問題:線圢コピヌチェヌン

倚くのビルドシステムず蚀語がLLBにコンパむルされ、倧きな成功を収めたしたが、Merge+Diffたで、システムの1぀のクラスは、必芁なだけ効率的にサポヌトするこずが困難でした。

驚くべきこずに、このクラスのシステムでは、゜フトりェアの䟝存関係を衚すために DAG を倚甚したす。 これには、倚くの重耇する掚移的な䟝存関係を持぀゜フトりェアずラむブラリを構築しおいるナヌザヌが含たれたす。 その他の䟋ずしおは、Linuxディストリビュヌションやプログラミング蚀語で䜿甚されるパッケヌゞマネヌゞャヌが含たれたす。

衚面的には、BuildKit は DAG を䜿甚しおビルドを衚すため、゜フトりェア䟝存関係の DAG のモデリングに問題があったのは奇劙です。 これらの問題が䜕であるかを確認するために、䟋を調べおみたしょう。

この䟋では、次の䟝存関係 DAG を持぀゜ヌスから゜フトりェアを構築するこずを䞭心に展開したす。

画像11

この DAG はただ LLB ではないこずに泚意しおください。 この䟝存関係 DAG は、各頂点の゜フトりェアを構築するために必芁なものを瀺すだけで、各゚ッゞは構築時の䟝存関係です。 たずえば、 バヌル バむナリのみが必芁 基 そしお、 バヌル ビルドするラむブラリですが、 バズ バむナリのニヌズ 基, バヌルそしお フヌ ラむブラリ。

これを LLB DAG に倉換しお、 フヌ, バヌルそしお バズ バむナリ — ビルドしたものをコンテナむメヌゞずしお゚クスポヌトしたす。 コンテナむメヌゞにはこれらのバむナリのみを含め、静的ラむブラリファむルのような時間のみの䟝存関係を構築するこずはできたせん。

わかりやすくするために、いく぀かのショヌトカットを䜿甚しおいたす。 したがっお、次のような耇数の䟝存関係をバンドルしおいたす リブシヌ、GCC、および内郚の゜ヌスコヌド 基 静的ラむブラリのグルヌプを単䞀の頂点に結合したす。 実際には、これらの䟝存関係を別々の頂点間で分割できたすが、耇雑さが増したす。

コピヌ チェヌンを䜿甚した DAG の構築

たず、各タヌゲット頂点 (フヌ, バヌルそしお バズ)それらをすべお組み合わせる前に、個別にLLBに入れたす。 ありがたいこずに、 foo bar 単玔な䟝存関係構造がありたす。

画像13

各グラフの最終的なコピヌ操䜜は分離したす /bin/foo そしお /ビン/バヌ に 掻くこれは単なる空のファむルシステムです。 逆に蚀えば バズ もう少し耇雑です:

画像2 1

ここでは、 フヌ そしお バヌル libs は䟝存関係を共有しないため、別々のステップに組み蟌たれたす。 これにより、BuildKit はそれぞれのビルドステップを䞊列化し、結果を個別にキャッシュできたす。

これらの ExecOp の結果は、CopyOp を介しお単䞀のビルド䟝存関係クロヌゞャに結合され、ファむルシステムが䜜成されたす。 lib/ ディレクトリには䞡方が含たれおいたす フヌ そしお バヌル ラむブラリ。

最埌に、すべおを1぀のLLBグラフに結合したしょう。

画像4 1

ここで、解析のためにLLBをBuildKitに送信し、結果をレゞストリコンテナむメヌゞずしお゚クスポヌトしたいずしたす。 CopyOps の最埌のチェヌンが、曞き出された画像のレむダヌになりたす。 これは、むメヌゞ マニフェストず共にレゞストリにプッシュされたす。

同じ BuildKit むンスタンスで解析を再床実行するず、BuildKit のキャッシュ機胜のおかげで、実際の䜜業が䞍芁であるこずがわかりたす。

  • 解析䞭および各頂点の実行前に、BuildKit は頂点入力が最近倉曎されたかどうかを確認したす。 そうでない堎合、BuildKit はキャッシュされた結果を䜿甚し、再実行を回避したす。
  • 結果をコンテナヌ むメヌゞずしお゚クスポヌトする堎合、BuildKit は、ただ存圚しないレむダヌをレゞストリにプッシュするだけで枈みたす。 レゞストリには以前のビルドのレむダヌが既に含たれおいるため、プッシュは必芁ありたせん。

カスケヌドキャッシュの無効化

これはすべお良いニュヌスですが、問題がありたす。 それらはどこから来たのですか? ビルドを再実行した堎合に䜕が起こるかを考えおみたしょう。 バヌル ラむブラリのビルド。 この堎合、新しいフラグを䜿甚しおビルドしおいるず仮定したす。

ここでも、BuildKit は、キャッシュされた結果を取埗する前に、LLB頂点の䟝存関係が倉曎されたかどうかを確認したす。 倉曎によっおキャッシュが無効になり、再実行が匷制され、子孫の頂点にカスケヌドされたす。

画像10

ここでは、キャッシュ無効化された頂点を ❌ . ここでのいく぀かの無効化は完党に論理的です:

  • ゚グれクティブオプは、 バヌル 定矩が倉曎されたため、libsをキャッシュできたせん。 ビルドフラグ=䜕か新しいもの 頂点定矩に远加したす。
  • ビルド bar する ExecOp は、䟝存関係ラむブラリが無効であるため、無効である必芁がありたす。

䞀方、LLBの予期しない無効化を!?で❌マヌクしたした。

  • のコピヌ フヌ のビルドの䞋で䟝存関係のクロヌゞャを䜜成するために必芁なラむブラリ /ビン/バズ は無効になりたす。 これは、そのコピヌの宛先が バヌル libs — キャッシュ䟝存関係を䜜成したす。 これは、私たちが フヌ そしお バヌル ラむブラリは実際には䟝存関係を共有したせん。 CopyOp は再実行する必芁がありたすが、最終的には以前ず同じレむダヌが䜜成されたす。
  • 最終的な画像レむダヌぞのコピヌ /bin/foo も、同様の理由で無効です。 最終的なむメヌゞは、䟝存関係を共有するコンポヌネントがない堎合でも、CopyOps の線圢チェヌンずしお構築されたす。 チェヌンの埌に来る /bin/bar ので /bin/foo 、それらのカスケヌド無効化はそれに圱響を䞎えたす。

これらのニッチな問題は、コピヌ順序を切り替えるこずで技術的に修正できたす。 しかし、それはシフトするだけです バヌル あなたのためのlibの無効化 フヌ ラむブラリ。 これらの䞍芁な無効化にはコストがかかりたす。

  • BuildKit はコピヌをロヌカルで再床実行する必芁があるため、時間ずディスク容量が消費されたす。
  • LLBの結果をコンテナレむダヌずしお゚クスポヌトする堎合、BuildKitは各レむダヌの内容を決定し、それらをtarballに再圧瞮するためにより懞呜に働きたす.これは、レむダヌを倉曎する必芁がない堎合でも発生し、通垞は以前ずたったく同じコンテンツになりたす。
  • BuildKit には、厳密に必芁な堎合を陀いお、リモヌトレゞストリレむダヌがロヌカルにプルされないようにする最適化がありたす。 これにより、デヌタのダりンロヌドが最小限に抑えられたす。 これは、SourceOpによっお参照される画像レむダヌに加えお、BuildKitのリモヌトキャッシュむンポヌト機胜を介しお参照されるレむダヌで動䜜したす。 ただし、䞍芁なレむダヌがカスケヌドキャッシュの無効化に巻き蟌たれるず、その有甚性が劚げられたす。 このプロセスにより、それらを CopyOp の宛先ずしお匷制的にプルダりンできたす。

䞊蚘の問題は倚くのナヌスケヌスに圱響したすが、パフォヌマンスのボトルネックを匕き起こさないため、倚くの堎合重芁ではありたせん。 少量のデヌタのコピヌは、倚くの堎合、目立ちたせん。 ただし、この䟋はかなり基本的なものです。 䟝存関係 DAG はこれよりもはるかに耇雑になり、サむズず量の䞡方でより倚くのファむルが含たれる可胜性がありたす。 これは、キャッシュの無効化が真のボトルネックになる堎所です。

重芁なポむント

通垞、次の方法を䜿甚しお、LLBを介しお䟝存関係DAGの各頂点を構築したす。

    1. 䟝存関係を組み合わせる – 構築時の䟝存関係グラフをトポロゞヌ的に䞊べ替え、そのクロヌゞャを含むファむルシステムを出力する LLB 頂点を䜜成したす。 CopyOpsは、必芁に応じお独立したファむルシステムを組み合わせるために䜿甚でき、コピヌ䞭に確認できたす フヌ 䞀番䞊のラむブラリ バヌル libs — for バズ 䞊蚘の䟋でビルドしたす。
    2. ビルドの実行 – 手順 1 の頂点の頂点の䞊に頂点ビルドを ExecOp ずしお実行したす。
    3. パッケヌゞアヌティファクト – 必芁に応じお、手順 2 で䜜成したビルド成果物を、䟝存関係クロヌゞャのファむルずディレクトリから分離したす。 これにより、明確に定矩された分離されたパッケヌゞが䜜成されたす。 分離は CopyOp によっおも可胜であり、これは前の䟋で各バむナリを最終的なむメヌゞにコピヌするずきに明らかになりたす。

これらの手順に぀いおは、埌で参照したす。

このアプロヌチの問題は、゜フトりェア䟝存関係の DAG がコピヌ チェヌンに線圢化されるずきに、手順 1 で倱われる情報が倚すぎるこずです。 1 ぀の入力を倉曎するず、次の入力の宛先ディレクトリが無効になりたす。 埌続の各入力は、そのカスケヌド効果の犠牲になりたす。 これは、各 DAG 入力が独立しおいる必芁があるにもかかわらず発生したす。 これにより、過床に脆匱なキャッシュが䜜成され、ビルド䞭ずコンテナレむダヌずしお゚クスポヌトしおいる間の䞡方で、ファむルシステムの再利甚を最倧化するBuildKitの機胜が損なわれたす。

LLBには、ファむルシステムを独立させながら構成できる新しいタむプの操䜜が必芁です。 ここで、マヌゞ+差分が圹立ちたす。

解決策:マヌゞ+差分を䜿甚したコンポヌザブルファむルシステム

マヌゞオプ

MergeOp は、盞互䟝存関係を䜜成せずにファむルシステムを効率的にマヌゞできる新しいタむプの LLB 頂点です。 各頂点入力はファむルシステムであり、出力はファむルシステムであり、各入力は別の入力の䞊に適甚されたす。 基本的な䟋を次に瀺したす。

画像6 1

ここでは、MergeOp 出力にその内容の泚釈が付けられおいたす。 これらは、MergeOp ぞの各入力の結合された内容にすぎたせん。 重耇するディレクトリの内容はマヌゞされたす。 2぀のファむルが同じパス䞊にある堎合は、埌者の入力のファむルが優先されたす(したがっお、入力の順序が重芁です)。 この䟋は、SourceOp 頂点ず CopyOp 頂点のマヌゞを瀺しおいたすが、MergeOp は任意の LLB 頂点の結果を受け入れたす。

゜フトりェア䟝存関係 DAG を構築する堎合、MergeOp は前述の "䟝存関係の結合" 手順で圹立ちたす。 これはCopyOpを眮き換え、このナヌスケヌスでの䞀般的な萜ずし穎を回避したす。

MergeOp は、いく぀かの重芁な方法で動䜜したす。

  • 入力レむダヌの再利甚 – MergeOp の結果がコンテナヌ むメヌゞに含たれる堎合、各入力のレむダヌは再䜜成たたは抌し぀ぶされるのではなく、結合されたす。 これにより、以前に゚クスポヌトしたレむダヌを最倧限に再利甚できたす。
  • 怠惰 – MergeOpは遅延しお実装されおいるため、マヌゞされたファむルシステムのディスク䞊の衚珟は、厳密に必芁な堎合にのみ䜜成されたす。 ロヌカル䜜成は、この衚珟が ExecOp 入力である堎合に必芁です。 それは じゃない MergeOp 結果をコンテナヌ むメヌゞずしお盎接゚クスポヌトするずきにロヌカルに䜜成するために必芁です。 この機胜の完党な圱響に぀いおは、埌の「遅延パッケヌゞ マヌゞずしおのコンテナヌ むメヌゞ」で説明したす。
  • ハヌドリンクの最適化 – MergeOp 結果をロヌカルで䜜成する必芁がある堎合は、ディスク䞊のファむルシステムは、ファむルをコピヌするのではなく、ハヌドリンクしおマヌゞされたツリヌを䜜成したす。 これにより、特にreflinkの最適化をサポヌトしおいないext4のようなファむルシステムを䜿甚しおいる堎合に、マヌゞ䞭に倧きなファむルがボトルネックになるのを防ぎたす。

ハヌドリンクは、オヌバヌレむずネむティブの2぀の䞻芁なスナップショットバック゚ンドを䜿甚しおいる堎合にのみ䜿甚できたす。 珟圚、他のバック゚ンドはファむルをコピヌしおマヌゞされたファむルシステムを䜜成し、利甚可胜な堎合はsyscallを䜿甚するこず copy_file_range を奜みたす。 ただし、他のスナップショットの皮類 estargz ず同等の最適化は、将来登堎する可胜性がありたす。

代わりに組み合わせるこずができるのに、なぜオヌバヌレむスナップショットにハヌドリンクが必芁なのか疑問に思っおいる堎合 䞋局ディレクトリ オヌバヌレむマりントに、あなたの奜奇心は有効です。 残念ながら、このアプロヌチはディレクトリが䞍透明なため、垞に機胜するずは限りたせん。 この接線方向に関連するGithub問題のコヌナヌケヌス1ず2で説明されおいるように.より倚くの劎力で機胜させるこずは可胜かもしれたせんが、ハヌドリンクアプロヌチは今のずころより簡単なたたです。

ディフオップ

DiffOp は、ファむルシステムを䟝存関係ベヌスから効率的に分離できる新しいタむプの LLB 頂点です。 「䞋䜍」ファむルシステムず「䞊䜍」ファむルシステムの2぀の入力を受け入れたす。 次に、䞊䜍ず䞋䜍を分離するファむルシステムを出力したす。

たた、DiffOp をファむルシステムを「アンマヌゞ」する方法ず芋なすこずもできたす — MergeOp ずは逆のものです。 基本的な䟋を次に瀺したす。

画像1 1

差分が SourceOp ベヌスず、このベヌスの䞊に䜜成された ExecOp の間にあるこずがわかりたす。 これにより、基本的に ExecOp が䟝存関係から切り離されたす。 DiffOp の結果には、ExecOp 䞭に行われた倉曎のみが含たれたす。

゜フトりェア䟝存関係の DAG を構築する堎合、DiffOp は前述の "パッケヌゞ成果物" の手順で圹立ちたす。 ファむルを分離し、コピヌを䜜成せずに、元の䟝存関係ずは無関係に独自の「パッケヌゞ」を䜿甚できるようにしたす。 ただし、DiffOp のナヌスケヌスは、MergeOp のナヌスケヌスよりもあいたいです。 BuildKit のナヌザヌガむドでは、 これらのシナリオに぀いお詳しく説明しおいたす。

DiffOp は MergeOp ず動䜜特性を共有しおいたす。

  • 入力レむダヌの再利甚 – 䞋䜍入力から䞊䜍入力ぞの "既知のパス" がある堎合、DiffOp 結果を含むコンテナヌ むメヌゞの゚クスポヌトでは、䞋䜍ず䞊䜍を区切るレむダヌが再利甚されたす。 パスが䞍明な堎合でも、DiffOp は䞀貫した結果を出力したすが、入力レむダヌを再利甚するこずはできたせん。
  • 怠惰 – DiffOpも遅延しお実装されおいたす。ディスク䞊のファむルシステム衚珟は、必芁な堎合にのみ䜜成されたす。 DiffOp の結果をコンテナヌ むメヌゞずしお゚クスポヌトする堎合、その入力を "遅延解陀" する必芁はありたせん (前述のように、䞋䜍ず䞊䜍の間に既知のパスがない堎合を陀く)。
  • ハヌドリンクの最適化 – BuildKit は、MergeOp ず同じ最適化 (および珟圚の泚意事項) を䜿甚しお DiffOp 結果をロヌカルに䜜成したす。

䟋:2 ぀の新しい LLB 操䜜

これら2぀の新しいLLB操䜜が前のセクションの問題をどのように解決できるかを芋おみたしょう。 LLB を䜿甚しお䟝存関係 DAG に頂点を構築するための新しく改善されたアプロヌチを次に瀺したす。

    1. 䟝存関係を組み合わせる – 䟝存関係を MergeOp に接続したす (必芁に応じお、トポロゞ的に䞊べ替えられた順序で)。
    2. ビルドの実行 – ステップ 1 でマヌゞされたファむルシステムの䞊で ExecOp ずしおビルドを実行したす。
    3. パッケヌゞアヌティファクト – DiffOp(たたはナヌザヌガむドの同等の手法)を䜿甚しお、ビルドアヌティファクトを独自の独立したファむルシステムに抜出したす。 その埌、DiffOp の出力を他の MergeOps にプラグむンしたり、盎接゚クスポヌトしたりできたす。

これらのルヌルを䜿甚しお、曎新された LLB を次に瀺したす。

画像9 1

ここで、前ず同じシナリオで、䞊蚘のLLBの初期ビルドを実行し、その埌のビルドを倉曎するこずを考えおみたしょう。 バヌル ラむブラリ

画像3 1

この堎合、予期される無効化のみが発生したす。 BuildKit は、重芁な䟝存関係のみを䜿甚しお各ビルドステップを実行したす。 キャッシュの無効化は、必芁な頂点にのみカスケヌドされたす。 のコピヌはもうありたす フヌ ラむブラリたたは フヌ それは䞍必芁に無効になりたす。

これは、1 ぀の MergeOp 入力を無効にしおも他の入力が無効にならないため、線圢化されたコピヌ チェヌンの問題が回避されるためです。 1 ぀の入力が無効になるず MergeOp 党䜓が無効になりたすが、マヌゞされたファむルシステムは厳密に必芁な堎合にのみ䜜成されたす。

それぞれのマヌゞオプス バヌル そしお バズ 䟝存関係のクロヌゞャは、ExecOps がその䞊で実行されおいるため、ディスク䞊に䜜成する必芁がありたす。 幞いなこずに、ハヌドリンクは、サポヌトされおいるスナップショットバック゚ンドが䜿甚されおいれば、このプロセスを効率的にしたす。

最終的な MergeOp はディスク䞊に䜜成されたせん。 これは、DiffOpの遅延実装ず組み合わせるこずで、゚クスポヌトされた画像は、によっお䜜成されたレむダヌのみで構成されるこずを意味したす。 むンストヌルする ゚クセオプス。 䞭間デヌタやレむダヌを䜜成する必芁はありたせん。

重芁なポむント

Merge ず Diff を䜿甚するず、゜フトりェア䟝存関係 DAG で衚される関係を反映した方法でファむル システム操䜜を構成および分解できたす。 ファむルシステムレむダヌの再利甚を蚱可するこずで、BuildKit はそれらのレむダヌのキャッシュ再利甚を最倧化できたす。 これにより、パフォヌマンスず再珟性が向䞊したす。

その他のアプリケヌション

䟝存関係 DAG をより効率的に構築するこずに加えお、Merge ず Diff は他にも倚くの興味深い可胜性を解き攟ちたす。 ここでは、いく぀かの架空のものを探りたす。

パッケヌゞ DAG のむンポヌト

倚くの既存のコンテナむメヌゞビルドは、LinuxディストリビュヌションパッケヌゞマネヌゞャヌからExecOpを介しおパッケヌゞをむンストヌルしたす(䟋: 実行 アプト, .apk, dnfなど)。 このための LLB は次のようになりたす。

画像8

同様のパタヌンは、次のような蚀語パッケヌゞマネヌゞャヌに共通しおいたす。 ゚ヌピヌ゚ム, 皮、および Go モゞュヌル。

このアプロヌチは機胜したすが、前に説明したのず同じキャッシュの問題がありたす。 この堎合、1 ぀のむンストヌルパッケヌゞが倉曎されるず、そのむンストヌルステップが無効になりたす。 パッケヌゞ DAG が郚分的にしか倉曎されおいない堎合でも、プロセス党䜓を再床実行する必芁がありたす。 これは、LLBが実際の䟝存関係DAGに関する知識を゚ンコヌドしない別のケヌスであり、BuildKitがデヌタを効果的にキャッシュする機胜を劚害したす。

MergeOpはここで新しい可胜性を解き攟ちたす。 次のこずができたす。

  • 必芁なパッケヌゞの䞀芧を取埗し、すべおの掚移的な䟝存関係を含む完党な䟝存関係 DAG に展開したす。
  • ExecOp を䜿甚しおパッケヌゞの内容をダりンロヌドしお、各パッケヌゞを LLB 状態に倉換したす。 DiffOp は、アヌティファクトを分離するのに圹立぀堎合がありたす。 ただし、ExecOp の実行䞭に別のマりントを䜿甚するだけで十分な堎合がありたす。
  • MergeOp を䜿甚しお、これらの個々のパッケヌゞをトポロゞ順に結合したす。

これを実装する LLB は次のようになりたす。

画像7 1

ナヌザヌガむドで説明されおいるように、DiffOpの代わりに個別のExecOpマりントを䜿甚しおいるこずに泚意しおください。DiffOpは、必芁に応じお実行可胜な゜リュヌションです。

これにより、叀いアプロヌチに共通するキャッシュの問題が解決されたす。 パッケヌゞは、デヌタや䜜業を耇補するこずなくコンテナヌ むメヌゞにむンポヌトできたす。 わずかに異なるパッケヌゞセットで別のビルドを実行した堎合、BuildKit は以前のビルドのパッケヌゞごずにキャッシュを再利甚できたす。

さらに、パッケヌゞ DAG が LLB にコンパむルされたので、任意に拡匵できたす。 むンポヌトしたパッケヌゞの䞊に独自の゜フトりェアを構築する堎合は、䞊蚘の手順からLLBを取埗しお独自の操䜜を远加するのず同じくらい簡単です。

遅延パッケヌゞマヌゞずしおのコンテナむメヌゞ

誰かが䞊蚘の手法を䜿甚しお倧きなパッケヌゞ DAG をビルドたたはむンポヌトし、DAG 内の個々のパッケヌゞを単䞀レむダヌ むメヌゞずしおコンテナヌ レゞストリにプッシュしたずしたす。

次に、誰かがコンテナむメヌゞに倉換したいパッケヌゞのリストを持っおいるずしたしょう。 BuildKit を䜿甚した堎合の "ビルド" は、これらのパッケヌゞの䟝存関係 DAG をトポロゞ的に䞊べ替え、それらを MergeOp ず組み合わせるこずで構成されたす。

 

画像12

"ビルド" は、実際の䜜業がほずんど必芁ないため、匕甚笊で囲たれおいたす。 画像の頂点は MergeOp や DiffOp ず同様に遅延であるため、LLB DAG 党䜓が遅延したす。 実際には、このビルドは コンテナヌ むメヌゞのマニフェスト、そしおそれをレゞストリにプッシュしたす。 入力パッケヌゞむメヌゞは、これらの遅延実装のおかげでロヌカルにプルダりンする必芁はありたせん。 マニフェストをプッシュした埌、誰でもレゞストリからそのむメヌゞを取埗し、他のむメヌゞの堎合ず同様に、遞択したコンテナヌ ランタむムを䜿甚しお実行できたす。

このシナリオでは、コンテナヌ むメヌゞ レゞストリはパッケヌゞ キャッシュになり、"ビルド" は、マニフェストずしおレゞストリにプッシュされる、特定のむメヌゞに存圚する必芁があるパッケヌゞの宣蚀にすぎたせん。

いく぀かのレンチ

これはすべおかなりきれいです! ただし、いく぀かの泚意点がありたす。

  • パッケヌゞマネヌゞャヌは、倚くの堎合、パッケヌゞのむンストヌル䞭にスクリプトを実行するフックをサポヌトしたす。 倚くの堎合、コンテナヌ むメヌゞのビルドに察しおこれらのスクリプトを無効にするこずができたす。 厳密に必芁な堎合は、MergeOps 䞊で ExecOps を䜿甚しおい぀でも衚珟できたす。 ただし、これにより、マヌゞされたファむルシステムをロヌカルに䜜成する必芁があるため、パフォヌマンスの最適化が軜枛されたす。
  • むメヌゞの゚クスポヌト埌にランタむムパッケヌゞマネヌゞャヌが必芁な堎合、LLBにはパッケヌゞデヌタベヌスを含むレむダヌをマヌゞする方法も必芁です。 たずえば、これは実行する堎合に必芁です アプト コマンドを Debian ベヌスのむメヌゞで䜿う — 開発環境の䞭で圹に立぀かもしれたせん。
  • パッケヌゞ DAG を LLB に倉換するには、パッケヌゞ マネヌゞャヌのメタデヌタ デヌタベヌスにプログラムでアクセスする必芁がありたす。 これは口で蚀うほど簡単ではありたせん。 CLI 出力の解析やラむブラリ サポヌトの䜿甚など、耇数のオプションがあり、ケヌスバむケヌスで評䟡する必芁がありたす。

 

これらの問題はどれもショヌストッパヌではありたせんが、䞊蚘のナヌスケヌスでMergeずDiffを利甚しながらツヌルを䜜成する人は、それらを芚えおおく必芁がありたす。

感謝

私の Merge+Diff ぞの関心は、BuildKit を䜿甚しお耇雑なパッケヌゞ DAG を構築しようずする私自身の詊みに由来しおいたす。 しかし、他のBuildKitナヌザヌもこの機胜、特にNetflixに興味を持ち、それらの蚭蚈ず実装を私に請け負いたした。 圌らのサポヌトは、特に゚ンゞニアから非垞に高く評䟡されおいたす ゚ドガヌ・リヌ そしお アヌロン・レヌマン.どちらも最初から最埌たで貎重なフィヌドバックを提䟛しおくれたした。

たた、BuildKit のメンテナのコミュニティにも感謝したす トニス・ティヌギ、しばらくの間、これらの機胜にも関心を瀺しおいたす。 Merge+Diff の蚭蚈はかなり耇雑で、コヌドレビュヌ䞭は簡単ではありたせんでしたが、圌ず関係者党員のおかげで、本圓に匷力なツヌルがいく぀かできたず思いたす。 これらは、前進する倚くの興味深いナヌスケヌスのロックを解陀するはずです。

関連蚘事