ドッカーコン

コンテナー イメージ: 対話型のディープ ダイブ

Yves Brissaud 氏 (シニア ソフトウェア エンジニア、Docker)

2023年11月15日収録
この講演では、OCI(Open Container Initiative)イメージについて詳しく説明します。 まずイメージを構築し、次にイメージの内部とレジストリとの関係を調べます。 最終的には、制限や拡張の可能性など、画像が実際に何であるかをよりよく理解できます。

写し

この講演へようこそ。 今朝の基調講演を楽しんでいただけたでしょうか。 まあ、これは少し違うことですが、それは本当にすべての画像であるすべての仕事の中核的な部分です。 そして、私のイメージのビジョンと、それがどのように機能しているかをよりよく理解する方法を紹介します。 まず、私はイヴです。 私はDockerのシニアソフトウェアエンジニアです。 私はDockerでCRIとバックエンドのものに取り組んでいます。

本題に入る前に、なぜ画像を気にすることが面白いのかを少し説明しておきたいと思います。 私は4年間、Dockerに取り組んできました。私はDockerのいくつかの異なる部分に取り組んできました。 私はレジストリで作業して、イメージのストレージ内の不整合を見つけます。 つまり、イメージがすべてだったのです。 DVPなどの出版社や、ソフトウェアやソースプログラムを担当しました。 プール分析など、画像、タグ、プールなど、いくつかの分析を作成しました。 そして今、私はDocker Scoutに取り組んでいますが、それは同じことです。 私は今でも画像を直接制作しています。 私はタグと、画像を拡張したり、画像内にコンテンツを追加したりする方法に取り組んでいます。

当初、画像は魔法のようなものでした。 つまり、Dockerを起動して何かを実行するときのように、イメージの中身がわかりません。 しかし、学べば学ぶほど、この異なるトピックに取り組み、同じ質問をするたびに「イメージとは何か?」という質問を投げかけます。 その通り。

タグと画像の関係は何ですか? そして、それはまた魔法のように見えます。 何がうまくいっているのか正確に理解できない場合があります。 そして実際、それはちょっと簡単です。 つまり、これらの画像を掘り下げて、それらすべてをよりよく理解するのは簡単です。 そして、それを理解すればするほど、ほとんどの場合、自分の仕事をきちんとこなすことができます。

この話は一体何なのでしょうか? 画像、つまりプッシュとプルについて説明します。 新しいバージョンの画像をプッシュするとどうなるか、どのように拡張できるか、ほとんどの場合、私たちが考える方法で画像の背後に移動するにはどうすればよいか。 しかし、それは仕様についてではありません。 仕様について何か見たい場合は、すべてがGitHubにあります。 それはかなりよく説明されています。 完全な仕様は記載しません。 ここでは意味がありません。 そして最後に、利用可能なスライドがあります。 したがって、スライドを見たい場合、または後で見たい場合は、すべてがすでにオンラインで入手できます。 今日お話しする内容と全く同じです。

目次

    単純なイメージを構築する

    画像について学びたい場合、最初に必要なのは画像です。 それでは、簡単なイメージを作成しましょう。 ほとんどの人はすでにその方法を知っているので、ビルド自体については説明しません。 イメージを構築します。 つまり、これは別のアーキテクチャ、複数のアーキテクチャの基本イメージに基づいています。 ここ数年、多くの人がプラットフォームの画像をあまり見ていないのです。 しかし、今、特に、人々が持っているので、 Mac M1、彼らは自分のラップトップに別のアーキテクチャを持ち始めます。 そのため、常にマルチプラットフォームのイメージが必要になってきています。 私たちはそれを行います。

    ある種の基本的なイメージを作成します。 サプライチェーンの資料をいくつか追加します。 ですから、私はこれを掘り下げません。 つまり、それが何を意味するのかを本当に理解したい場合は、他のツールがありますが、実際の例を挙げるだけです。 そして、それをさまざまなタグで生成します。 では、やってみましょう。 私は非常に単純なDockerファイルを持っています。 つまり、中身は関係ないのです。 長い画像から、いくつかのパッケージを追加し、JavaScriptコードを実行するだけです。 特別なことは何もありません。 そして、それが私のビルドです。 ですから、おそらくすでにご存知のこと、つまり、ビルド、私の2つのプラットフォーム、私が言ったように、Linux AMD64、Linux Arm64、2つが証明しています。

    その詳細を掘り下げることはしませんが、SBOMを追加する方法にすぎません。 つまり、イメージ、すべてのパッケージ、ライセンスなどのすべての詳細です。 そして、来歴は、ビルド時に記録したすべてのもの、つまり、この画像のダイジェストは何かなどです。 そして、4つのタグがあります。 このタイトルを選びました。 それは必ずしもあなたがほとんどの場合行うことではありませんが、ベースイメージを使用しているときは、そのように行われます。 そのため、アルパインの画像を撮った場合と同様に、アルパインの最新、アルパイン 3などを引っ張ることができます。これは、チャンネルを選択して必要なチャンネルを選択する方法です。 だから、それを複製するだけです。 やりたいことは何でもできますが、あくまでも一例です。 そして、私はそれを推し進めます。 簡単なことを1つだけ。 つまり、いくつかのロケールなどがあります。 私は自分のラップトップに自分のレジストリを持っているので、ある種のネットワーク履歴を避けるためだけに、それは可能な限り多くありません。 それでは、かなり速いはずです。 ええ、押しています。 大丈夫です。 だから、私には私のイメージがあります。 つまり、私はそれを実行することができます。 そして、はい、こんにちは。

    中身は?

    これが物語の始まりです。 私には私のイメージがあります。 そして今、私がやりたいのは、中身を理解することです。 このイメージを実行するのではなく、このイメージを開きますが、イメージの内部を開き、コード内の移動を開始します。 そのためには、それが重要なのです。 ローカルディレクトリを作成するだけです。 そして、Docker の save コマンドが存在します。 したがって、Dockerの保存はイメージを取得し、それをアーカイブのtarに入れ、それをアーカイブして中身を確認します。 だから、抽出します。

    大丈夫です。 だから私はローカルディレクトリを作成し、Dockerを保存し、それをアーカイブするだけです。 以上が私の画像の内容です。 だから、たくさんのBLOBとほんの少しのファイルを調べて、それを見るためにVSコードを開くだけです。 大丈夫です。 これは、読みたいときの画像の内容です。 そのため、ほとんどの場合、さまざまなファイルがあるため、表示されません。 ですから、私たちはそれらを異なる方法で保存するだけです。 レジストリ内にどのように格納されるかについては、少し後で説明します。 しかし、それは1つのイメージです。 保存を行うと、それがアーカイブにあるものです。

    そこで、OCIレイアウトから簡単に説明します。 つまり、OCIとはOpen Container Initiativeの略です。 これで、画像の仕様がわかりました。 以前はDockerイメージもありましたが、今では誰もがOCIを使用しています。 それは私達が持っている最もよい指定です。 そして、私たちはただ、オーケー、これはバージョン1、1ゼロだと言うだけです。 大丈夫、大丈夫です。 マニフェスト JSON は、Docker イメージの方法です。 インデックスJSONはOCIの方法です。 そこで、インデックス JSON に移動します。 つまり、いたるところにたくさんのJSONがあることがわかります。 この部分はエントリポイントにすぎません。 特別なことは何もありません。 つまり、これが私が抽出したばかりの画像であると言っているだけです。 そして、私たちが常に持っているのは、メディアの種類とダイジェスト、そしてサイズです。 そのため、どこかにコンテンツがあるたびに、このコンテンツのダイジェストを作成するだけです。 そして、これは私たちがあらゆるコンテンツを参照する方法です。

    それで素晴らしいのは、同じ内容が2回ある場合、同じダイジェストが得られることです。 そのため、コンテンツを複製することはありません。 そして、メディアタイプがあります。 ですから、その場合は、これは画像インデックスです。 これがインデックスです。 ここからが私の出発点です。

    イメージダイジェスト

    ですから、それが私たちがずっとやっていることです。 このダイジェストをピックアップして、中身を見て、という具合です。 だから、この1つ、3つの8を選んでください。 ああ、そうです。 そちらに行ってください。 大丈夫です。 つまり、これもデジタルファイルです。 これがインデックスであることを確認できます。 そして、それは基本的にマニフェストのインデックスにすぎません。 これは単なるマニフェストのリストです。 中身はこれだけです。 そして、すべてのマニフェストについて、私たちが持っているのはプラットフォームです。 そのため、ここではイメージのマルチプラットフォームの側面からのみ始めました。 私たちはただやっているだけなので、これは Linux AMD64、以下の Arm64。 そして、それらのそれぞれについて、私たちはただ、よし、これがイメージマニフェストになるだろうと言うだけです。 そして、これがこのマニフェストのダイジェストです。 Arm64にとって、つまり、それはまさに何かであり、ダイジェストが違うだけで、内容が違うだけです。

    また、プラットフォームが不明なため、少し異なる他の2つのマニフェストもあります。 つまり、不明とは、プラットフォーム以外のコンピューターを使用している場合を除き、それを実行できない場合を意味します。 ですから、少し違うのです。 これはまだイメージマニフェストです。 しかし、その内容については、後でもう少し深く掘り下げます。 しかし、私たちのイメージには他のマニフェストがあります。 いくつかの注釈があります。 それがここで見ることができます。 タイプがあります。 つまり、これは構成証明マニフェストです。 ビルド中に、これ、テストを追加するだけです。 ですから、これも同じことだと考えることができます。

    そして、この注釈の何が興味深いのでしょうか? つまり、注釈は、あなたが望むすべてを伝えることができます。 それには本当のルールはありません。 しかし、参考になるものがあります。 だから、このマニフェストのダイジェストがあります。 そして、2番目のダイジェストを保存しています。 しかし、これ、C1、これはこれです。 そこで、イメージ内のさまざまなマニフェスト間のリンクを作成し始めます。 そして、それで何をするかというと、画像の何らかの視覚的表現の構築を開始します。

    イメージ インデックス

    したがって、最初に表示するのは画像インデックスです。 そして、4つのマニフェストがあります。 そして、私たちは毎回、2人の間にこの関係を持っています。 したがって、AMD64の 1 つのマニフェスト、Arm64の 1 つのマニフェスト。 そして、2つの証明が現れ、1つはこれを指し、もう1つはこれを指し示します。 それが私たちのイメージの基本です。 しかし、もう少し深く掘り下げてみましょう。 したがって、デフォルトでAMD64 を選択します。 つまり、他のものを選ぶこともできたでしょう。

    それでは、このダイジェストに進みましょう。 大丈夫です。 だから、それと同じことなんです。 つまり、これもJSONファイルです。 ただ違うだけです。 つまり、今回は主に2つの道があります。 1つはconfig、もう1つはlayerです。 つまり、期待どおりにマニフェストされているメディアタイプがあるだけです。 コンフィグは、イメージを実行するときにイメージのコンテンツの上に置くすべてのものです。 したがって、このファイルに移動すると、DB7。 繰り返しになりますが、JSONファイルです。 そして、イメージを実行するために必要なものがすべて見つかります — これは環境変数です。 これが私の命令です。 したがって、これはまさにDockerファイル内にあるものです。 つまり、環境、ビルドアップ、または私が意味するように表示するものは何でも、作業ディレクトリと言いました。 イメージを正確に実行するのはこれだけです。 また、設定履歴の部分もあります。

    つまり、この BLOB に格納されているのは、Docker ファイル内にあるすべての異なるレイヤー、すべての異なる命令です。 そして最後に、この差分IDがあります — これはコンテンツの非圧縮ダイジェストです。 それはまさに、最終的に最終的な画像の一部となるコンテンツです。 しかし、はい、これが構成です。

    そして、いくつかのレイヤーがあります。 レイヤーについては、かなり一般的な用語なので、ほとんどの人がすでに聞いたことがあると思います。 レイヤーは、コンテンツの BLOB のセットにすぎません。 これ以上深く掘り下げることはしません。 ここのレイヤーでは、つまり、jzipです。それはただのアーカイブです。 それは画像のすべてのファイルです。 そのため、さまざまなレイヤーがあり、それらを組み合わせます。 一部のレイヤーはファイルを追加でき、一部のレイヤーはファイルを変更でき、一部のレイヤーはファイルを削除できます。 そして、すべてのレイヤーをスタックするだけで、画像の最終的なファイルシステムが得られます。 次に、ファイルシステムと構成を使用して、イメージを実行できます。

    ここに戻ると、それがイメージです。 インデックスがあり、AMD64 プラットフォームのマニフェストを選択し、1 つの構成ブロックと複数のレイヤーがあります。 それは私たちがいつも持っているものです。 あなたが見ると アーム64、まったく同じものになります。 ほとんどの場合、それは人々がイメージと呼ぶものです。 これは、実際に最後に実行できるアセットです。 目標は、このアセットを取得するか、このアセットを保存することですが、最終的にはそれを実行します。 そして、これらすべてを組み合わせると、1つまたは複数の画像とインデックスのように、これはマルチプラットフォーム画像と呼ばれるものです。 これはその一歩に過ぎません。

    しかし、この2つ、2つの証明が何を示しているかを見てみましょう。 ここに戻ると、これが私のイメージです。 というわけで、インデックスの話に戻ります。 たとえば、このようなものを選びます。 これはイメージマニフェストなので、同じものでなければなりません。 それで、EF、私のEFはどこにありますか?はい、ここです。 繰り返しになりますが、これはイメージ マニフェストです。 構成があり、いくつかのレイヤーがあります。 構成に移動すると、わずかに異なります。 だから、これは、中にほとんど何もないからです。 これは信頼できません。 環境変数は気にしません。 コマンドなんてどうでもいい。 私は特定の3つのポイントを気にしません。 これは信頼できるイメージではありません。 しかし、これはまだイメージです。 そして、これを閉じることができ、レイヤーを見ると、それらはわずかに異なります。 まず第一に、それはまったく異なるメディアタイプです。 しかし、それはまだレイヤーです。 しかし、それはtotoにあります。 つまり、すべてのファイルを含むコンテンツです。 ダイジェストは、つまり、予想通りです。 そして、いくつかの注釈を再度追加しました。

    注釈

    アノテーションは、そのことわざの上にメタデータを与える方法にすぎませんが、ここには2つのレイヤーがあります。 どちらもtotoにありますが、同じ内容ではありません。 したがって、そのうちの1つがSPDXドキュメントです。 これがSBOM(ソフトウェア部品表)です。 これが私のイメージのすべてのパッケージです。 もう 1 つは SLSA の出所です。 そのため、ビルド時のすべてのコンテキストが発生します。 中身を非常に簡単にお見せできますが、それはこのツールの本当の目的ではありません。 つまり、必要なものをすべてそこに保存できるということです。 だから、それはyamlではありません。それはJSONです。 さて、これはただのファイルです。 私はファイルを調べません。それはあなたが持っているすべてです。 あなたはそれを保存することができます、あなたはあなたが望むすべてを保存することができます。 そして、パッケージ、イメージ内でそれらを見つけることができるすべてのライセンス。 これはある種のメタデータであり、画像のレイヤーとしてです。 そして、それは来歴についても同じことです。 したがって、添付されたセッションマニフェストのこの図を完成させようとすると、同じものになります。 これは同じメディアタイプではありませんが、最終的には、まったく役に立たない場合でも、1つの構成BLOBと2つのレイヤーにすぎません。

    それで、これは私たちが見ることができるものです - 私がインターネットで見せなかった唯一のものは、ブロブ自体、つまり、実行する画像のレイヤーだけですが、それはただのファイルです。 ですから、そんなことはどうでもいいのです。 でも、面白いのは、こういうイメージがあるんです。 走らせてあげられます。 しかし、私が望むのは、ほとんどの場合、プッシュすることです。 そこが大事なところです。 そして、なぜレジストリをプッシュするのですか? それをアーカイブして、任意のサーバーに置くことができます。 しかし、それのクールな点は重複排除です。 そこが一番大事なところでしょうね。 つまり、同一のコンテンツはすべて同一のダイジェストを生成します。 なので、一度だけ保管します。 レジストリのレベルでは、多くの人がまったく同じコンテンツを何度も作成しているため、これは非常に大きなことです。 または、他の人のコンテンツを再利用するためだけに。 ですから、私たちはすべてを重複排除するだけです。 また、メタデータも必要です。 つまり、この画像はダイジェストに関するものです。 したがって、常に実行したいイメージの正確なダイジェストを覚えたくない場合は、その上にメタデータの追加レイヤーが必要です。

    最後はバージョンです。 すべてのすべてのバージョンを保持したいと考えています。 たとえば、最新の画像をプッシュする場合、明日には最新の新しいバージョンをプッシュするかもしれませんが、前のバージョンを使用している人々を壊したくありません。 そのため、以前のすべてのバージョンを常に追跡する必要があります。 明らかに、レジストリにはそれらがたくさんあります。 つまり、認証、許可などです。 しかし、これは本当にその中で最高です。

    イメージをプッシュする

    次に、イメージをレジストリに直接プッシュする方法を見ていきます。 したがって、ほとんどの場合、すべてのBLOB、BLOBフォルダーのすべてのコンテンツをプッシュします。 私はそれを私のレジストリにプッシュしたいです。 したがって、レイヤー、構成だけでなく、すべてのマニフェストもなります。 基本的に、私のブロブの下にあるすべてのもの、私はそれをプッシュしたいのです。 そして、タグを作成し、その上にすべてのメタデータを作成します。

    したがって、レジストリに保存される方法は、私たちが持っているものと非常によく似ています。 したがって、ここでコンテンツに戻ると、つまり、私たちが持っているのはこれらのブロブ、SHA 256です。 それはレジストリにあり、ほぼ同じものです。 この追加のレベル、中級レベルがあるだけです。 最初の 2 文字だけです。 つまり、ブロブをセグメント化するだけですが、最終的には、ローカルにあるものとまったく同じです。 つまり、この部分はきれいで、すべてのブロブをプッシュするだけです。 中身なんて気にせず、ただ全部押し込むだけ。

    そして、それが非常に面白くなってきたのは、タグを押したいときです。 したがって、これはもう少し複雑です。 つまり、レイヤーが増えただけです。 つまり、リポジトリ名のように、タグがあります。 ですから、私はただ表現しただけです、つまり、ゼロにされたものとゼロにされたものがあるので、私はただプッシュするだけです。 そして、ここにはさらに多くのものがあります。 したがって、それをよりよく理解するために文字だけに焦点を当てると、最初に興味深いのは、リンクが最終的なファイルであるということです。 私が欲しいのは、タイトルの現在のバージョンを最新のものにしたいということです。 これがこのファイルです。 しかし、時々、私は私の最新のインデックスの以前のバージョンが欲しいです。 だから、それはこれになります。 つまり、ここでは、このタグに記録されたすべての異なるダイジェストを保存します。 後でさまざまなタイプをプッシュするときに、より理にかなっています。

    そして、それをまとめると、これがレジストリです。 これはまさに内部配布の内容です。 しかし、これもまさに今の現状です。 これはまさにそのように保存されます。 したがって、すべての宣伝文句、リポジトリ、およびその間のすべてのタグがあります。 そして、このリンクファイルの内容は何ですか? あくまでもダイジェストです。 したがって、これらすべてのファイルリンクには、私の画像のダイジェストが含まれているだけです。 だから多分私の画像インデックス。 そこからすべての点と点をつなぎ始めます。

    たとえば、画像をプッシュするとします。 そこで、ブロブをプッシュします。 そして、manifestタグの下に、異なるタグ、それぞれの現在のバージョンを格納します。 そして、バージョン、つまりインデックス、その履歴バージョンを保存するだけです。

    イメージをプルする

    そして今、私が知りたいのは、それをどのように引き出すことができるかということです。 実際、それはそれほど難しいことではありません。 つまり、主に3つの異なるステップがあります。 1つ目は、タグをダイジェストに変換したいということです。 アルパインを引っ張ってきたら、これを見つけたい、というか。 つまり、すべてが BLOB として格納され、そのダイジェストによって参照されます。 だから、私は自分のダイジェストが何であるかを知る必要があります。

    2つ目は、マルチプラットフォームのイメージがあるため、インデックスを取得し、どのプラットフォームをプルするかを知りたいということです。 多分私はLinux、AMD64のために実行したいからです。 だから、他のものは気にせず、これだけ欲しい。 だから私は最初にこれを選んでみます。 そして、実際に画像の内容をダウンロードします。 最初の部分は、これらの構成とレイヤーへのアクセスを許可することです。

    設定の宣伝文句とレイヤーを取得したら、それらを組み合わせて画像を実行できます。 つまり、ほんの数個のHTTPリクエストです。 とても簡単です。 私はちょうど私のマニフェストの最新のヘッドリクエストを行います。 つまり、manifest latestは最新のタグを意味します。 そして、答えは、わかりました、これは画像インデックスです。 そして、これはあなたのコンテンツのダイジェストです。

    だから私が得るのはこのファイルです。 このファイルの内容を取得するだけです。 だから私は最新のタグを求めています。 そして、私は他に何も言わなかった。 だから私はこのタグの現在のバージョンが欲しいです。 だから私にこのリンクの内容を与えてください。 そして、このリンクには私のインデックスのダイジェストが含まれています。 それで、ユーザーが2つのダイジェストを要求しているタグを作成しています。 だから私はダイジェストを手に入れることができます。 今回はこのダイジェストでマニフェストが手に入ります。 そして、私は取得します。 つまり、ヘッドリクエストは、ヘッダーに何も書き込まなかっただけです。 今、私はマニフェストを取得します。 しかし、特に、この画像インデックスは、すでに内部のさまざまなマニフェストを示しています。 そして、それらはすべて異なるプラットフォームを備えています。 それで、ここで私が得るのは、この画像インデックスです。

    だから、今は自分のイメージの中に入り込んでいくんです。 そして、このマニフェストのリストで私が望むのは、私のプラットフォームに適したものを選ぶことです。 だから私はLinux AMD64を使用しています。 ここでは、このダイジェストを取り上げます。 そして今、私は最後のダイジェストに行くまでそれを続けます。 これがイメージ マニフェストです。 それが私の望みです。 ダイジェストでも同じです。 そして、私はこのイメージマニフェストを取得します。 したがって、イメージ マニフェストはイメージのこの部分です。 そして、私がそれを読むならば、私はダイジェストで構成を持っています。 そして、私はそのダイジェストですべての層を持っています。 それで、私はいくつかのgetリクエストを続けます。 今回は、同じ場所ではありません。 つまり、ブロブ部分の中にあります。 これは私がこの情報を得ることができる方法です。 これは、イメージを実行するために取得したい本物です。 そして、これはあなたがイメージを「docker pull」したときにあなたが見たものです。 その場合は、プラットフォームAMD64でdocker pull を実行します。 そして、私はこのすべての行をダイジェストの一部で見ます。 短いダイジェストです。 そして、その場合、つまり、それが答えです。 完成したので、イメージインデックスの取得、イメージマニフェストの取得、設定ブログの取得、レイヤーの取得などを行います。

    それが私たちがやったことのすべてです。 つまり、手作業でできるのです。 つまり、それはほんの少しの要求です。 つまり、それほど難しいことではありません。 いくつかのリクエスト。 いくつかのJSONファイルを読むだけです。 つまり、docker pullを実行したときにDockerが行っていることです。 その通り。 それから、つまり、並列のことなどもできます。 あなたはそれを複雑にすることができます。 しかし、画像を引くようなものを書きたいのであれば、それはとても簡単です。 これで、画像の残りの部分がすべて取得されます。

    したがって、これはプルの要約の一種です。 しかし、これは私たちがイメージをプルするために行わなければならないすべての要求です。 それほど難しいことは何もありません、つまり、画像は非常に単純です。 すべてがアドレス指定可能なので、ダイジェストを知るだけで済みます。 そして、プルしたいダイジェストを知るには、いくつかのJSONファイルを読み取るだけで済みます。

    さて、面白いのは、最新の画像を引っ張ってきていることです。 しかし、画像を取得したい場合はどうすればよいでしょうか。 重要なのは、1 つのイメージを作成し、4 回ターゲットにすることです。 最新のものをプルし、今度はバージョンをプルします。 したがって、これら3つのまったく同じ手順に進みます。 したがって、最初に、タイプをダイジェストに変換します。 したがって、今回は最新のものではなく、1つになります。 適切なプラットフォームを見つけたのに、内容がわからない。 しかし、クールなのは、ここで行うべき要求が 1 つしかないことです。 つまり、タイプをダイジェストに変換すると、これはまったく同じダイジェストであり、最新のダイジェストだからです。 そして、それは私のマシンに保存されています。

    だから私はこのダイジェストを持っています。 もう一度、同じファイルを読みます。 ですから、この相互作用は本当に重要です。 つまり、これは本当に同じファイルだからです。 そして、同じファイルを読み取ります。 適切なプラットフォームを選択します。 私はすでに、つまり、ブロブ、このプラットフォームのマニフェストのダイジェストを持っています。 すべてのレイヤーの構成blobのダイジェストを読みましたが、すでにすべてがローカルにあります。

    最後には、たった1つの頭のリクエストで、新しいイメージができました。 ですから、明らかに極端なケースですが、ほとんどの場合、まったく同じ画像を2回引き出すことはありません。 しかし、コンテンツを追加するだけの画像があり、データから始める場合、つまり、コンテンツの一部がすでにローカルにあるため、一部のリクエストがそれらを行わないことがすでにわかっています。 つまり、私たちがやったことは、それが最新であるものは何でも、1つなのです。 このリンクから始めます。 つまり、最新のものを入手したら、このリンクを取得するだけです。 これは同じ内容です、それは完了です。

    新しい画像

    今、私たちは非常に興味深いことをすることができます。 それはいいですね。 私たちにはイメージがあり、それを押すことも、引っ張ることもできる。 しかし、私が望むのは、理由が何であれ、修正すべきことがあるのかわからないので、新しい画像を撮ることです。 では、やってみましょう。 非常に簡単な変更を行いましょう。 ですから、私はそれについて非常に簡単にします。 DockerCon LA の皆さん、こんにちは。 私はそれを再構築します。 したがって、これは同じビルドコマンドです。 1行を除いて。 これを除いて、同じタグを使用します。 これが私の新しいイメージです。 たぶん、それは非常に重要な修正です。 このバグ修正が欲しいので、 101と呼ぶことにします。 しかし、タグ 1 を使用することを選択した人には、このイメージを引き続き持ってもらいたいのです。 だから私は文字 1 と 101にタグを付け直します。 しかし、私は新しいタグを作成します 101. しかし、私は 1を変えません。00. それで、私が意味するものを見てみましょう、ただ、はい、最初に私はそれを構築する必要があります、それはより良いでしょう。 大丈夫です。 つまり、私はそれを実行することができます。 ええ、つまり、それは私の新しいものです。 つまり、タグを付けませんでしたが、最新という意味です。

    これは私の最新のイメージの新しいバージョンです。 大丈夫です。 この新しいバージョンを抽出できます。 したがって、 101. 基本的には全く同じことです。 つまり、少なくとも同じ構造です。 そして、私たちが見ることができるもの。 比較を用意しました。 正しいものを入力できれば。 はい。 だから、私は2つを混ぜました。 つまり、私が抽出した最初の画像と、違いを確認するための2番目の画像です。

    そして、私たちが見ることができるのは、新しいブロブがあるということです。 新しいイメージです。 新しいコンテンツがあります。 新しいタグが追加されました。 しかし、それらのいくつかは、つまり、白で表示されているものはすべてまったく同じです。 これらは、イメージの最初のバージョンに存在していました。 そして、それらはまだ2番目のバージョンに存在します。 ですから、ローカルでは、つまり、私が言わなければ、すべてを複製するだけです。 しかし、同じコンテンツがいくつかあります。 Dockerファイルの一部のみを変更します。 基本イメージは同じです。 パッケージが追加されます。 同じ。 多くのことが同じように読まれます。 ただし、そうでないものもあるため、すべての詳細については説明しません。 しかし、これが変わったことであり、変わらないことです。

    一部のレイヤーは変更されていません — 基本イメージ、パッケージなど。 しかし、それ以外はすべて変わりました。 私のマニフェストが同じではないように。 最終的な画像。 つまり、これはDockerConをDockerCon LAに変更した場所だとしましょう。 だから、新しいコンテンツ、新しいダイジェスト、私が彼らから読んだように、それは新しいものです。 このレイヤーのダイジェストを変更しました。 そのため、マニフェストが変更されました。 というか、内容が変わったんですね。 それで内容のダイジェストが変わったとか

    ですから、同じものがいくつかあります。 そうでないものもある。 しかし、異なる時期に構築するため、構成証明が異なります。 そこにタイムスタンプがあるのは、それが私たちが知りたいことだからです。 それで内容が変わりました。 しかし、はい、私たちはあらゆる場所での変更を可能な限り制限しようとしています。

    そして、このイメージをレジストリにプッシュすると、それが私のやっていることです。 だから私はこの 101をプッシュしています。 これが先ほど見たものです。 これは現在のバージョンであり、インデックスのバージョンです。 それで、私たちはダイジェストをしました。 つまり、それは歴史的なバージョンです。 しかし、私は 101を変えませんでした。 タグを付け直さなかったからです。 しかし、私は最新のものにタグを付け直しました。 そこで、2つの変更を行いました。 1つ目はこのリンクです。 これは、変更された現在のバージョンです。 いいえの場合、この画像を引っ張りたいです。 新しいバージョンが欲しいです。 前のものは欲しくない。 そこで、この新しいバージョンを履歴バージョンに追加しました。 しかし、私はまだ前のものを保持しています。 ですから、最新のものを引っ張ってこようとしても、つまり、この最新のダイジェストが欲しいと言っても、まだうまくいきます。 それはまだそこにあります。 ただし、デフォルトでは、新しいものになります。 したがって、これらのタグと異なるブロックの間の比率を見ると。 ですから、例えば、 100、つまり、このリンクは、1つのダイジェストに行くのです。 そして、最初の1つをやります。 そして、この新しいリンクは別のダイジェストを指しています。 そして、最近では、私は両方を持っています。

    これは、すべてのバージョンを保存する場所です。 そして、はい、これは非常に一般的です。 これは非常に良い習慣です。 たとえば、画像をピン留めしたいとします。 ですから、これはこのターゲットですが、この正確なダイジェストで、私たちは「よし、これがこのターゲットだ」と言います。 したがって、誰かがダイジェスト、ターゲットを変更し、新しいバージョンをプッシュした場合、私のビルドは、特に最新のものと同じままです。 だから、人々は時々本当に最新のものをたくさんプッシュします。 今でも、たまに、このダイジェストで自分のイメージを検証したのであって、別のダイジェストではない、みたいなことを言いたいんだ。 そのため、すべてを保存しています。 これが画像を作成し、画像をプッシュおよびプルする方法です。

    画像を超えて

    しかし、ちょっと面白いことがあります。 なぜなら、私たちはそれをはるかに超えることができるからです。 それは、私がそれらを実行するための画像を持っているようなものです。 私はいくつかのものを埋め込むだけです。 しかし、ほとんどの場合、それはファイルと構成を含む私の異なるレイヤーであり、それが私が望むものです。 しかし、実際には、それをはるかに超えることができます。 そして、それは2つの異なる方法で見ることができます。 その 1 つは、コンテナー イメージの保存を強制されないことです。 必要なものは何でも保存できます。 つまり、仕様を尊重するとすぐに、マニフェストイメージ、マニフェスト、およびイメージインデックスを尊重するとすぐに、残りはまさにあなたが望むものです。

    次に、私が本当に興味深いと思ったのは、コンテナイメージを拡張する方法です。 画像のデータに非常に近い画像内に保存できるため、必要なものをすべて保存することもできます。 だから、その例をいくつか挙げるだけです。

    まず、すべてを保存できます。 たとえば、Docker Compose には、Docker Compose を公開できる新しいコマンドが 1 つあります。 したがって、Docker作成YAMLファイルを含むOCIイメージになります。 そして、それはただのイメージです。

    マニフェストを見ると、これが私のイメージマニフェストです。 新しいアーティファクトタイプがあり、これはDocker Composeプロジェクトです、OK、それでいいのです。 予想どおり、構成 BLOB があります。 ちょうどサイズは2つです。 では、中には何も入っていないとしましょう。 そして、基本的には、ここに注釈を格納しているだけです。 つまり、使用される作成バージョンにすぎない注釈です。 そして、他のすべての画像と同様に、いくつかのレイヤーがあります。 しかし、今回のメディアタイプは作成ファイルのYAMLです。 それはJSONではありません、それは無料です、あなたはファイルを作成します。 そして、これがダイジェストです。 したがって、このダイジェスト、この BLOB を見つけて、それを読むと、これが YAML ファイルになります。 ただし、画像として保存されます。

    そのため、イメージを保存したら、すべての異なるレジストリ間で共有できます。 同じツールを使用できます。 さまざまなリンクやリクエストをたどるだけのツールがある場合は、タグをダイジェストに変換したり、マニフェストに移動したりします。同じように機能しています。 したがって、作成ファイルまたは画像をプルする場合、これはまったく同じことです。 これは新しいコマンドです。 だから、今はDockerComposeでのdash dash publishだと思います。 したがって、それをテストできます。 これは一つのことです。 Macをお持ちの場合は、おそらくすでにHomeBrewを使用しているでしょう。 ただし、HomeBrew はイメージ マニフェストとして保存することもできます。

    繰り返しますが、これはイメージではありません。 さまざまなレイヤーがあります。 しかし、あなたはそれを持っています。 そして、それのクールなことは、繰り返しになりますが、それをレジストリに保存することです。 重複排除は実際にはプロトコル内、つまり画像を保存する方法内で行われるため、重複排除があります。 だから、箱から出してすぐに使えるのです。 そして、レジストリは今、どこにでもあります。 したがって、HomeBrewをOCIイメージマニフェストとして使用することもできます。 CNABを持つことは可能ですが、その詳細には触れません。 CNABは、複数の画像を1つの大きなパッケージに結合し、複数の画像を含む可能性のある1つのアプリケーションを持つ方法です。 しかし、問題は、画像インデックスを参照する画像インデックスを持つことができるということです。 そして、あなたが望むなら、私たちは画像に画像を保存することができます。 そのため、1つのアセット内で多くの画像を組み合わせることができます。 そして、さまざまなリンクをたどる限り、それはうまくいきます。 だから、ちょうど別の方法。 そのために別のツールを作成する必要はなく、まったく同じレジストリを使用するだけです。

    それだけではありません。 つまり、すでにもっとあります。 そして、それを Helm チャートに使用しています。 Helm チャートをレジストリに保存し、すべてのイメージを同じ場所に保存できます。 コンテナイメージやDockerボリューム、開発コンテナなどとは少し異なるWASMモジュールを格納できます。 そのため、同じレジストリ内に保存できるものがたくさんあります。 したがって、レジストリはそれにとらわれません。 そして、仕様は、変更すべきものがあるかもしれませんが、そこにはあなたが望むものを何でも保存することができます。

    しかし、少なくとも観点から見ると、本当にクールなのは、画像を拡張することです。 したがって、最初の部分、最初の画像に戻ると、これら4つのレイヤーがすべて揃っています。 つまり、2つの証明なので、請求書の資料を大まかに保管する場所。 本当に良いのは、フルイメージ内に保存されていることです。 ですから、どこかに保管するようなものではありません。 SBOMが欲しい、画像の中に画像の説明が欲しい。 私はそれをどこか他の場所に置きたくありません。 だからあなたはそれを行うことができます。 まったく同じツールを使用しているので、本当にクールです。 画像を参照するときに、実行するパーツを選択できます。 しかし、たとえば脆弱性を表示するなど、分析する部分を選択することもできます。 しかし、それのクールな点は、少なくとも私が持っている、そしておそらくあなたにとっての質問は、何を保存すべきかということです。 画像内にドキュメントを埋め込む方法など、いくつかのハイライトをすでに行いました。 したがって、イメージを実行するだけで、イメージの完全なドキュメントが得られるか、または実行することができます。 たぶん、それを使ってRunbookなどを保存できます。

    重要なのは、実行可能なイメージに非常に近い場所に、必要なものをすべて保存できるということです。 そして、それはほんの少しの要求であり、あなたはあなた自身のツールを作ることができます。 ですから、もしかしたら、ドキュメントを表示するためのツールを作りたいのかもしれませんし、ツールを作りたいのかもしれません。

    とてもシンプルなので、それで何が作れるのか、とても興味があります。 つまり、ほとんどの場合、画像は非常に魔法のようなもので、一種のブラックボックスです。 しかし、それはただの異なるファイルの束です。 つまり、手作業で画像を作成することもできます。 つまり、コンテンツを作成し、そのダイジェストを作成し、JSONファイルを作成するだけで、画像が手に入ります。 とても簡単です。

    OCIイメージ仕様

    そして、最後にもう一つだけ。 したがって、最初に、つまり、画像の最初の外観では、このOCIレイアウトがあります。 そして、いくつかの注釈を見ました。 アノテーション、問題はそれが一般的すぎることです。 ただ、やりたいことをやればいいのです。 その寛大さは、やりたいことをやれるので、良いことです。 しかし、欠点は、やりたいことができることです。 そのため、その上にツールを作成するのは困難です。 つまり、仕様には新しいバージョンがあり、それは仕様にもたらされる新しい変更です。 したがって、バージョンになります 1.1.

    つまり、3つのことがあります。 1 つ目は、非コンテナー イメージの作成を支援することです。 2つ目は、この関係、たとえば、構成証明と内部の適切な画像の間に、この関係を作成するために、いくつかの非常に具体的なフィールドを作成することです。 したがって、これらのフィールドを取得したら、適切なAPIを作成できます。 ですから、いくつかのAPIを用意して、OK、このリファレンスがあります。 そして、私が知りたいのは、私のイメージのさまざまな部分間の関係です。

    したがって、これらは、新しいコンテンツの作成、コンテンツの拡張に役立つ仕様の新しい変更です。 そして、それはまさにエキサイティングな瞬間です。 つまり、これらの変化を見るのはとてもうれしいことです。 それで、人々がそれで何を作るか見てみましょう。

    そして、それで終わりです。 ここにいてくれてありがとう。 そして、そういったものを使って、たくさんの新しいツールを作っていきたいと思っています。 ありがとうございます。

    さらに詳しく

    ドッカーは初めてですか? 始めましょう

    この記事には、DockerCon 2023のプレゼンテーションの YouTube トランスクリプトが含まれています。 「Container Images: Interactive Deep Dive」は、DockerのシニアソフトウェアエンジニアであるYves Brissaud氏によって発表されました。

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

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