1. 概要 Docker のイメージはレイヤーで設計されています。各レイヤーは「レイヤー」と呼ばれます。これらのレイヤーは /var/lib/docker/<storage-driver>/ ディレクトリに保存されます。ストレージ ドライバーには、AUFS、OverlayFS、VFS、Brtfs など、さまざまな種類があります。ストレージ ドライバーは、docker info コマンドで確認できます (著者のシステムは centos7.4 です)。 通常、Ubuntu のようなシステムではデフォルトで AUFS が使用されますが、CentOS 7.1 以降のシリーズでは OverlayFS が使用されます。この記事では、ストレージ ドライバーとして OverlayFS を使用したイメージ保存の原理とストレージ構造を紹介します。 2. オーバーレイFS導入 OverlayFS は、他のファイルシステム (ext4fs や xfs など) に依存し、それらの上に構築されたスタックファイルシステムです。ディスクスペース構造の分割には直接関与しません。元の基盤となるファイルシステム内のさまざまなディレクトリを「マージ」し、ユーザーに提示するだけです。これがジョイントマウントテクノロジです。AUFS と比較すると、OverlayFS は実装が高速でシンプルです。 Linux カーネルは、Docker 用に overlay と overlay2 という 2 種類の OverlayFS ドライバーを提供します。 Overlay2 は Overlay の改良版であり、inode の使用率の点では Overlay よりも効率的です。ただし、オーバーレイには環境要件があります: Docker バージョン 17.06.02 以上、ホスト ファイル システムは ext4 または xfs 形式である必要があります。 複合マウント Overlayfs は、下位ディレクトリ、上位ディレクトリ、作業ディレクトリの 3 つのディレクトリを通じて実装されます。下位ディレクトリは複数存在する場合があります。作業ディレクトリは基本的な作業ディレクトリです。マウント後にその内容はクリアされ、使用中にユーザーには表示されません。最後に、ジョイントマウントが完了した後にユーザーに表示される統一されたビューは、マージされたディレクトリと呼ばれます。次の mount の使用法では、それがどのように機能するかを説明します。 次の構文で mount コマンドを使用して overlayfs をマウントします。 マウント -t オーバーレイ オーバーレイ -o 下位ディレクトリ=下位1:下位2:下位3、上位ディレクトリ=上位、作業ディレクトリ=作業 マージされたディレクトリ 3 つのディレクトリ A、B、C、およびワーカー ディレクトリを作成します。 次に、マウントの組み合わせを使用して /tmp/test にマウントします。 次に、/tmp/test ディレクトリを再度確認すると、ディレクトリ A、B、C が結合され、同じファイル名のファイルが「上書き」されていることがわかります。ここでの上書きは実際の上書きではありませんが、結合中にディレクトリ内の 2 つのファイルの名前が同じである場合、結合されたレイヤー ディレクトリには最も近いファイルが表示されます。 同時に、mount コマンドを使用してマウント オプションを表示することもできます。 上記の方法はジョイントマウント技術とも呼ばれます。 Docker のオーバーレイ ドライバー オーバーレイ ドライバーの原理を紹介した後、Docker のオーバーレイ ストレージ ドライバーを見てみましょう。以下は、Docker の公式 Web サイトに掲載されているオーバーレイの動作原理の図です。 上の図では、lowerdir、upperdir、merged の 3 つのレイヤー構造が確認できます。Lowerdir は読み取り専用のイメージ レイヤーで、実際には rootfs です。上で示したディレクトリ A と B と比較すると、イメージ レイヤーは複数のレイヤーに分割できるため、対応する lowerdir には複数のディレクトリが存在する可能性があることがわかります。 upperdir は lowerdir の上の層です。この層は読み取り/書き込み層です。コンテナの起動時に作成されます。例の C と比較すると、コンテナ データへのすべての変更はこの層で発生します。最後に、マージされたディレクトリはコンテナのマウント ポイントであり、例の /tmp/test と比較して、ユーザーに公開される統一されたパースペクティブです。これらのディレクトリ レイヤーは、/var/lib/docker/overlay2/ または /var/lib/docker/overlay/ (オーバーレイが使用されている場合) に保存されます。 デモ コンテナを起動する オーバーレイ マウント ポイントを確認すると、マウントされたマージされたディレクトリ、lowerdir、upperdir、workdir を見つけることができます。 overlay2 には複数の下位ディレクトリが存在する可能性があり、それらはソフト リンクとしてマウントされます。これについては後で説明します。 仕組み コンテナ内でデータが変更された場合、overlayfs ストレージ ドライバーはどのように機能しますか?読み書きのプロセスについては、以下で説明します。 読む:
改訂:
予防
3. Overlay2画像保存構造 リポジトリから Ubuntu イメージをプルします。結果は、次のように合計 4 層のイメージがプルされたことを示しています。 この時点で、4 つのレイヤーは /var/lib/docker/overlay2/ ディレクトリに保存されます。 すべてのレイヤーのソフト リンクを含む追加の l ディレクトリがあります。短いリンクでは、マウント時にパラメータがページ サイズの制限に達するのを避けるために短い名前を使用します (デモでマウント コマンドを表示するときの短いディレクトリ): 最下層の画像ディレクトリには、差分ファイルとリンク ファイルが含まれています。差分ディレクトリには現在のレイヤーの画像コンテンツが保存され、リンク ファイルは対応する短い名前です。 上の画像には作業ディレクトリと下位ファイルが追加されています。下位ファイルは親レイヤーの短縮名を記録するために使用され、作業ディレクトリは指定された作業ディレクトリを共同マウントするために使用されます。これらのディレクトリと画像はどのように整理されていますか?答えはメタデータの関連付けです。メタデータは、画像メタデータとレイヤーメタデータに分かれています。 画像のメタデータ イメージのメタデータは、/var/lib/docker/image/<storage_driver>/imagedb/content/sha256/ ディレクトリに保存されます。名前は、イメージ ID にちなんで名付けられたファイルです。イメージ ID は、docker images を通じて確認できます。これらのファイルには、イメージの rootfs 情報、イメージの作成時間、ビルド履歴情報、起動エントリポイントや CMD を含む使用されたコンテナーなどが json 形式で保存されます。たとえば、ubuntu イメージの ID は 47b19964fb50 です。 対応するメタデータ (vim :%!python -m json.tool を使用して json にフォーマット) を表示し、その rootfs の構成をキャプチャします。 上記の diff_id はイメージ レイヤーに対応しており、上から下の順に並べられ、イメージ レイヤーの最下層から最上層を表します。 diff_id はレイヤーとどのように関係していますか?具体的には、docker は rootfs 内の各 diff_id と履歴情報を使用して、対応するコンテンツ アドレス可能インデックス (chainID) を計算し、chaiID をレイヤー レイヤーに関連付け、各イメージ レイヤーのイメージ ファイルに関連付けます。 レイヤーメタデータ レイヤーはイメージ レイヤーの概念に対応します。Docker バージョン 1.10 より前では、イメージはグラフ構造を通じて管理されていました。各イメージ レイヤーには、レイヤーのビルド情報と親イメージ レイヤー ID を記録したメタデータがありました。最上位のイメージ レイヤーには、イメージ全体のメタデータとしてさらに多くの情報が記録されます。グラフは、各イメージ レイヤーに記録されたイメージ ID (つまり、最上位のイメージ レイヤー ID) と親イメージ レイヤー ID に基づいて、ツリー状のイメージ レイヤー構造を維持します。 Docker バージョン 1.10 以降、イメージ メタデータ管理における最大の変更点の 1 つは、イメージ レイヤーのメタデータが簡素化され、特定のイメージ レイヤー ファイル パッケージのみが含まれるようになったことです。ユーザーが Docker ホストに特定のイメージ レイヤーをダウンロードすると、Docker はイメージ レイヤー ファイル パッケージとイメージ メタデータ (差分、親、サイズなど) に基づいて、ホスト上にローカル レイヤー メタデータを構築します。 Docker がホスト マシン上で生成された新しいイメージ レイヤーをレジストリにアップロードする場合、新しいイメージ レイヤーに関連するホスト マシン上のメタデータはパッケージ化されず、イメージ レイヤーと一緒にアップロードされません。 Docker は、読み取り専用レイヤーと読み取り/書き込みレイヤーの一部の操作をそれぞれ定義するために使用される、Layer と RWLayer という 2 つのインターフェースを定義します。また、上記の 2 つのインターフェースをそれぞれ実装するために、roLayer と mountedLayer も定義します。このうち、roLayer は不変のイメージ層を記述するために使用され、mountedLayer は読み取りおよび書き込み可能なコンテナ層を記述するために使用されます。具体的には、roLayer に格納される内容は、主に、イメージ レイヤーをインデックスする chainID、イメージ レイヤーの検証コード diffID、親イメージ レイヤー parent、現在のイメージ レイヤー ファイルを格納する storage_driver の cacheID、イメージ レイヤーのサイズ、その他の内容が含まれます。これらのメタデータは、/var/lib/docker/image/<storage_driver>/layerdb/sha256/<chainID>/ フォルダーに保存されます。次のように: 各 chainID ディレクトリには、cache-id、diff、zize の 3 つのファイルがあります。 キャッシュIDファイル: docker によってランダムに生成された uuid には、イメージ レイヤーのディレクトリ インデックス (/var/lib/docker/overlay2/ 内のディレクトリ) が含まれます。そのため、対応するレイヤー ディレクトリは chainID を通じて見つけることができます。チェーンIDに対応するディレクトリはd801a12f6af7beff367268f99607376584d8b2da656dcd8656973b7ad9779ab4で、これは130ea10d6f0ebfafc8ca260992c8d0bef63a1b5ca3a7d51a5cd1b1031d23efd5であり、/var/lib/docker/overlay2/130ea10d6f0ebfafc8ca260992c8d0bef63a1b5ca3a7d51a5cd1b1031d23efd5に保存されます。 差分ファイル: イメージメタデータの diff_id が保存されます (メタデータの diff_ids の uuid に対応) ファイルサイズ: 画像レイヤーのサイズを節約します レイヤーのすべての属性のうち、diffID は、SHA256 アルゴリズムを使用してイメージ レイヤー ファイル パッケージの内容に基づいて計算されます。 chainID は、コンテンツ ストレージに基づくインデックスです。現在のレイヤーとすべての祖先イメージ レイヤーの diffID に基づいて計算されます。具体的な計算は次のとおりです。
MountedLayer 情報に格納される読み取り可能な init レイヤーおよびコンテナ マウント ポイント情報には、コンテナ init レイヤー ID (init-id)、ジョイント マウントに使用される ID (mount-id)、およびコンテナ レイヤーの親レイヤー イメージの chainID (parent) が含まれます。関連するファイルは、/var/lib/docker/image/<storage_driver>/layerdb/mounts/<container_id>/ ディレクトリにあります。次のように、ID 3c96960b3127 のコンテナを起動します。 対応する 3 つの mountLayer ファイルを表示します。 initID は、mountID の後に -init が追加された、/var/lib/docker/overlay2/ に保存されているディレクトリの名前であることがわかります。 また、mount コマンドを使用して、対応するマウントの mountID を直接表示することもできます。これは、overlayfs によって提供されるマージされたディレクトリでもある /var/lib/docker/overlay2/ ディレクトリに対応します。 コンテナ内にファイルが作成されます: この時点で、ホストのマージされたディレクトリ内に対応するファイルを確認できます。 初期化層について init 層は、uuid+-init で終わる名前で表されます。読み取り専用層と読み書き可能層の間に挟まれており、/etc/hosts や /etc/resolv.conf などの情報を格納するために使用されます。この層が必要なのは、コンテナの起動時に、ホスト名などイメージ層に属するべきファイルやディレクトリをユーザーが変更する必要があるためです。ただし、イメージ層では変更できません。そのため、起動時に別の init 層をマウントし、init 層内のファイルを変更することで、これらのファイルを変更する目的を達成します。これらの変更は多くの場合、現在のコンテナでのみ有効であり、docker commit がイメージとして送信されると、init レイヤーは送信されません。このファイル層が保存されるディレクトリは /var/lib/docker/overlay2/<init_id>/diff です。 まとめ 上記の紹介により、コンテナの完全なレイヤーは、以下に示すように 3 つの部分で構成されるはずです。
IV. 結論 この記事では、ストレージ ドライバーとして overlayfs を使用したイメージ ストレージの原理を紹介します。各レイヤーのイメージ データは /var/lib/docker/overlay2/<uuid>/diff ディレクトリに保存され、init レイヤー データは /var/lib/docker/overlay2/<init-id>/diff ディレクトリに保存され、統合ビュー (コンテナ レイヤー) データは /var/lib/docker/overlay2/<mount_id>/diff ディレクトリに保存されます。Docker は、イメージ メタデータとレイヤー メタデータを通じてコンテンツ アドレス指定 (chainID) を使用してこれらのディレクトリを整理し、コンテナ上で実行されるファイル システムを形成します。 参照: 《overlayfs ドライバーを使用する》 《Dockerイメージのストレージ管理》 以上で、Docker イメージ保存における overlayfs の利用についての説明は終了です。Docker イメージ保存における overlayfs についての詳細は、123WORDPRESS.COM の過去の記事や以下の関連記事をご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
これは、CSS 3.0 で実装されたテキストのホバーとジャンプ効果です。効果は次のとおりです。 以下...
コードをコピーコードは次のとおりです。 @文字セット "utf-8"; /* @...
目次1. JavaScriptの問題2. TypeScriptの利点3. TypeScriptの欠点...
類似の構造:コードをコピーコードは次のとおりです。 <div></div>&...
MySQL ブール値、偽または真を格納つまり、データベースに保存されるブール値は 0 と 1 であり...
この記事では、参考までにEasy Notepadを実装するためのVueの具体的なコードを紹介します。...
このブログ投稿は、ブロガーが数日前に取り組んだプロジェクトで遭遇した困難についてです。これを学んだ後...
// これをインストールするのに丸一日かかったので、記録するためにメモを書きました。 //何か問題が...
teeコマンドは主にstandout(標準出力ストリーム、通常はコマンド実行ウィンドウ)に出力し、同...
システム環境: Windows 7 1. DockerをインストールするDocker公式サイトからd...
目次1. 新しいII. 変更element-ui は、Ele.me のフロントエンド チームが開発者...
画像の色を変更するための CSS テクニックは非常にシンプルです。具体的なコードは次のとおりです。ヒ...
テーブル パーティショニングは、データベース パーティショニングとは異なります。では、テーブル パー...
Linux viコマンドの詳しい説明vi エディタは、すべての Unix および Linux システ...
必要な項目をループして検証するために、クエリ フォームのいくつかのプロパティを実装したいと考えていま...