banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

【転載】Dockerイメージの原理

title: 【転載】Docker イメージの原理
date: 2021-08-16 09:24:01
comment: false
toc: true
category:

  • Docker
    tags:
  • 転載
  • Docker
  • イメージ
  • 原理

この記事は、Docker イメージの原理から転載されています。


Docker イメージの原理#

イメージは、ソフトウェアの実行環境とその環境に基づいて開発されたソフトウェアをパッケージ化するための軽量で実行可能な独立したソフトウェアパッケージです。これには、特定のソフトウェアに必要なすべての内容が含まれており、コード、ランタイムライブラリ、環境変数、設定ファイルなどが含まれます。

UnionFs(ユニオンファイルシステム)#

UnionFS(ユニオンファイルシステム):Union ファイルシステム(UnionFS)は、階層的で軽量かつ高性能なファイルシステムであり、ファイルシステムの変更を一度のコミットとして層ごとに重ね合わせることをサポートします。同時に、異なるディレクトリを同じ仮想ファイルシステムにマウントすることができます(unite several directories into a single virtual filesystem)。Union ファイルシステムは Docker イメージの基盤です。イメージは階層を通じて継承でき、基礎イメージ(親イメージがない)に基づいてさまざまな具体的なアプリケーションイメージを作成できます。 特性 :同時に複数のファイルシステムをロードできますが、外部から見ると 1 つのファイルシステムしか見えません。ユニオンロードは各層のファイルシステムを重ね合わせ、最終的なファイルシステムにはすべての下層のファイルとディレクトリが含まれます。

Docker イメージをダウンロードする際に、一層一層の実体は実際にはユニオンファイルシステムの表れです。

Docker イメージのロード原理#

Docker のイメージは実際には層ごとのファイルシステムで構成されており、この階層的なファイルシステムは UnionFS です。bootfs(ブートファイルシステム)は主にブートローダーとカーネルを含み、ブートローダーは主にカーネルを起動します。Linux が起動するとき、bootfs ファイルシステムがロードされ、Docker イメージの最下層は bootfs です。この層は、典型的な Linux/Unix システムと同じで、ブートローダーとカーネルを含みます。ブートが完了すると、カーネル全体がメモリにロードされ、この時点でメモリの使用権は bootfs からカーネルに移譲され、システムは bootfs をアンマウントします。

rootfs(ルートファイルシステム)は bootfs の上にあり、典型的な Linux システムの /dev、/proc、/bin、/etc などの標準ディレクトリとファイルを含みます。rootfs はさまざまな異なるオペレーティングシステムのディストリビューション、例えば Ubuntu や CentOS などです。

image

通常、私たちがインストールする仮想マシンの CentOS は数 GB ですが、なぜ Docker は数百 MB なのか。

簡素化された OS の場合、rootfs は非常に小さくできます。最も基本的なコマンド、ツール、ライブラリだけを含めればよく、基盤はホストのカーネルを直接使用するため、rootfs だけを提供すればよいのです。このように、異なる Linux ディストリビューションに対して、bootfs は基本的に一致し、rootfs には違いがあるため、異なるディストリビューションは bootfs を共有できます。

層の理解#

Docker イメージをダウンロードする際に、一層一層の実体は実際には層の最も直感的な表れです(すでにダウンロードされたものは再度ダウンロードされません)。

$ docker pull redis
Using default tag: latest
latest: Pulling from library/redis
33847f680f63: Already exists 
26a746039521: Pull complete
18d87da94363: Pull complete
5e118a708802: Pull complete
ecf0dbe7c357: Pull complete
46f280ba52da: Pull complete
Digest: sha256:cd0c68c5479f2db4b9e2c5fbfdb7a8acb77625322dd5b474578515422d3ddb59
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

以前の記事で言及した inspect コマンドを使用することもできます。

docker image inspect redis:latest

イメージの具体的な層情報が表示され、上記のイメージダウンロード時の 6 層に対応しています。

"RootFS": {
    "Type": "layers",
    "Layers": [
        "sha256:814bff7343242acfd20a2c841e041dd57c50f0cf844d4abd2329f78b992197f4",
        "sha256:dd1ebb1f5319785e34838c7332a71e5255bda9ccf61d2a0bf3bff3d2c3f4cdb4",
        "sha256:11f99184504048b93dc2bdabf1999d6bc7d9d9ded54d15a5f09e36d8c571c32d",
        "sha256:e461360755916af80821289b1cbc503692cf63e4e93f09b35784d9f7a819f7f2",
        "sha256:45f6df6342536d948b07e9df6ad231bf17a73e5861a84fc3c9ee8a59f73d0f9f",
        "sha256:262de04acb7e0165281132c876c0636c358963aa3e0b99e7fbeb8aba08c06935"
    ]
},

層の利点

最大の利点は - リソースの共有です。

例えば、複数のイメージが同じベースイメージから構築されている場合、Docker ホストはディスク上にベースイメージの 1 つだけを保存する必要があります。また、メモリ内にもベースイメージを 1 つだけロードすれば、すべてのコンテナにサービスを提供できます。そして、イメージの各層は共有可能です。

この時、誰かが質問するかもしれません:複数のコンテナが 1 つの基盤イメージを共有している場合、あるコンテナが基盤イメージの内容を変更した場合、例えば /etc のファイルが変更された場合、他のコンテナの /etc も変更されるのでしょうか? 答え:変更は単一のコンテナ内に制限されるため、変更されません。

これが、次に学ぶコンテナの Copy-on-Write 特性です。

コンテナの書き込み可能層#

コンテナが起動すると、新しい書き込み可能層がイメージの上にロードされます。この層は通常「コンテナ層」と呼ばれ、「コンテナ層」の下はすべて「イメージ層」と呼ばれます。すべての操作はコンテナ層に対して行われ、コンテナ層のみが書き込み可能で、コンテナ層の下のすべてのイメージ層は読み取り専用です。

image

commit イメージ#

docker commit  コンテナを新しいコピーとしてコミット

以下の例で説明します。

私は以前に tomcat のイメージをダウンロードしました。

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
tomcat       latest    710ec5c56683   7 days ago     668MB
redis        latest    aa4d65e670d6   3 weeks ago    105MB
mysql        latest    c60d96bd2b77   3 weeks ago    514MB
centos       centos7   8652b9f0cb4c   9 months ago   204MB

tomcat を起動します。

-- イメージを実行し、ポートをホストポートにマッピングします。
docker run  -it -p 8080:8080 tomcat

別のコマンドを使用して現在実行中のコンテナを確認すると、tomcat が実行中です。

$ docker ps
CONTAINER ID   IMAGE            COMMAND             CREATED          STATUS          PORTS                                       NAMES
8b294cd7074e   tomcat           "catalina.sh run"   29 seconds ago   Up 28 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   zealous_cohen
f42ae22e4b72   centos:centos7   "/bin/bash"         3 weeks ago      Up 46 hours                                                 centos-test

次に、tomcat コンテナに入ってみましょう。

docker exec -it 8b294cd7074e /bin/bash
$ docker exec -it 8b294cd7074e /bin/bash
root@8b294cd7074e:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work

次に、webapp(プロジェクトファイルの場所)に入ってみると、webapp は空であることがわかります。

root@8b294cd7074e:/usr/local/tomcat# cd webapps
root@8b294cd7074e:/usr/local/tomcat/webapps# ls
root@8b294cd7074e:/usr/local/tomcat/webapps#

次に、tomcat にアクセスすると、404 が表示され、tomcat は正常に起動していますが、対応するページが見つからないことがわかります。これは webapp が空であるため、理解しやすいです。

image

それでは、webapp に内容のあるイメージを作成してみましょう。

webapps.dist のファイルを webapp にコピーします。

root@8b294cd7074e:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@8b294cd7074e:/usr/local/tomcat# cd webapps
root@8b294cd7074e:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

変更後、tomcat に正常にアクセスできることがわかります。

image

$ docker ps
CONTAINER ID   IMAGE            COMMAND             CREATED          STATUS          PORTS                                       NAMES
8b294cd7074e   tomcat           "catalina.sh run"   27 minutes ago   Up 27 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   zealous_cohen

この tomcat は簡単な変更を加えました。私のこの tomcat は公式のものより少し良いと思いますので、このイメージをコミットします。

$ docker commit -a="cb" -m "add init file" 8b294cd7074e newtomcat:1.0
sha256:44cf4d44be664d9704a3fc38ddef1f03fa7f113ad83f4049cced322a14dc216b

docker images を通じて新しいイメージが作成されたことが確認でき、注意深く観察すると、私たちがコミットした newtomcat は公式の tomcat よりも少し大きいことがわかります。

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
newtomcat    1.0       44cf4d44be66   46 seconds ago   673MB
tomcat       latest    710ec5c56683   7 days ago       668MB
redis        latest    aa4d65e670d6   3 weeks ago      105MB
mysql        latest    c60d96bd2b77   3 weeks ago      514MB
centos       centos7   8652b9f0cb4c   9 months ago     204MB

今後は自分のイメージを直接使用したり、他の人に配布したりすることができます。これについては後で説明します。

この例を通じて、上記の層の考え方を振り返ることができます。newtomcat は、以前のコンテナ層で変更を加えた後に生成されたイメージであり、このイメージは仮想マシンのイメージスナップショットに似ています。

Docker のイメージについてはここまでです。今のところ、Docker は簡単に入門したと言えます。今後も Docker に関連する内容を学び続けますので、皆さんも一緒に頑張りましょう!

日々の努力は無駄にならず、最終的には海に入る。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。