サイドバーの壁紙
博主头像
tin博主等级

子の曰わく、我れ三人行なえば必ず我が師を得(う)。其の善き者を択びてこれに従う。其の善からざる者にしてこれを改む。

  • 累積執筆 73 記事
  • 累計作成 32 タグ
  • 累計受入 2 コメント

目 次CONTENT

記事目次

docker commit、docker export、docker saveの違いと使い分け

tin
tin
2023-03-03 / 0 コメント / 5 いいね! / 277 読み / 2,619 文字

背景

この前、docker commitの操作をしました。
今回はdockerのバックアップ及びリストアの際によく使われているdocker exportとdocker saveについて話します。
また、docker commitとdocker exportとdocker saveの違いについても整理してみます。

1. 簡単紹介

- docker commit

コンテナから新しいイメージを作成するコマンドです。
使用例:
コンテナ内の変更を新しいDockerイメージとしてコミットする場合
デバッグや開発中に、変更を加えたコンテナを新しいイメージとして保存する場合

- docker export

コンテナ内のファイルシステムをtarアーカイブとしてエクスポートするコマンドです。
使用例:
コンテナ内で実行された特定のプログラムやコマンドの出力を保存する場合
コンテナ内で生成されたファイルやデータをエクスポートし、別の環境で再利用する場合

- docker save

Dockerイメージをtarアーカイブとして保存するコマンドです。
ヒント:tarアーカイブになると、自由に別の端末にコピーできますね。
使用例:
Dockerイメージ全体を保存して、他のホストで再利用する場合
Dockerイメージを外部のレジストリにアップロードする場合
バージョン管理のためにDockerイメージを保存する場合

2. 入出力から三者を見比べる

コマンド 入力 出力
docker commit コンテナ イメージ
docker export コンテナ アーカイブファイル(.tarなど)。また、docker importで「.tar」からイメージを生成できる
docker save イメージ アーカイブファイル(.tarなど)。また、docker loadで「.tar」からイメージを生成できる

👆上記の内容でdocker commitとdocker exportとdocker saveの違いを理解できれば、おめでとうございます!
三者各自の入力と出力を見て、なんとなくみんなの違いを判断ですますが、実は、目に見えない違いは三者の中に潜んでいます。次は質問と回答からさらに深掘ります。

3. 質問と回答

3-1. QAその1(ヒント:レイヤー情報)

◆質問:

「docker export⇒docker import」のコマンドでもイメージを作成できますが、出来たイメージと「docker commit 」による生まれたイメージとは違いがありますか。

◆回答:

違いがあります。
docker export と docker import を使用してイメージを作成する場合、元のコンテナのレイヤー情報は失われます。
これは、 docker export がコンテナを単一のtarアーカイブにまとめるため、レイヤー情報を除外するためです。
つまり、イメージは1つのレイヤーのみで構成されます。変更履歴が保持できません。

一方、 docker commit によって生成されたイメージは、元のイメージのレイヤー情報を維持します。このため、元のイメージの変更履歴やレイヤー情報が保持され、新しいイメージを作成する際に役立ちます。

また、後ろのデモの結果から見れば、元コンテナ内に追加&変更のあったファイルは2種類の新イメージにも含まれています。(注意:後ろのデモにおいて、追加&変更のあったファイルはVolumes、Bind mountsでホスト側にマウントされていない。マウント(mount)を実施する場合、結果は変わるかもしれません。

デモ(nginxのcommitとexport)

①nginxイメージのレイヤー情報を確認(レイヤー6階層)
[root@localhost home]# docker inspect  nginx:latest
[
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:650abce4b096b06ac8bec2046d821d66d801af34f1f1d4c5e272ad030c7873db",
                "sha256:4dc5cd799a08ff49a603870c8378ea93083bfc2a4176f56e5531997e94c195d0",
                "sha256:e161c82b34d21179db1f546c1cd84153d28a17d865ccaf2dedeb06a903fec12c",
                "sha256:83ba6d8ffb8c2974174c02d3ba549e7e0656ebb1bc075a6b6ee89b6c609c6a71",
                "sha256:d8466e142d8710abf5b495ebb536478f7e19d9d03b151b5d5bd09df4cfb49248",
                "sha256:101af4ba983b04be266217ecee414e88b23e394f62e9801c7c1bdb37cb37bcaa"
            ]
        }
]
[root@localhost home]# 
②コンテナを新規⇒コンテナ内にディレクトリとファイルを1個新規⇒commit

⇒新イメージmynginx:2.1は生まれる

[root@localhost home]# docker run --name=nginx-1 -d nginx
9d930c5bc00be586e48720fa88c054e1f8375ec5f8bd751242878c9a46d4a24f
[root@localhost home]# docker exec -it  nginx-1 bash
root@9d930c5bc00b:/# mkdir demo //ディレクトリを新規
root@9d930c5bc00b:/# echo "test commit" > /demo/demo.txt //ファイルを新規
root@9d930c5bc00b:/# ls -l /demo/demo.txt
-rw-r--r--. 1 root root 12 Mar  5 09:35 /demo/demo.txt
root@9d930c5bc00b:/# 
root@9d930c5bc00b:/# exit 
exit
[root@localhost home]# docker commit -m="new file to commit" -a=tin 9d930c5bc00b mynginx:2.1 //commitして、新イメージ名:「mynginx:2.1」
sha256:02a2fed6d3840eead29024d6618819d38fd030b7a4c447c8650837246ae9fe9f
[root@localhost home]# 
[root@localhost home]# docker images | grep nginx
mynginx      2.1       02a2fed6d384   22 seconds ago   142MB  //新イメージ
nginx        latest    904b8cb13b93   3 days ago       142MB

③新イメージmynginx:2.1のレイヤー情報を確認

⇒レイヤーは1個追加され、7階層となりました。

[root@localhost home]# 
[root@localhost home]# docker inspect mynginx:2.1  //新イメージの情報(レイヤー情報を抜粋)を確認
[
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:650abce4b096b06ac8bec2046d821d66d801af34f1f1d4c5e272ad030c7873db",
                "sha256:4dc5cd799a08ff49a603870c8378ea93083bfc2a4176f56e5531997e94c195d0",
                "sha256:e161c82b34d21179db1f546c1cd84153d28a17d865ccaf2dedeb06a903fec12c",
                "sha256:83ba6d8ffb8c2974174c02d3ba549e7e0656ebb1bc075a6b6ee89b6c609c6a71",
                "sha256:d8466e142d8710abf5b495ebb536478f7e19d9d03b151b5d5bd09df4cfb49248",
                "sha256:101af4ba983b04be266217ecee414e88b23e394f62e9801c7c1bdb37cb37bcaa",
                "sha256:5d7e5f231c1e6aeee3dcbdbf39817f9e0238ab434fb0800d93154da47b809c2b"  //これは、追加されたレイヤーです。
            ]
        }
]
④新イメージmynginx:2.1で起動したコンテナを確認。

⇒追加したファイルが存在します。

[root@localhost home]# 
[root@localhost home]# docker run -it mynginx:2.1 bash       //新イメージでコンテナを新規
root@2721285f7f48:/# 
root@2721285f7f48:/# ls
bin  boot  demo  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
root@2721285f7f48:/# 
root@2721285f7f48:/# ls -l demo
total 4
-rw-r--r--. 1 root root 12 Mar  5 09:35 demo.txt                //追加されたファイルは存在します

⑤同じコンテナから「docker export⇒docker import」を実行

⇒新イメージmynginx:3.1が生まれる

[root@localhost work]# docker ps
CONTAINER ID   IMAGE         COMMAND                   CREATED             STATUS             PORTS     NAMES
2721285f7f48   mynginx:2.1   "/docker-entrypoint.…"   About an hour ago   Up About an hour   80/tcp    modest_villani
9d930c5bc00b   nginx         "/docker-entrypoint.…"   About an hour ago   Up About an hour   80/tcp    nginx-1
1e28fd489bea   ubuntu        "bash"                    44 hours ago        Up 44 hours                  serene_khayyam
[root@localhost work]# 
[root@localhost work]# docker export nginx-1 > demo.tar
[root@localhost work]# ll
合計 140984
-rw-r--r--. 1 root root 144364544  3月  5 20:02 demo.tar
[root@localhost work]# 
[root@localhost work]# tar tf demo.tar | grep demo
demo/
demo/demo.txt
[root@localhost work]# 
[root@localhost work]# docker import demo.tar mynginx:3.1
sha256:d0b262b543ae77354ae463ee0551a64812eda9554b0023974d0ee9b7ad7d5af7
[root@localhost work]# 
[root@localhost work]# docker images | grep nginx
mynginx      3.1       d0b262b543ae   11 seconds ago      140MB   //「docker export⇒docker import」で出来た新イメージ
mynginx      2.1       02a2fed6d384   About an hour ago   142MB   // 「docker commit」で出来た新イメージ
nginx        latest    904b8cb13b93   3 days ago          142MB
[root@localhost work]# 
⑥新イメージmynginx:3.1のレイヤー情報を確認

⇒レイヤーは1つだけとなりました。

[root@localhost work]# docker inspect mynginx:3.1   //「docker import」で出来た新イメージの情報を確認
[
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:d1f05c59f705eaeb78a8d8f4d1ffa12d9056ee672b584f344b31692281e19bc3"  //レイヤーは1つのみになった
            ]
        }
]
[root@localhost work]# 

⑦新イメージmynginx:3.1で起動したコンテナを確認

⇒追加したファイルは存在します。

[root@localhost work]# docker run -it mynginx:3.1 bash
root@de30e18022dc:/# ls
bin  boot  demo  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
root@de30e18022dc:/# 
root@de30e18022dc:/# ls -l /demo/demo.txt 
-rw-r--r--. 1 root root 12 Mar  5 09:35 /demo/demo.txt
root@de30e18022dc:/# 

補足:docker saveとdocker loadのデモ

⇒アーカイブ化の元イメージと同じく:
①7階層のレイヤーの構造
②追加したファイルは存在。しかし、tar -tfで追加ファイルの存在確認は不能。一方、docker exportで出来たtarファイルでは可能。

[root@localhost work]# docker save mynginx:2.1 > demo-save.tar
[root@localhost work]# ls -l
合計 283840
-rw-r--r--. 1 root root 146284544  3月  5 21:07 demo-save.tar
-rw-r--r--. 1 root root 144364544  3月  5 20:37 demo.tar
[root@localhost work]# tar tf demo-save.tar | grep demo   //docker saveで作成したアーカイブファイル
[root@localhost work]#                    //追加ファイルの存在確認は不能
[root@localhost work]# tar tf demo.tar | grep demo   //docker exportで作成したアーカイブファイル
demo/                                                 //追加ファイルの存在確認は可能
demo/demo.txt
[root@localhost work]# 
[root@localhost work]# docker images | grep nginx
mynginx      3.1       d0b262b543ae   About an hour ago   140MB
mynginx      2.1       02a2fed6d384   3 hours ago         142MB
nginx        latest    904b8cb13b93   3 days ago          142MB
[root@localhost work]# 
[root@localhost work]# docker rmi -f mynginx:2.1
Untagged: mynginx:2.1
Deleted: sha256:02a2fed6d3840eead29024d6618819d38fd030b7a4c447c8650837246ae9fe9f
Deleted: sha256:c3e07abe1e6c23e8f85b89cddb9160f81b046b71cb0b30cf21a5f060509c1a7c 
[root@localhost work]# 
[root@localhost work]# docker load < demo-save.tar 
5d7e5f231c1e: Loading layer [==================================================>]  16.38kB/16.38kB
Loaded image: mynginx:2.1
[root@localhost work]# 
[root@localhost work]# docker images | grep nginx
mynginx      3.1       d0b262b543ae   About an hour ago   140MB
mynginx      2.1       02a2fed6d384   3 hours ago         142MB
nginx        latest    904b8cb13b93   3 days ago          142MB
[root@localhost work]# docker inspect mynginx:2.1
[
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:650abce4b096b06ac8bec2046d821d66d801af34f1f1d4c5e272ad030c7873db",
                "sha256:4dc5cd799a08ff49a603870c8378ea93083bfc2a4176f56e5531997e94c195d0",
                "sha256:e161c82b34d21179db1f546c1cd84153d28a17d865ccaf2dedeb06a903fec12c",
                "sha256:83ba6d8ffb8c2974174c02d3ba549e7e0656ebb1bc075a6b6ee89b6c609c6a71",
                "sha256:d8466e142d8710abf5b495ebb536478f7e19d9d03b151b5d5bd09df4cfb49248",
                "sha256:101af4ba983b04be266217ecee414e88b23e394f62e9801c7c1bdb37cb37bcaa",
                "sha256:5d7e5f231c1e6aeee3dcbdbf39817f9e0238ab434fb0800d93154da47b809c2b"
            ]
       }
]
[root@localhost work]# 
[root@localhost work]# docker run -it mynginx:2.1 bash
root@5543b358f8d9:/# ls
bin  boot  demo  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
root@5543b358f8d9:/# 
root@5543b358f8d9:/# ls -l demo  //tar -tfで存在確認できないものの、起動したコンテナの中に確認できた
total 4
-rw-r--r--. 1 root root 12 Mar  5 09:35 demo.txt
root@5543b358f8d9:/# 
[root@localhost work]# 



5
  • 5

コメント欄