ドッカーコン

Docker-in-Docker: コンテナー化された CI ワークフロー

Chris Maki 氏 (プリンシパル ソフトウェア エンジニア、Docker)

Rodny Molina 氏 (プリンシパル ソフトウェア エンジニア、Docker)

2023年11月16日収録
Docker-in-Docker(DinD)は、別のDockerコンテナ内でDockerコンテナを実行する手法です。 DinD を使用すると、CI プラットフォームでテスト対象のアプリケーションまたはサービスごとに分離された環境を簡単に作成できます。 このプレゼンテーションでは、DinDの基本、その利点、およびユースケースについて説明します。

写し

こんにちは。 今日は、コンテナ化されたCIワークフローのコンテキストにおけるDocker-in-Docker(DinD)についてお話しします。 今日は、Docker-in-Dockerを少しでもエキサイティングなものにするために最善を尽くします。

さっそく始めましょう。 これが今日の私たちのアジェンダです。 簡単に紹介します。 次に、Docker-in-Dockerについて説明します。 Docker-in-Dockerをいつ使用するかを説明します。 次に、Docker-in-Dockerの実行方法とそれに関連する課題について説明します。 次に、そのための潜在的な解決策に飛び込みます。 次に、例を挙げてまとめます。

私の名前はロドニー・モリーナです。 私はDockerのソフトウェアエンジニアです。 Dockerの前は、Nestyboxというスタートアップでリード開発者兼共同創業者の1人として働いていました。 Nestyboxはsysboxという時間のコンテナを作成しました。 これについては、後ほど説明します。 この講演の犯罪のパートナーはクリス・マキです。 残念ながら、彼は最後の最後でそれを作ることができませんでした。 では、プレゼンテーションに何か問題がありますか? 好きなものはありますか? どうぞご自由に責めてください。 では、始めましょう。

目次

    Docker-in-Dockerとは?

    Docker-in-Dockerとは? おそらくほとんどの人にとって、Docker-in-Dockerはしばらく前からあるので、あまり紹介する必要はありません。 しかし、私たちが同じページにいることを確認するために、基本的なことだけを説明させてください。 Docker-in-Dockerは、開発者がDockerコンテナ内でDockerコンテナを実行できるようにするためのシンプルな手法です。 それだけです。 したがって、その青いボックスにコンテナだけのプロセスがあり、そのプロセスがタスクである場合、基本的に、Docker-in-Dockerはそのプロセスが動作を完了できるようにする必要があります。

    2番目も同じです。違いはないはずです。 物事が正しく行われていれば、そのボックス内のDockerは外側のDockerと同じように動作するはずです。 これは概念的には理解しやすいです。 では、そもそもなぜこのような話をしているのでしょうか? 実装に関しては、物事は少しトリッキーです。 なぜなら、一番下にあるコンポーネント、つまりコンテナスタックはどれも、Dockerのようなアプリケーションを念頭に置いて設計されていないからです。 それらはすべて、私が研究をしたいという文脈から考え出されたものです。

    Dockerは、カーネルで多くのトリッキーなことを行うため、システムレベルと見なされるアプリケーションの1つです。 通常のアプリケーションが本当に気にする多くのものが必要です。 ですから、次に説明する内容、つまり、構築しなければならないすべての課題と、それらの課題が存在する理由について、その基礎を築いています。

    ユースケース

    さて、ユースケースでは、Docker-in-Dockerはいつ必要ですか? それを見ていきましょう。 最も明白なユースケースは際立っており、ここにいるほとんどの人がCIツールとエージェントに精通していると思います。 おそらく、いくつかのDocker関連のタスクを完了する必要があるジョブを処理する必要がありますよね? ですから、そのエンジンの中、CIツールの中、エージェントの中にエンジンが必要になるのは当然のことです。 このユースケースは非常に明白です。

    しかし、あまり明白ではないのは、この環境のコンテキスト内でローカルのコンテナ化された環境が必要な場合、たとえば、CIワークブックを含むリポジトリで作業している場合、それほど複雑ではありませんが、それほど単純ではありません。 その中間のようなものです。 単純すぎる場合は、内部にDockerエンジンを搭載する必要はありません。 複雑すぎると、その CI ワークフロー環境をローカルの開発マシンに移植することさえできません。 複雑すぎます。 その中間にある場合は、その CI エンジン、またはすべてのツールが既に内部にあるエンジンを持ち込むことができるシナリオを考えることができます。 そのため、ローカルのテストおよび開発環境を、あまり気にしない多くのツールでマシンを乱雑にすることなく実行できます。 これが、入れ子になったデプロイを必要とするローカルのコンテナー化された環境を意味します。 そういうことなんです。

    別のユースケースは、サンドボックス化されたDocker環境です。 これは、開発者がサンドボックス環境として機能するDockerコンテナを作成できる環境です。 シナリオは想像できます。 開発者は、開発環境に必要なすべてのツール (Docker、Kubernetes、開発テスト、GUI など、必要なほとんどすべてのもの) をイメージ内に投入します。 そうすることで、作業中のラップトップを切り離し、実行している他のデバイスに移植できるため、柔軟性と移植性が大幅に向上します。

    このユースケースは、開発者として個人的に目指すところだと思うので、とてもワクワクしています。 自分が納得できる要素をすべて含めたイメージにしたい。 そして、彼らは私が望むようにサイクルを構成しています。 ラップトップを切り替えたり、タブレットに移動したり、会社を変えたりしなければならないのは、私にとっては意味がありません。 その後、意味をなさないことをすべてやり直さなければなりません。 将来的にはこういうのが本当にありたいですね。 これはサンドボックス化されたDocker環境であり、仮想マシンのように動作します。 実はこれが、私が以前取り組んでいたスタートアップの主な原動力なのです。 ユースケースは、少なくとも私の頭の中ではかなり明確です。 続けましょう。

    Docker-in-Dockerの実行

    Docker-in-Dockerを実行するにはどうすればよいですか? まず、Docker-in-Dockerをネストして実行しようとしたときにユーザーが遭遇する課題の非常に簡単なデモから始めましょう。 とても簡単です。 ここでは、私がデプロイ パターンと呼んでいるもののいくつかについて説明します。 これらについては、後で詳しく説明します。 したがって、ここで得られないものがある場合は、辛抱強く、次の数枚のスライドを待ってください。

    さて、一番下で、すべての「dockerps」を見ていきます。 システム内のすべてのコンテナを監視します。 一番上で、Busybox しか持たないコンテナーを初期化します。 そこでDockerを実行してみます。 当然のことながら、それは失敗するでしょう。 したがって、簡単な例は、デフォルトでDockerがどこにも含まれていないことを示すことです。 次に、画像を書き込む必要があります。 どこにも、あなたはそれをインストールする必要はありません。 簡単。

    では、もう少し賢いことをしてみましょう。 Docker CLI イメージではありません。 本当に何かを含めてください。 Docker CLI 自体。 それを実行すると、うまくいきます。 そこにはCLIがあります。 命令である「docker ps」をいくつか行います。 失敗します。 なぜでしょうか。 バイナリがエンジンに接続しようとしているためです。 ここで私が説明しようとしているのは、多くの人にとって明白なことですが、DockerはCLIの2つの要素、つまりエンジンで構成されています。 操作するには両方が必要です。

    したがって、ここにあるDockerバイナリはソケットに接続しようとしています。 Dockerがデフォルトでリッスンしている一意のソケット。 明らかに、Docker CLIのコンテキストでは、エンジンはありません。 エンジンはどこから持ち込めばいいの? エンジンはどこから手に入れたのか? さて、ここからがDockerのDockerパターンが意味をなすところです。 代わりに、それを見ていきましょう。 最初にやろうとすることは、通常のコンテナーを実行することです。 これは実際には適用されません。 これから説明するユースケースでは、あまり意味がありません。 このコンテナーを作成する理由は、Docker out of Docker が抱える主な課題の 1 つを紹介するためです。

    だから、私と一緒に耐えてください。 作成したばかりのコンテナがある下部を見てください。 一番下は、前述したように、Dockerエンジンがホストレベルで実行されるシステムレベルです。 そこで、DockerCLIコンテナを再度初期化します。 この時点で、何かを渡していることに注意してください。 ホストのDockerエンジンがリッスンしているソケットを渡しています。 そのソケットをホストからコンテナにバインドマウントしています。 それは最初から怪しいように聞こえます。

    それに伴う問題は、「docker ps」を実行すると、はい、物事は機能しますが、今はシステムのすべてのコンテナを見ていることです。 それはやってはいけないことです。 基本的に、そこにあるすべてのコンテナを削除しようとすると、驚いたことに、これはうまくいきます。 ホストからソケットをバインドマウントし、システム全体にアクセスできるため、機能します。 つまり、Dockerを個人的に試さないでください。

    それでは、この講演のすべてであるDocker-in-Dockerパターンで行きましょう。 Docker-in-Dockerは、CLIとエンジンに固有のネットワークを作成するなど、セキュリティをもう少し強化するために完了できるいくつかの手順を実行します。 これは本当になくてはならないものではありませんが、あなたはそれを行うことができます。 手順がより複雑になっていることがわかります。 そこで行ったのは、Dockerイメージを含むコンテナを作成することです。 このイメージには、Docker エンジンがすでに含まれています。 そのため、エンジンを検索する必要はもうありません。 このDockerエンジンが実行されるコンテキストは既にあります。 これは、以前と同様に、Docker out of Docker環境と比較するためのDockerCLIです。 次に、エンジンを作成し、さまざまなコンテナーに対する CLI を作成します。 そして、物事は今うまくいくでしょう。

    そして最も重要なのは、ホストエンジンにアクセスできないことで、これは私たちが避けようとしていたことです。 現在、何かを削除しようとしていますが、ホストレベルにあるコンテナにアクセスできないため、明らかに機能しません。 さて、私が言ったように、このデモはこれでほとんど終わりです。

    長所と短所

    それでは、前のデモで触れたデプロイ パターンについて詳しく見ていきましょう。 前述したように、Docker out of DockerはホストレベルのDockerエンジンを再利用します。 また、Docker-in-Dockerは、コンテナ内で実行される個別の専用Dockerエンジンに依存しています。

    それでは、それぞれを見ていきましょう。 では、Dockerのうち、Dockerの長所は何でしょうか? さて、機能のコンテキスト内では、ホストDockerエンジンを使用するという事実は、スペースを節約するため便利です。 これにより、すべてのイメージが移動する共有場所に依存しているため、ビルド アクションが迅速化されます。 また、すべてのコンテナがイメージをプールすることに依存しているわけではありません。 ですから、物事がより速く、より効率的であると考えるのは自然なことですが、そこには大きな短所があります。

    前述したように、ホストのDockerエンジンに直接アクセスできます。 そして、それだけでは不十分な場合は、共有で最速のように機能を壊します。 ご存じのとおり、異なるバインドマウント空間に住んでいるという事実だけでは、定義上、異なる環境、異なるコンテキストにあるホストからバインドマウントすることはできません。 したがって、「docker run」を実行しようとすると、最速のパスをインポートするため、明らかに機能しません。 同じ環境、同じコンテキストにいないため、うまくいきません。 しかし、私が言ったように、DockerからDockerの主な問題はセキュリティです。 共有パブリック環境には絶対にお勧めしません。

    さて、これは実際には少し繰り返しなので、これを簡単に説明します。 DockerからDockerを出すと、「docker ps」を実行すると、環境全体にアクセスできます。 また、内部コンテナはシステム内のすべてのコンテナを簡単に殺すことができます。

    さて、Docker-in-Docker、長所と短所は何ですか? 長所は、既にパッケージ化されている DinD イメージに依存し、実際にはエンジンと CLI の両方が含まれているため、使いやすいことです。 前の例では、Docker と Docker を比較するためだけに分割しましたが、実際には、その DinD イメージ内には、必要なものがほとんどすべて揃っています。 だから、それは非常に使いやすいです。

    もうひとつの良い点は、ようやくDocker安定版からの外部コンテキストができたことです。 別々のエンジンが独立して動作しています。 これは、Dockerのセキュリティ上の懸念からDockerのいくつかに対処するため、これもプロです。 では、安全でない特権コンテナを必要とするDocker-in-Dockerの大きな課題は何でしょうか? 多くの組織には当てはまらないことはわかっています。 私はそれを提案しません。 私もお勧めしません。 そうです、それは間違いなく実行可能な解決策ではありません。

    これもまた、デモの前にやったことを少し繰り返したものです。 私たちはネットワークを作りました — それは本当になくてはならないものではありません。 Docker-inDockerコンテナを開始しました。 CLIコンテナを作成し、それに実行します。 そして、ホストコンテナにアクセスできないことに気付きましたが、これは良いことです。

    現在、Docker-in-Dockerの主な課題は、特権コンテナに依存しているという事実です。 要約すると、特権コンテナの問題は、コンテナ内のrootユーザーがホスト上のrootユーザーとまったく同じであることです。 それだけでは不十分な場合は、すべての機能、すべてのカーネル機能が、コンテナー内で実行されるプロセスに割り当てられます。 したがって、誰かが、プロセスが DinD コンテナーを使用してその GL 環境から脱出した場合、そのプロセスは、root ユーザーがシステム内で持っているのとまったく同じ権限を持つすべての機能を備えていることに気付くと考えることができます。

    だから、ほとんど何でもできます。 そのため、多くの組織にとって間違いなくNGです。 これで、エスケープしなくても、エスケープしてホストに行くシステムがなくても、コンテナ内でも、ホストデバイスに直接アクセスできます。 そのため、ルートハードドライブから何かをマウントできます。 マウントをコンテナーにバインドできます。 これらのファイルへのルートアクセス権があります。 さらに、procfs システムと sysfs システムへの読み取り/書き込みアクセス権もあります。 したがって、文字通りカーネルに、カーネルからのルートを書き込むことができます。

    次に、ここにスクリーンキャストを少し紹介します。 そこで、特権コンテナを初期化します。 私はprocfsシステムを見ています。 UIDマップとは何ですか? これは、このコンテナのプロセスが実行されているUIDが何であるかを意味します。 ご覧のとおり、最初の列は 0 で、2 番目の列は列であり、それも 0 です。 つまり、プロセスはコンテナ内のUIDゼロで実行されており、ホストシステム上のUIDゼロにマップされます。

    私たちはその機能に注目しています。 したがって、システムで可能なすべての機能で実行されているプロセスを確認できます。 そこにあるすべてのFFF。 そして最後に、先ほども言ったように、procfs と sysfs を介してカーネルへの読み書きアクセスがあるため、procfs のこれらのファイルに 2 バイトを書き込むだけで、文字通りシステム全体を再起動することになります。 たった1つのコマンドで、すべてが再起動されます。 つまり、このソリューションがいかに安全でないかを示しています。 さて、もう十分です。

    シスボックス

    それでは、考えられる解決策について話しましょう。 Docker-in-Dockerをより安全な方法で処理するにはどうすればよいでしょうか? どうやってやるの? したがって、Sysboxは考えられる解決策の1つです。 Sysboxとは何かを見ていきましょう。

    Sysbox は新しいコンテナー ランタイムです。 それは新しいランクです。 DockerやKubernetes、さらにはcontainerdやCRI-Oよりも下で動作します。 だから、それは本当に低いレベルにとどまります。 つまり、ユーザーは別のツールを学ぶ必要はありません。 Sysboxで操作する必要はありません。 ご存じのとおり、SysboxはOCI仕様に目を通し、上から来る要件や要求に耳を傾けます。 それはそれで動作するでしょう。 ユーザーは新しいことを学ぶ必要はありません。 ここが重要なポイントです。

    Sysboxが行うことは、通常のコンテナよりも多くのワークロードを可能にすることです。 そして、それをシームレスかつ安全に行います。 それはどのように行われますか? まあ、それは、常に、仮想化技術の利用を通じて、より多くの分離を提供します。 たとえば、Sysbox 内で実行されるすべてのコンテナーは、ユーザー名前空間に依存しています。 それらに含まれるすべてのプロセスは、その環境に固有の ID スペースに割り当てられます。 ですから、それは重要なことです。 そして、先ほども言ったように、機能的に言えば、Sysboxでは、特権ワークロード、コンテナなし、特権ワークロードを実行できます。 これが、DockerやKubernetesのようなものをSysbox内で実行できる理由です。 前述したように、DockerおよびKubernetesと完全に統合されています。 そのため、他のランタイムと同様に、runcなどの別のランタイムとして実行できます。 そして最後に、オープンソースであることが重要なのです。

    この講演の文脈の中で、なぜここでSysboxについて話しているのですか? Docker-in-Docker環境でSysboxを使用する場合、特定の長所と短所があるためです。 まず、長所を見ていきましょう。 まず、このパターンは概念的に単純です。 これは、前に説明した従来の Docker-in-Docker シナリオと一致します。 Linux ユーザー名前空間、procfs と sysfs の仮想化により、強力な分離を提供します。 マウントなど、制御パス上の特定のシステムコールに対して、いくつかのシステムコールトラップを行います。 ですから、私たちはデータパスから離れて、パフォーマンスを損なわないようにしています。 ファイルシステムに関してユーザー名前空間が問題にならないように、ユーザーIDのシフトを行います。 そして、すべてのもの。 しかし、主な長所となると、最も重要なことは、特権コンテナが必要ないということです。 同じワークロードを引き続き実行できますが、コンテナー内で実行できる操作が含まれています。

    もう 1 つの重要な点は、これがベアメタルまたはクラウド VM で機能することです。 入れ子になった仮想化は必要ありません。 たとえば、なぜマイクロVMでDocker-in-Dockerをやらなかったのか、と言う人がいるからです。 これも有効な解決策です。 しかし、そのためには喜んでお金を払わなければなりません。 それだけでなく、すべてのクラウドベンダーでさえそのオプションを提供しているわけではありません。 実際、セキュリティの手法に深く踏み込む必要がない場合もあります。 真ん中に何かが欲しくなることもあります。 sysbox が micro VM と比較して提供する点の 1 つは、非常に使いやすいことです。 Dockerを実行するだけです。 画像を作成する必要はありません。 私の意見では、マイクロVMには多くの複雑さがあります。 短所は何ですか? 主なものは、比較的最新のLinuxカーネルが必要であることです。 これは比較的単純で、現在サポートされているLinuxディストリビューションの数は限られています。

    すべてをまとめましょう。 Docker-in-Dockerとは何かについて話しました。 ユースケースについてお話ししました。 Docker-in-Dockerをどのように実行するかについて説明しました。 そして、それに伴う課題も見えてきました。 私たちは、そこから考えられる解決策を提起し、言及しました。 そして、すべてのピースをデモでまとめます。

    すべてをまとめる

    先ほど説明したすべてのコンポーネントを接続するために最初にできることは、ここで説明したすべてのコンポーネントを含む AMI (VM イメージ) を作成することです。 それがDockerでやったことです。 私たちは、私たちが必要とするすべてのコンポーネントをほぼ満たすDinD AMIと呼ばれるものを作成しました。 ディストリビューションの面では、カーネルの観点から。 内部に住んでいるコンポーネントに必須のものはすべて、そのイメージですでに認めています。 そのイメージは、どこでもすぐに使用できます。 もちろん、Docker Engine、CLI、BuildXなどの主要なDockerプラグインなどが含まれています。 そしてもちろん、Sysboxもインストールし、事前設定されているため、すべてを使用する準備が整います。

    ここまでは、Docker-in-Dockerについて説明してきましたが、CIについてはあまり触れていませんでした。 ここでのCIの部分とは何なのか、疑問に思われるかもしれません。 ですから、私が個人的に保証していることの 1 つは、このモデル、つまりすべてのコンポーネントを備えたこの DinD AMI が提供できるものは、CI 環境のコストを削減する方法であるということです。 なぜなら、私たちがこれを提案している間は、ランナーが必要ならVMが必要だという現在のパラダイムに頼るのではなく、どうにかして何か違うことができるからです。 たとえば、1 つの VM を複数のランナー専用にすると言えます。 ですから、喉から手が出る前に、これは誰にでもお勧めできるものではありません。 これは、すべてのマルチテナント環境に当てはまるわけではありません。 私は、企業にいくつかのチームがあり、組織内のそれらのチームが多数のリポジトリを指し示しているソフトマルチテナント環境について、何らかの形でインフラストラクチャのコストを削減したいと考えています。 20VMをレンタルする代わりに、10してコストをどうにかして削減することもできます。これらのVMの中には、明らかに少し大きくする必要があるものもありますが、それでも価格を考えると、このスキームはそこでお金を節約するつもりです。 これが、私が具体的に触れているユースケースです。

    GitHub Actionsコンテナ化されたランナー

    さあ、前に進みましょう。 私が念頭に置いている例は、先ほど説明したすべてを説明するもので、GitHub Actions、つまりコンテナ化されたランナーです。 そのため、現在、セルフホストランナーはホストレベルで最適に機能します。 つまり、Docker化されたランナーは、Docker関連のステップでCIパイプラインをサポートしていないということです。 私が話しているのはDocker化であり、Kubernetes環境やランナーではないことに注意してください。 Kubernetesの世界では、このDockerコンテナを基本的にポッドとして別の場所にスポーンするための修正が過去数か月にわたって行われたためです。 そして、Dockerizedランナーが抱える複雑さのいくつかを迂回し、回避しています。 実際、それはもはやDocker-in-Dockerではありません。 それはおそらくDockerとKubernetesでしょう。 ただし、覚えておくべき重要なことは、KubernetesとDocker環境の両方で、エンジンを実行するには、特権コンテナまたはDockerからDockerのアプローチが必要になるということです。 そこから抜け出す方法はありません。 それでもそれが必要です。

    そこで、上記で強調した課題についてです。 つまり、すべてのランナーに VM を専用にしているため、コストの面で問題があるということです。 そして、それはコンピューティングリソースを最大化するための最も効率的な方法ではありません。 それが肝心です。

    さて、これが解決策の外観です。 下から始めますが、先ほど説明した Docker DinD AMI があります。 仮想マシンがあります。 コンテナスタック、つまりDocker、containerd、Sysboxで表示される灰色のレイヤーがあります。 これは今はruncではありません。 Sysbox があり、Sysbox はそれらのランナーをインスタンス化し、それらのランナーはリポジトリと通信します。

    このスライドで強調したこのパターンでは、各ランナーが個々のリポジトリと対話しています。 しかし、これはほんの一例です。 しかし、そうである必要はありません。 たとえば、3 人のランナーがいて、同じ GitHub リポジトリをポイントし、そこでジョブの負荷分散を行う別の環境があるとします。 別のユースケースとしては、たとえば、2 つのランナーがあり、3 番目のランナーのためのスペースがある場合があります。 3 つ目は、デバッグ CI ランナーです。 ええ、CIの問題をデバッグするのが嫌いな人はいます。 そのため、別の VM に移動してその問題をデバッグする代わりに、同じ VM にとどまります。 その場でランナーをインスタンス化するだけです。 また、同僚への影響も回避できます。 他のランナーは作業を続けます。 ランナーを作成するときにラベルを付け、そのランナーがラベル X を呼び出すように指示します。 また、開発ワークフローを作成するときは、そのラベルを使用します。 あなたの仕事はすぐにそこに移り、CI環境はそのままにしておくことになります。 したがって、デバッグの観点からも、これは理にかなっています。

    デモ

    それでは、今説明した内容を紹介するデモを見てみましょう。 さて、これは私の開発環境であるLinuxVMです。 基本的に、私はほとんどのことをLinux VMに依存しています。 これは比較的縮小されたカーネルです。 ご覧のとおり、コンテナはありません。 そして、これからお見せするのはレポです。 このリポジトリは、GitHub Actionランナーを実行する、かなり成功している既存のプロジェクトのクローンです。 私たちが行ったのは、このプロジェクトをクローンし、Sysboxに特化させたことです。 私が言いたいのは、そのリポジトリをgit cloneすると、GitHub Actionランナーがすでに含まれているイメージを作成するオプションと、それを設定するために必要なすべての手順が得られるということです。 すべてが自動化されています。 そして、この特定のリポジトリの利点は、特にSysbox用であることです。

    大丈夫です。 これから行うことは、そのリポジトリをgit cloneすることです。 前述したように、そのリポジトリには GitHub ランナー イメージをビルドする方法があります。 また、シェルラッパーもありますが、これについては後ほど説明します。 そのシェルラッパーが行うことは、ランナーを作成するために必要なDocker命令をラップすることです。 それで、しかし、そのリポジトリは私たちにイメージをもたらしています。 また、ラッパーを上に置いて、開発環境や仮想マシンから GitHub ランナーを簡単に作成することもできます。

    それでは、そのラッパーを実行してみましょう。 さて、これはあなたが必要とするものの1つです。 さて、別のリポジトリに戻ります。 これは私たちが複製したものではありません。 これは、開発に関するもの、つまりCISワークフローを含むリポジトリです。 すべてがこのリポジトリにあります。 また、仮想マシンからランナーを作成するには、いくつかのトークンが必要です。 GitHubへの認証を可能にするもの。

    では、どうすればいいのでしょうか? GitHubでは、そのためのトークンを作成することができます。 それを見ていきましょう。 設定。 Linuxをクリックすれば、そこに行きます。 これは、ここで必要なトークンです。 GitHub がユーザが従うべき公開する他のすべての手順に注目してください。 そのどれも必要ありません。 これらはすべて、以前に事前に構築したランナー イメージ内で既に自動化されています。 したがって、すべてをスキップできます。 実際には、トークンを生成する必要をなくす方法もあります。 個人用アクセス トークンを使用する場合は、そのリポジトリ内の権限がある限り、ほとんど何でも実行できます。

    したがって、技術的には、これを行う必要さえありません。 しかし、この例で行きましょう。 必要なトークンはそれだけです。 そして今、あなたはこのCLIラッパーを呼び出しますか、これはDockerコマンドに他なりません。 ここで渡しているのはランナーの名前です。 これを GitHub Action Runner 1と呼んでいます。 以前取り組んでいた組織であるリポジトリ、つまりこのパッケージを渡します。 そして、トークンを渡します。 ランナーを生成するために必要なのは、ほとんどすべてです。 ランナーが作成されました。 そのランナーに関連付けられているロックを見てみましょう。 GitHub Action が近づいているのを見てください。 すでに認証済みです。 そして今、私たちはGitHubから来る仕事に耳を傾けています。 GitHub側を見てみましょう。 そして、ランナーがすでにそこに存在していることを確認しましょう。 さあ行こう。 すでに準備が整いました。 それでは、ワークフローを機能させてみましょう。 これは、単にDockerジョブを含む私が作成したワークフローです。 基本的には、イメージを構築し、イメージをプッシュします。 前にも言ったように、今日現在、Docker化された環境で問題になっていること。

    では、このワークフローを実行してみましょう。 開発ワークフローがある開発ブランチにいくつかの変更を加えました。 だから、ここですぐに仕事が決まるのがわかります。 GitHubから来ています。 さあ行こう。 実行中のジョブ。 これはいつものことです。 ここには、これまでに見たことのないものは何もありません。 GitHub Actionsを使用したことがある場合。 ワークフローの実行が開始されます。 数秒かかります。 もっと簡単な仕事を選ぶこともできたはずです。 これには数秒かかります。 ですから、私たちはその場でイメージを構築しているのです。 そして、私たちはすぐにプッシュするつもりです。

    さあ行こう。 ボスチェックアウト。 完成。 大丈夫です。 私たちが同じページにいることを確認するためだけに。 私はあなたを騙してはいません。 実際にそれが起こったのをお見せします。 ランナーを受け入れます。 実行中のコンテナがもう存在しないことを示します。 走っているときに見せてあげることもできたのに、見せなかった。 これが、私たちが最初に構築しようとしていたイメージです。 これは実際に起こったことです。 私はあなたに嘘をついていません。

    したがって、これはすべて理にかなっています。 つまり、開発環境内にランナーを作成しました。 さて、私がここで保証している別のことは何ですか? まあ、複数のランナーを作成することもできます。 それが肝心ですよね? では、それをやってみましょう。 複数のランナーを作成してみましょう。 そのランナーをその場に置いておきます。 次に、前に実行したのとまったく同じスクリプトを呼び出します。 for ループを使用します。 前に使用したトークンをコピーして貼り付けます。 突然、文字通り2、3秒で、4人のランナーがマシンを走らせることになります。 とても簡単です。 そして、先ほども言ったように、それらはすべてDockerエンジンを持ち、その監獄環境内で処理されているという意味で分離されており、明らかに特権コンテナがある場合よりも十分に封じ込められています。 それでも、仮想化環境を持つためのコストを支払っているわけではありません。 これらはランナーです。 そこには4人のランナーがいます。 これで、すべてのジョブを並行して実行する準備が整いました。 はい、それはほとんどそれです。 今日はそんなことを考えました。

    質疑応答

    何か質問はありますか? まだ時間があります。 大丈夫です。 これは、シェルスクリプトであるセルフホストのGitLabに適合させることができますか? そのため、GitHub、GitLabには独自のバージョンのランナーがあります。 そのためにSysboxにも適応できますか?

    ええ、もちろんです。 なぜそうしないのかわかりません。 実は、すでにSysboxがあります。 私の理解では、多くの人がGitLab環境でSysboxを使用しています。 ですから、GitLabランナーをSysboxで駆動することは間違いなく可能です。 実はこれは、GitHubランナーが登場する前の最初のユースケースでした。 はい、もちろんです。 ありがとうございます。

    これらすべてのレイヤーが一緒にネストされている場合、ホストマシン上のファイルアクセスなどに一種の遅延があり、顕著な違いが生じますか?

    I/Oとパフォーマンス全般に関して言えば、これは可能な限り効率的であると言えます。 同じ OS を実行しています。 カーネルを使用しています。 その代替案は、仮想マシンを用意するか、パフォーマンスにコストをかけることです。

    したがって、スループットに関しては、仮想マシンをネストして使用する場合よりも間違いなく効率的です。 それはあなたが得ようとしているものですか? ええ、そんな感じです。 Sysboxは、その点でそれほど多くの追加のオーバーヘッドを導入しません。 いいえ。いいえ、ごめんなさい。 私は今あなたの質問を受けました。 いいえ。Sysboxは単なるコンテナソリューションです。 それはただの別のruncです。 したがって、すべてが同じカーネルで実行されています。 レイヤーは追加していません。 インターフェイスを追加するだけです。 そう、ううん。

    ご不明な点がございましたら、イノベーションラウンジにお越しください。 私はあなたが持っているかもしれないすべての質問に答えてぶらぶらするつもりです。 ここにいてくれてありがとう。

    さらに詳しく

    この記事には、DockerCon 2023のプレゼンテーションの YouTube トランスクリプトが含まれています。 「Docker-in-Docker: Containerized CI Workflows」は、DockerのプリンシパルソフトウェアエンジニアであるChris Maki氏とDockerのプリンシパルソフトウェアエンジニアであるRodny Molina氏によって発表されました。

    自分に合ったサブスクリプションを見つける

    今すぐ専門家に連絡して、Dockerサブスクリプションのコラボレーション、セキュリティ、サポートの完璧なバランスを見つけてください。