背景
この前、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]#
コメント欄