写し
こんにちは、このセッションでは、高度なビルドのトピックについて詳しく説明します。 フォーカスエリアは基本的に、Dockerfileと実際にビルドされたイメージの間のすべてであり、ビルド中に実際に何が起こるかに焦点を当てています。 どのようなツールが関係していますか? ビルドパフォーマンスを最大化するにはどうすればよいでしょうか? どのようなオプションがありますか? 繰り返しになりますが、Dockerfile と実際にビルドされたイメージの間のすべてです。 そのために、私たちはこのアジェンダに従います。 まず、イメージビルダーから始めて、コンテキストについて少しお話しします。 ここでは、マルチアーキテクチャイメージやキャッシュ管理など、buildxに付属する高度な機能の一部について説明します。 また、Docker Bakeなど、この分野での新たな開発についてもお話しします。 また、DockerでDockerを使用したくない場合や時期については、DockerでDockerについて心配する必要がないようにする他のツールについて説明します。
目次
- イメージビルダーとコンテキスト (0:52)
- buildx の使用 (6:54)
- マルチアーキテクチャビルド (13:22)
- キャッシュ管理 (19:37)
- ベイクでビルド (24:19)
- Docker in Docker (DinD) (27:00)
- 詳細情報
イメージビルダーとコンテキスト (0:52)
まず、イメージビルダーとコンテキストについてお話ししましょう。 繰り返しになりますが、実際にDockerビルドコマンドでEnterキーを押すとどうなりますか? さて、レガシービルダーについて少し情報を提供することから始めることが重要です。 基本的に、私たちはどこから来たのでしょうか? これは、Docker エンジンに含まれていた元のビルダーです。 そのため、Docker buildを実行すると、このレガシービルダーが使用されました。 さて、ほとんどの場合、Dockerfileのスクリプトに従って、1つの命令から次の命令へ、そして次の命令へとイメージを生成するだけでした。 しかし、それはかなり基本的なことでもありました。 マルチステージビルドの非常に基本的なサポートがありました。 そしてまた、一歩一歩読んでいたので、すべての指示と順番を読み取りました。 そして、それは基本的に、多段階ビルドの目標に到達するまでそれを行いました。 したがって、複数のステージがある場合、最終ビルドにさえ必要なかった中間ステージが構築される可能性さえあります。 しかし、繰り返しになりますが、それは従来のビルダーの限界の一部にすぎませんでした。 また、従来のビルダーでは、マルチアーキテクチャのイメージを実行することもできません。 したがって、AMD 64を武装させる必要がある場合、それはできませんでした。 ここでも、非常にシーケンシャルな展開でした。 これがDockerファイルです。 これがスクリプトです。 次に、イメージをビルドします。
そのため、 2017年頃、つまりかなり前のことですが、新しい取り組みとBuildKitという新しいオープンソースプロジェクトがまとめられました。 そして、BuildKitは、これらの問題の多くを置き換えて修正するように設計されています。 そして、その仕組みは、結局のところ、非常に低レベルのビルド定義形式であるということです。 基本的には、ステップ、ノード、実行、設定など、すべてのグラフがまとめられています。 これにより、最終出力を構築するための実行プランを作成できます。 つまり、以前はビルドが順次にしか進めなかったのが、今ではビルドを並行して実行できるようになったのです。 また、これは非常に低レベルのツールであるため、BuildKit を直接操作することはほとんどありません。 ほとんどの場合、BuildKit の上に構築されるツールを操作することになります。 しかし、BuildKitは、キャッシング、分散ワーカー、新しいフロントエンドなどの新機能に対する多くのサポートも提供します。 繰り返しになりますが、従来のビルダーが基本的にビルドして順番に実行していたのに対し、BuildKit はグラフのように考えてください。グラフでは、すべてのステップがグラフ内のノードとして概説されています。
BuildKitを実行するには、どこかで実行する必要があります。 BuildKit をスタンドアロンで実行することもできますが、ほとんどの場合、それを行うことはありません。 Docker DesktopにはBuildKitデーモンが含まれていますが、Docker Desktopにまだ残っているレガシーシステムの一部が引き出されているため、現在いくつかの制限があります。 そのため、たとえば、Docker Desktop に組み込まれている従来のイメージ ストアでは、マルチアーキテクチャ イメージをサポートできません。 したがって、1つのアーキテクチャを構築して保存することしかできませんが、複数のアーキテクチャを処理することはできません。 そのため、組み込みの BuildKit デーモンも同じ制限に縛られます。 そのレガシーイメージストアをcontainerdに移動する努力があり、それによってこれらの問題の多くが解決されます。 また、画像に構成証明を添付することもできます。 たとえば、SBOMやビルドの出所などです。 しかし、その作業はまだ進行中です。
Docker buildx は、通常操作するツールであり、これも BuildKit の上に構築されます。 また、これは BuildKit の多くの機能を公開する CLI コマンドです。 たとえば、BuildKit Builders、マルチアーキテクチャビルドを作成できます。 また、高度なキャッシュ管理やSBOMの来歴作成も処理できます。 Docker Desktop 4.19、 Docker Build は、実際には Docker buildx Build にエイリアスが付けられています。 つまり、実際には知らず知らずのうちにBuildKitを使用していたかもしれませんが、それでもDockerドライバーを使用していたのは、これについては数分後ほどお話しします。 そして、このDockerドライバーは、基本的にエクスポート、イメージを取得し、レガシーイメージストアで動作するように作成していました。 そして、ここではドライバーについてもう少し詳しく説明します。 さて、buildxが提供する他のものの1つは、リモートビルダーを使用する機能です。 そのため、ローカルの BuildKit やローカル マシン上のものを使用する必要さえありません。 そのために、Dockerコンテキストと呼ばれるものを活用します。 Docker のコンテキストとコンテキストは、ビルドだけの範囲を超えています。 しかし、コンテキストにより、基本的にローカル CLI は他のエンジンに対して動作できます。 結局のところ、Docker CLI は、Docker エンジンによって公開されるエンジンと対話している REST クライアントにすぎません。 そして、そのエンジンはローカルでもリモートでもかまいません。 そのため、デフォルトのコンテキストは、ローカルマシンにあるエンジンを使用するだけです。 ただし、他のマシンを指すコンテキストを作成することはできます。
たとえば、Docker context create は新しいコンテキストを作成し、コンテキストをリストアウトしたり、新しいコンテキストを使用したりできます。 そして、ここでの2つの例は、最初のものはコンテキストを作成し、SSHの例と名付けます。これはDockerコンテキストであり、リモートマシンに接続する方法は次のとおりです。 この場合、SSH を使用します。 2 番目の例は TLS の例で、TLS エンドポイントを介してエンジン API を公開している Docker エンジンと対話します。 この場合、証明書ベースの認証を行っているため、CA証明書、秘密鍵などの詳細は次のとおりです。 ここでも、デフォルトのコンテキストはローカルのDockerエンジンを指しており、たとえばSSHコンテキストを使用してコマンドを使用し始めると、ローカルエンジンをクエリする代わりに、リモートマシン上のエンジンをクエリします。 ただし、その前に、実際にはそのマシンにSSH接続し、エンジンにクエリを実行してから結果を送り返しますが、ローカルCLIには引き続き表示されます。 そのため、実際にはリモートでマシンにSSH接続しているにもかかわらず、ローカルであるように感じられます。 TLS の例は、構成されている証明書を使用して、このリモート マシンに直接公開されている API と通信するだけです。 さて、ここでの背景は少しです。
buildx の使用 (6:54)
さて、buildXは、それに付随するいくつかのより深い例と機能ですが、buildxを使用すると、さまざまなBuildKitデーモンを作成できます。 先ほど述べたように、Docker Desktopにバンドルされているものは、現在、Docker Desktopが従来のイメージストアなどに対して持っている制限に縛られています。 しかし、別のビルダーを作成し、基本的にはコンテナ内で実行しているだけの状態で配置することができます。 そして、そのビルダーは、BuildKitデーモンのすべての機能セットを持つことができます。 そのため、マルチアーキテクチャビルド、SBOMなどを実行できます。 したがって、たとえば、Docker buildx createを実行し、プラットフォームを指定できます。 この場合、2つのプラットフォームです。 これにより、マルチアーキテクチャのビルダーが作成され、生成された名前が使用されます。 また、このビルダーは、複数のアーキテクチャのビルドを実行できるようになります。 現在、非ネイティブアーキテクチャでは、QEMUエミュレーションを使用するだけです。 したがって、ネイティブの速度で実行されることは決してありません。 しかし、他のアーキテクチャを使用してビルドを行うことはできます。 ビルダーをリストアップすることもでき、このビルダーを使用したいと言うこともでき、それを将来のビルドのデフォルトビルダーとして設定します。
さて、前に述べたように、私が使用できる他のドライバーがあります。 そして、これらのドライバーは、バックエンドでのBuildKitの動作を少し変えます。 そのため、前述したように、Docker ドライバーは BuildKit ライブラリ、つまり Docker デーモンにバンドルされている BuildKit デーモン、つまり Docker デスクトップにバンドルされているデーモンを使用します。 また、イメージをエクスポートして、Docker デスクトップにバンドルされているイメージ ストアに保存します。 Docker コンテナ ドライバーは、コンテナ内で BuildKit を実行するドライバーです。 Kubernetesでは、BuildKitポッドとKubernetesクラスターを作成します。 ですから、ビルドを行うたびに、基本的に何かを起動し、Kubernetesクラスタで新しいポッドを起動します。 また、リモートを使用すると、リモートビルダーにも接続できます。 また、スライドの下部に特徴量マトリックスの種類と、それぞれに付随するさまざまな機能を確認できます。 また、Docker ドライバーの機能は少ないですが、イメージを自動的にイメージ ストアに読み込み直し、構成証明のない 1 つのアーキテクチャなどであることがわかります。 これで、これらの他の画像もロードできます。 ビルドを行うときに指定するだけです。
さて、これをうまくエクスポートするために、私ができることがいくつかあります。 そして、これは実際には一種の優れた機能の一部です。 通常、Dockerビルドを行うときは、イメージをビルドしてイメージストアに保存します。 しかし、これにより、ビルドで他のことができる他の機会がいくつか開かれます。 たぶん、ビルドを行いたいと思っていて、実際にイメージをtarballとして保存したい場合はどうでしょうか。このビルドを取得し、USBドライブに入れてエアギャップネットワークに移動し、そこにイメージをロードするからです。 OCIエクスポーターを使用して、OCIイメージレイアウト形式でローカルファイルシステムにエクスポートできます。 そして、これは実際にそれを拡大します。 たぶん、私もtarballをやりたいのでしょう、動きやすくするために。 しかし、ここでも多くの異なる例があります。 実際、ここでは端末に切り替えて、ここではその一部をデモンストレーションします。
したがって、Dockerビルドを実行して出力を行う場合、type=oci、そしてそれをここでtarにエクスポートするだけです。 これにより、ビルドがトリガーされ、ここで実際にクラウドビルダーを使用していることがわかります。 これはDocker Build Cloudからのもので、ここですぐに説明します。 そして、このビルドをここで実行した後、非常に単純なReactアプリケーションを構築しているだけです。 ビルドが完了すると、tarball が送られることがわかります。 そして、実際には画像として保存していませんが、ここでoci-export.tarを見ることができます。 そして、新しいディレクトリを作成しましょう。 そして、そのタールをここにコピーして、それを拡張しましょう。 JQを使ってみよう。 それに付随するマニフェストと、すべての個々のレイヤーのすべてのブロブなども表示されます。 したがって、繰り返しになりますが、OCI形式のtarballとしてエクスポートされます。 さて、ここでも私にできることは他にもあります。 したがって、このDockerfile(デフォルトのもの)は、このReactアプリケーションをビルドしてnginxコンテナに入れます。 しかし、何らかの理由で、nginxコンテナに入れる代わりに、nginxコンテナにコピーしているこのビルドの結果をエクスポートしたいだけかもしれません。 しかし、ファイルシステムに載せたいだけの場合はどうでしょうか? デプロイプロセスが違うかもしれないし、Dockerを使ってビルドしたいけど、実際には静的なHTMLアセットなので、S3 バケットに入れてCloudFrontCDNで配布するつもりだからです。まあ、それはできます。 それでは、他のDockerfileを指定しましょう。 出力type=localを使用します。 エクスポートというローカルフォルダとして宛先を設定します。 そして今、これが実行されると、コンテキストの再アップロードにはOCI出力が含まれるため、すべてをアップロードするのに少し時間がかかりました。 しかし、この場合、クライアントディレクトリにエクスポートされていることがわかります。 約 151 キロバイトをコピーしました。 そして今、エクスポートディレクトリを見ると、そこにビルドされた出力が表示されます。 そして、それは私のReactアプリからの私のindex.htmlだけでなく、他のJavaScriptとCSSのアセットも得ています。 したがって、繰り返しになりますが、これらのエクスポーターを使用すると、ビルドの出力を変更できます。 そしてまた、そのDockerfileがどのように見えるかを示すために、この場合、私はゼロから始めました。 そして、前の段階から保持したかったファイルを取得しています。 そして、ここではそれらをファイルシステムのルートに置いています。 つまり、ルートにあるすべてのファイルも、そのローカルディレクトリにエクスポートされるときも同じファイルシステム構造に従います。 繰り返しになりますが、さまざまなニーズに応じて活用できるさまざまな輸出業者がかなりあります。
マルチアーキテクチャビルド (13:22)
では、マルチアーキテクチャ ビルドについて少しお話ししましょう。 では、マルチアーキテクチャビルドはなぜ重要なのでしょうか? なぜ必要なのですか? 私たちはそれらからどのような価値を得ているのでしょうか? そして、ここでの答えは、明らかにあなたの組織に大きく依存します。 しかし、最初にバイナリ、つまり 0 と 1 について考えると、それらは特定の CPU アーキテクチャにエンコードされます。 また、すべてのCPUアーキテクチャには異なる命令セットがあります。 たとえば、ARMはAMDなどとは命令セットが大きく異なります。 また、オペレーティングシステムも異なります。 したがって、WindowsとLinuxでは、バイナリは大きく異なります。 ですから、文字通り1つの画像を撮って、1回作ればどこでも遊べるわけではありません。 このアプリケーションを実行するさまざまな CPU アーキテクチャとオペレーティング システムごとに、そのイメージを作成する必要があります。 現在、多くの開発者は、特にAppleのラップトップで、ARMベースのマシンを使用するようますますシフトしており、それらの多くはARMベースのAppleシリコンマシンを使用しています。 しかし、より多くのWindowsマシンがフリートに参入し始めているのも見られます。 そして、それらの多くはARMベースでもあります。 そのため、開発者のワークステーションにはさまざまな環境が混在するケースが見られます。 アプリケーションがデプロイされると、多くの人々がクラウドでARMベースのマシンを使用し始めます。これは、エネルギー効率が高く、実行コストも低いためです。 ですから、その収益は重要です。 ですから、ARMベースのイメージを簡単に構築する方法があり、インフラストラクチャのコストを節約することができるようになったとしたら、なおさらです。 そして最後に、マルチアーキテクチャイメージは選択肢を提供します。 もちろん、ここではMacで走っています。 私のマシンはAMD 64 イメージを実行できます。 しかし、もちろん、ネイティブの速度で走るわけではなく、パフォーマンスの低下も伴います。 さて、その同じイメージが複数のアーキテクチャで利用可能であった場合、私には選択肢があり、それは私にとってより適切に機能します。 また、他のダウンストリームユーザーが引っ張るソフトウェアを作成している組織であれば、繰り返しになりますが、彼らにも選択肢が与えられます。
繰り返しになりますが、人々がマルチアーキテクチャをやりたい理由はたくさんあります。 さて、そのビルドを行う方法があります。 ビルトインされたBuildKitは、QEMUを使用して非ネイティブアーキテクチャをエミュレートします。 したがって、この例では、docker buildx createを実行してビルダーを作成し、プラットフォームを指定します。 そして、このビルドが実行されると、ネイティブアーキテクチャがネイティブ速度で実行されるものはすべて使用されますが、非ネイティブアーキテクチャはQEMUエミュレーションを使用します。 繰り返しになりますが、うまくいくのですが、かなり遅いことが多いのです。 また、CIパイプラインでは、ジョブが単一のパイプラインで実行されている可能性があるため、これは明らかに単一のアーキテクチャにバインドされているため、これによく遭遇します。 しかし、私は複数のアーキテクチャ用に構築したいと考えています。 それについては、ここですぐにお話しします。 繰り返しになりますが、QEMUエミュレーションが組み込まれています。 最高ではありませんが、そこにはあります。
もう少しDIYのアプローチをしたい人のために、ネイティブのマルチアーキテクチャビルドを行う方法があります。 そのため、この一部は、前に説明したDockerコンテキストを活用することになります。 したがって、この場合は、ARMベースのマシンを指すarm-machineというコンテキストを作成します。 そして、SSHを使用して接続します。 次に、ARM64 プラットフォームの場合、この特定のビルドにARMマシンコンテキストを使用するというビルダーを作成します。 次にできることは、基本的にこのビルダーに別のノードを追加して、つまり、別のアーキテクチャ、デフォルトを使用することです。 したがって、この場合、この特定のマシンはAMDの64 マシンである可能性があります。 したがって、このマルチアーキテクチャビルドを今すぐ行うと、AMD64 ビルドはローカルマシンに委任されますが、ARMのビルド64 リモートマシンに委任されます。 そして、BuildKitはあなたのためにそれをすべて面倒見ます。 さて、繰り返しになりますが、これを設定することもできますし、自分で実行することもできますが、複雑です。 そしてもちろん、今ではこれらすべての異なる機械やビルダーなどを維持する必要があります。 しかし、私はここにDocker Build Cloudのプラグを置きたいだけです。 Docker Build Cloudでは、クラウドで実行されるこれらのマネージドビルダーを利用できます。 また、ネイティブのマルチアーキテクチャサポートが付属しています。 そのため、セットアップは不要で、マシンやさまざまなコンテキストの異なるノードを管理する必要もありません。 とても簡単です。
マルチアーキテクチャビルドに付属する高度なDockerfileサポートについて話しましょう。 あなたができるクールなことの1つは、さまざまなステージのそれぞれで、このステージを実行するプラットフォームを実際に指定できることです。 たとえば、この特定のビルドでは、AMD64 と ARM64というマルチアーキテクチャ ビルドを行いますが、この React アプリでは、最終的なアセット、HTML、CSS、JavaScript はプラットフォームに依存しません。 では、静的アセットがある場合に、ARM マシンと AMD64 マシンで HTML、CSS、JavaScript を実際にビルドすることは本当に理にかなっていますか? これらの資産も、プラットフォームに依存していません。 したがって、この場合、私たちが言えることは、ネイティブビルドプラットフォームを使用してこのビルドを実際に実行するだけだということです。 しかし、最終段階では、実際には、ターゲットプラットフォームを行います。 つまり、最終的に行われるのは、ビルドステージがネイティブアーキテクチャで実行されているようなことです。 繰り返しになりますが、実行するのは一度だけです。 ただし、最終ステージは最終ターゲットプラットフォームごとに1回実行されます。 これは、プラットフォームに依存しないアセットにとって非常に強力です。 したがって、この場合、最終的なjarファイルまたはファイルがプラットフォームに依存しないReactアプリまたはJavaアプリケーションです。 また、ネイティブビルドプラットフォームを使用してビルドを行うことができます。 そして、最終的なターゲットプラットフォームは、ARM用のJDK、AMD64 用のJRE、およびARM64に基づくことができます。 そして、それはうまくいきます。 繰り返しになりますが、これらのプラットフォームフラグでもできる非常にクールなことがいくつかあります。
キャッシュ管理 (19:37)
さて、キャッシュ管理について話しましょう。 そして、おそらくあなたはすでにビルドキャッシュに気づいていると確信しています。 しかし、キャッシュについて考えると、他にもいくつかのことが浮かび上がってきます。 そこで、キャッシュ管理の理由について少しお話ししたいと思います。 まず、ビルダーはビルドキャッシュを使用してビルドを高速化します。 また、ビルドキャッシュを活用できれば、より効果的です。 レイヤーを再利用できるようにDockerfileをオーケストレーションおよびビルドできれば、ビルドが速くなります。 押したり引いたりする必要がないなど、少ないです。 しかし、問題は、これらのキャッシュが、通常、デフォルトではビルダーに対してローカルであることです。 したがって、ここでローカル マシンでビルドすると、チームの他の誰も、私が入力したばかりのキャッシュを活用できません。 または、特に私のCIパイプラインでは、ビルドは一時的な環境で実行されることが多く、CIパイプラインが起動するたびに、以前の実行からの知識やキャッシュがない真新しいマシンのジョブで開始されます。
では、これらのキャッシュをどのように活用できるのでしょうか。 さて、これを自分で行うにはいくつかの方法があります。 また、BuildKit と buildx にはさまざまなキャッシュバックエンドがあります。 たとえば、実際にキャッシュを画像自体に埋め込むようにしたいと言うことができます。 お勧めしませんが、確かにできます。 キャッシュをレジストリにプッシュすると、イメージをプッシュするだけでなく、キャッシュもプッシュする場所として、かなり頻繁に使用されます。 また、キャッシュの検索やすべてが将来も発生するように、追加のマニフェストが含まれています。 ビルド間などで使用されているネットワーク接続ストレージがある場合は、キャッシュをローカルディレクトリに書き込むことができます。 GitHub アクション統合があり、キャッシュは GitHub アクション キャッシュにプッシュされます (S3など)。 さて、ここで言及したい2つの異なるモードがあります。 最初の分は、エクスポートされたレイヤーのみがキャッシュされる、つまり最終ステージのみがキャッシュされるということです。 マルチステージ ビルドを行っている場合、これは前のすべてのステージをキャッチするわけではありません。 そして、それはあなたが望むものかもしれないし、そうでないかもしれません、それはあなたのニーズに依存します。 そして、それがあなたが望むものではない場合、おそらく最大であり、それもすべての中間ステップをキャッチします。 繰り返しになりますが、あなたのニーズによります。 そこにはさまざまなキャッシュモードがあります。
そこで、ここで示す 2 つの例を紹介します。 このキャッシュの例では、これが行うことは通常のビルドを行うことですが、キャッシュ 2 と from はレジストリを使用し、レジストリの場所はこの場合は my-repo/my-cache になることを示しています。 さて、明らかにここではただの作り話です。 ただし、この場合は Docker Hub からプルされます。 独自の内部レジストリから取得する場合は、通常のイメージ名と同じ名前付けパターンに従います。 だから、registry.company.com/my-repo/my-cache。 何と。 この場合、mode=max です。 したがって、繰り返しになりますが、すべての中間ステップがプッシュされます。 そこからキャッシュを使用します。 そして、完了したら、キャッシュをそこにプッシュします。 ここでの別の例は、S3 バケットの使用です。 この例では、キャッシュはレジストリに格納されるのではなく、このリージョンの S3 バケット、このバケット名、バケット内のこのキープレフィックスにも格納されます。 繰り返しになりますが、これを構成するにはさまざまな方法があります。
GitHub Actionsでこれがどのように見えるか – Dockerビルドプッシュアクションを使用している場合、キャッシュのfromとcache toを指定するための追加のフィールドにすぎません。 そして、それはただ差し込むだけです。 ですから、繰り返しになりますが、チャンスがあります。 つまり、これらすべてを自分で管理することは確かにできます。 そして、すべてのガベージコレクションやクリーンアップなどを管理する必要があります。 しかし、繰り返しになりますが、ここには当社の製品の1つであるDocker Build Cloud用の別のプラグをここに置きます。 現在、すべてのビルド間で共有キャッシュがあり、ガベージコレクションが自動的に処理され、すべてのディスクスペースとキャッシュにすべてが費やされないようにします。
そしてまた、これでビルドを実行すると、ここでハブワークフローを取得するためにジャンプしましょう-この特定のビルドはキャッシュを使用していません。 そして、毎回画像レイヤーを引っ張る必要があることがわかります。キャッシュは使用されていません。 そのため、毎回すべての依存関係やすべてをプッシュしたりプルしたりしなければならないことが多く、Docker Build Cloudを使用すると、すべてのイメージがすでにプルされ、レイヤーがさまざまなワークフローにキャッシュされていることがわかります。 繰り返しになりますが、ここで必要な変更は非常に簡単で、非常に最小限に抑えられます。
ベイクでビルド (24:19)
さて、ベイクについて少し話しましょう。 現在、ベイクは私たちが取り組んできた新しいツールであり、かなり洗練されたビルドのニーズを満たすのに役立ちます。 それでは、この複雑なCLIビルドから始めましょう。 さて、誰もがこのようなものを持っているわけではないと思いますが、これにはcache-from、cache-toがあり、マルチアーキテクチャビルドを実行し、さまざまなラベルを指定しています。この場合、実際には複数のタグを持ち、ファイルを指定しているため、デフォルトのDockerファイルを使用していません。 繰り返しになりますが、すべての人のビルドがこのように見えるわけではありませんが、ラベルをたくさん追加するなど、多くのことが見られます。繰り返しになりますが、どうすればこれを簡単にできるのでしょうか? つまり、bakeが行うことは、より高いレベルのツールであり、抽象化、オーケストレーション、フォーマットの宣言、それに使える多くの用語です。 しかし、基本的にはビルドコマンドを体系化し、イメージのさまざまなバリエーションを公開することができます。「このビルドとこのビルドはどうやって行うのか」という疑問があれば、 BuildKitがDockerfile内の個々のステップを並行して実行できるのに対し、Bakeは実際に並列イメージビルドを実行し、それらをリンクして非常に優れたことを行うことができます。 オーケストレーション ファイルを使用し、多くの場合、HCL を使用して表示されます。 そのため、Terraformのように見えますが、明らかに構造が異なりますが、JSONやYAMLで記述することもできます。
そのため、多くの点で、Bake は Compose を実行するようにビルドすると考えることができます。 したがって、この前のCLIコマンドを使用して、このBakeファイルに変換できました。 今、ターゲットを指定すると、出力、キャッシュ、Dockerfile、プラットフォーム、ラベルなどがあります。 そして、ここからdocker buildx bakeを実行するだけで、それが私のために仕事をしてくれます。 そして今、その複雑なCLIコマンドがこのHCLファイルに体系化され、簡単に再現してビルドできるようになりました。 さて、繰り返しになりますが、これはかなり単純な例です。 ここには多くの議論がありますが、実際には 3 つの異なるコンテナイメージをビルドし、それぞれが異なる Docker ファイルを使用し、共有構成から継承する並列実行を開始できます。 繰り返しになりますが、かなり洗練されたことを行うことができますが、ここですべてを教えようとするわけではありませんが、ドキュメントをチェックしてください。 Docker Bakeには、非常に優れた例やドキュメントがたくさんあります。
Docker in Docker (DinD) (27:00)
さて、まとめとして、DockerのDockerについて説明します。 さて、DockerのDockerは厄介なテーマです。 また、特にCIパイプラインでは、Docker Buildを使用している場合、Dockerエンジンが必要になるため、ビルドでよく出てくるものです。 また、多くの CI ジョブはコンテナ内で実行されます。 例えば、JenkinsやGitLabなど、CIパイプラインでは、新しいジョブはすべてポッドとクラスタ、または実行中の別のコンテナであるということを多くの人と話しました。 そのため、そのコンテナがビルドを行うためには、実際にビルドを行うために新しいコンテナを実行する能力が必要です。 したがって、基本的には2つのオプションがあります - 1つは、ホストソケットをそのイメージまたはCIジョブにマウントするか、基本的にネストされたコンテナを実行できるようにするかです。これがDockerのDockerの由来です。 非常に多くのCIジョブがコンテナ内で実行され、これは基本的に、そのCIジョブをサンドボックス化しておきたいのですが、あなたを切り離すことはできませんし、ホスト上で何もできません。 そのため、新しいコンテナを起動できますが、Dockerにはネストされたコンテナ、Dockerが存在する可能性があります。
しかし、そのためには、CIジョブコンテナに追加の権限が必要であり、ネストされた名前空間を作成したり、コンテナを起動したりするための特権モードアクセスが必要になるため、これにはいくつかの課題が伴います。 また、この特権モードは、組織のセキュリティ構成でブロックされている場合があります。また、そこで実行されているマシン上にある可能性のあるLinuxセキュリティモジュールと競合する可能性もあります。 また、ネストされたコンテナを起動しようとすると、ファイルのマウントパスが正確でなく、かなりトリッキーな状況が発生する可能性があるという複雑なファイルシステムの問題に遭遇し始めます。 ですから、ここには2つの選択肢があるのです。 繰り返しになりますが、これを自分で行っている場合、最初にDockerソケットをコンテナにマウントすると、これには非常に大きな警告が伴います。 さて、これはセキュリティギャップと見なすことができます。 したがって、たとえば、これを行う場合、ホストソケットをこのコンテナに共有します。 したがって、そのコンテナ内のコマンドは実際にはホストのエンジン上で動作しているため、そのジョブは「Dockerを実行し、ホストファイルシステム全体を新しいコンテナにマウントし、ホスト上の任意のものにアクセスできるようにしたい」と言うことができます。 繰り返しになりますが、それには十分注意したいところですが、それは選択肢の一つです。 繰り返しになりますが、セキュリティギャップとセキュリティ体制に自分自身が置かれていることを認識してください。 別のオプションはsysboxを使用することであり、ネストされたコンテナを安全に実行できるこの例がいくつかあります。 これにはいくつかのトレードオフがありますが、sysbox を使用してネストされたコンテナを実行できるように設定する方法がありますが、ネストされたコンテナができることとできないことを少し制御したり、たとえば、ルート ファイル システムをマウントできないなどします。 そのため、セットアップは複雑ですが、オプションでもあります。 そして最後に、Docker Build Cloudに移行すると、DockerにDockerは必要なく、あなたの仕事は実際にはリモートビルドのクライアントだけです。 また、ARM マシンと AMD64 マシンの両方のネイティブ サポートを利用できます。 しかし、ここでも、パイプラインで起動しているKubernetesポッドがあり、そのポッドはDocker Build Cloudと通信する能力のみが必要であると想像して、この中間点を非常に難しく打つ必要があります。 ネストされたコンテナを起動したり、実際に何かをしたりする機能は必要ありません。 また、すでに慣れ親しんでいるのと同じツールをすべて使用することができ、Docker Buildだけで魔法が起こります。 また、共有キャッシュや、以前に説明した他のすべてのことを活用する予定です。 繰り返しになりますが、そこには多くの利点があります。それに伴い、ビルドとビルドX、およびマルチアーキテクチャビルドとキャッシュ管理に関して、さまざまなことについて話してきました。 だから、ありがとうと言いたいのです。 ご不明な点がございましたら、お気軽にお問い合わせください。 あなたが顧客であり、さまざまなサポートニーズがある場合は、サポートチケットを自由に送信し、コミュニティSlackやその他の場所でもお気軽にお問い合わせください。 そしていつものように、私たちはあなたに感謝しています。 また、また質問がある場合は、お気軽にお問い合わせください。 ありがとうございました。
さらに詳しく
- ドッカーは初めてですか? 始めましょう。
- 注目のガイドでDocker製品を深く掘り下げます。
- Docker Newsletter を購読してください。
- Docker デスクトップの最新リリースを入手します。
- 質問がありますか? Docker コミュニティがお手伝いします。