この記事では、イメージの階層化、コンテナーの階層化、および Docker でコンテナーが占有するディスク容量に関連する問題について説明します。
Dokcer は、ストレージ コンテンツを整理するときに階層再利用のアイデアを巧みに適用します。したがって、このアイデアを学ぶためのケースとしてこれを使用できます。
Docker イメージは構築プロセス中に多くのレイヤーに分割され、各レイヤーは読み取り専用になります。次の例で説明してみましょう:
# syntax=docker/dockerfile:1 FROM ubuntu:18.04 LABEL org.opencontainers.image.authors="org@example.com" COPY . /app RUN make /app RUN rm -r $HOME/.cache CMD python /app/app.py
この Dockerfile には、ファイル システムを変更して新しいレイヤーを作成する 4 つの命令があります。
FROM
コマンドは、ubuntu:18.04 イメージから基本レイヤーを作成します。 LABEL
このコマンドは画像のメタデータを変更するだけであり、新しいレイヤーは作成しません。 COPY
コマンドは、このビルドが実行される現在のディレクトリの内容をイメージに追加し、変更を記録するための新しいレイヤーを作成します。 RUN
命令はプログラムを構築し、結果を画像に出力し、変更を記録するための新しいレイヤーを作成します。 RUN
コマンドは、キャッシュ ディレクトリを削除し、変更を記録するための新しいレイヤーを作成します。 CMD
ディレクティブは、コンテナー内で実行される命令を定義します。これは画像のメタデータを変更するだけであり、新しいレイヤーは作成しません。 ここでは、各レイヤーは前のレイヤーとの違いのみを記録します。コンテナを作成すると、コンテナ レイヤーとも呼ばれる書き込み可能なレイヤーが作成されます。実行中のコンテナの内容に対する変更は、このレイヤーに記録されます。次の図は、この関係を示しています:
コンテナとイメージの主な違いは、トップレベルです。書き込みレイヤーは異なります。コンテナへのすべての書き込み操作はこのレイヤーに記録されます。コンテナが削除されると、書き込み可能なレイヤーも削除されますが、イメージは保持されます。
注: 複数のコンテナーで同じデータを共有する場合は、Docker ボリュームを使用できます。
各コンテナには独自の書き込み可能なレイヤーがあり、そこにすべての変換が保存されるため、複数のコンテナが同じイメージを共有できます。次の図は、この関係を示しています:
Note: ここには別の詳細があります。複数のミラー (2 つのミラーなど) が同じレイヤーを共有する場合があります。ビルドまたはプル時に同じレイヤーがローカルで見つかった場合、再度ビルドまたはプルされることはありません。そのため、イメージサイズを計算する際には、dockerimages
コマンドで表示されるサイズを単純に合計することはできず、実際の値よりも大きくなる可能性があります。
docker ps -s
コマンドを使用すると、コンテナーが占めるスペースを確認できます。実行中のコンテナ (部分値)。 2 つの列で表されるさまざまな内容:
コンテナがディスク領域を占有するその他の方法:
CoW 戦略では、最大限の効率でファイルを共有およびコピーできます。ファイルがイメージの下位レイヤーに存在する場合、その上位レイヤー (書き込み可能なレイヤーを含む) はコンテンツを読み取る必要があり、ファイルを直接使用できます。変更する必要がある場合、ファイルはこのレイヤーにコピーされて変更されます。これにより、IO と後続の各層のサイズが最小限に抑えられます。
4.1 共有するとイメージが小さくなります を使用してイメージをプルする場合、またはローカルで作成できないイメージを使用する場合コンテナーの場合、イメージはローカルの Dockers ストレージ領域に階層的に保存されます。 Linux では通常、/var/lib/docker
です。
ディレクトリに移動して、各レイヤーのイメージを取得したことを確認できます。たとえば、overlay2
ストレージ ドライバーを使用します。
非常に多くのレイヤーがあるため、
docker image Inspection を使用して、特定のイメージにどのレイヤーが含まれているかを確認できます<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">docker image inspect --format "{{json .RootFS.Layers}}" redis
docker image inspect --format "{{json .RootFS.Layers}}" mysql:5.7</pre><div class="contentsignin">ログイン後にコピー</div></div>
##上記のレビューを通じて、redis と mysql5.7 が同じレイヤーを使用していることがわかります。同じレイヤーを共有することで、ストレージ イメージのスペースが大幅に節約され、プルも向上します。ミラーリングの速度。
我们可以通过 docker image history
命令来查看镜像分层情况,以redis为例
docker history redis
注意 :
有些步骤的大小为0,是因为他们只改变了元数据,并不会产生新层,也不会占用额外的空间(除元数据本身)。所以上述redis镜像中包含了5层。
<missing></missing>
步骤,这些步骤可能是以下情况中的一种
当我们启动一个容器的时候,会添加一个可写层在镜像之上,用于存储所有的变化。当对已有文件进行修改的时候采用CoW策略。首先会到各层寻找到该文件,然后复制该文件到可写层,然后进行修改并存储。
这么做能够让我们最大限度地减少I/O操作。
但是,很明显的是当一个容器中的应用需要进行频繁的写操作,那么会造成可写层越来越庞大,此时我们可以通过Volume来帮助我们分担压力。
容器的元数据和日志是单独存放的,一般是存放在 /var/lib/docker/containers
中,我们可以使用 du -sh /var/lib/docker/containers/*
来查看各个容器占用多少。(容器ID其实就是文件夹名称的前12位)。
推荐学习:《docker视频教程》
以上がDocker を使用した階層的再利用のアイデアを 10 分で学べますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。