1. ホーム
  2. ドッカー

docker saveとdocker exportの違いについて

2022-03-03 16:45:31

http://cnodejs.org/topic/59a2304f7aeedce818249eeb

原点

docker save と docker export はどちらもイメージパッケージをエクスポートできるので、大きな違いはないように思われます。この記事ではこの疑問を解決するために、docker save と docker export が何をするものなのかを考えてみます。これらはどのようなアプリケーションシナリオに適用されるのでしょうか?

<スパン *注意: ユーザーは docker load を使ってミラーストアファイルをローカルのミラーリポジトリにインポートするか、 docker import を使ってコンテナスナップショットをローカルのミラーリポジトリにインポートするかのどちらかを選択することができます。両者の違いは、コンテナ・スナップショット・ファイルは履歴やメタデータ情報をすべて破棄する(つまり、その時点のコンテナのスナップショット状態のみが保存される)のに対し、ミラーストア・ファイルは全レコードを保存し、サイズも大きくなる点です。また、コンテナ・スナップショット・ファイルからインポートする場合、タグなどのメタデータ情報を再割り当てすることができる。 <スパン

本記事で検証したDockerのバージョンは以下の通りですが、すべてのバージョンのDockerで本記事の結果が再現されることを保証するものではありません。

>docker version

Client:
 Version: 17.07.0-ce-rc1
 API version: 1.31
 Go version: go1.8.3
 Git commit: 8c4be39
 Built: Wed Jul 26 05:19:44 2017
 OS/Arch: windows/amd64

Server:
 Version: 17.07.0-ce-rc1
 API version: 1.31 (minimum version 1.12)
 Go version: go1.8.3
 Git commit: 8c4be39
 Built: Wed Jul 26 05:25:01 2017
 OS/Arch: linux/amd64
 Experimental: true

また、Windowsからbashでdockerを操作しているのですが、以下のようなコマンドもあります。 ls はWindowsのコマンドではないので、私の実験を再現したい場合は、適切なWindowsのコマンドに切り替えてください。

ドッカーセーブ

docker のコマンドラインインターフェースはエレガントに設計されており、多くのコマンドのヘルプの後に直接 --help と表示することができます。

docker saveのヘルプは以下の通りです。

>docker save --help

Usage: docker save [OPTIONS] IMAGE [IMAGE...]

Save one or more images to a tar archive (streamed to STDOUT by default)

Options:
      --help Print usage
  -o, --output string Write to a file, instead of STDOUT

コマンドラインヘルプを見ればわかるように、docker saveは1つまたは複数のイメージをパッケージ化して保存するためのツールです。

例えば、イメージリポジトリからpostgresとmongoをパッケージ化したい場合は、次のように実行します。

docker save -o images.tar postgres:9.6 mongo:3.4

パッケージの後 images.tar には postgres:9.6 mongo:3.4 この2つのミラー

コマンドライン引数ではイメージを指定する必要がありますが、実際にはコンテナをパッケージ化することも可能で、例えば次のようになります。

>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3623943d369f postgres:9.6 "docker-entrypoint... " 3 hours ago Up 3 hours 5432/tcp postgres

>docker save -o b.tar postgres
>docker save -o c.tar postgres:9.6
>ls -al
-rwxrwxrwx 1 root root 277886464 Aug 26 14:40 b.tar
-rwxrwxrwx 1 root root 277886464 Aug 26 14:41 c.tar

上記のコマンドからわかるように b.tar c.tar は全く同じです。つまり、docker save がコンテナを指定した場合、docker save はコンテナの後ろにある画像を保存することになります。

パッケージ化された画像を docker load で読み込む、など。

docker load -i images.tar

上記のコマンドは postgres:9.6 mongo:3.4 が読み込まれ、ローカルのミラーリポジトリにすでに存在する場合は上書きされます。

docker save のシナリオは、アプリケーションが docker-compose.yml を使用してオーケストレーションされた複数のイメージの組み合わせであり、デプロイ先のクライアントサーバーがエクストラネットに接続されていない場合です。この場合、docker save を使用して使用するイメージをパッケージ化し、それをクライアントサーバーにコピーして docker load を使用してロードします。

ドッカーエクスポート

通常通り、docker exportのヘルプを確認してください。

>docker export --help

Usage: docker export [OPTIONS] CONTAINER

Export a container's filesystem as a tar archive

Options:
      --help Print usage
  -o, --output string Write to a file, instead of STDOUT

ヘルプを見ればわかるように、docker exportはコンテナのファイルシステムをパッケージ化するために使用されます。例えば

docker export -o postgres-export.tar postgres

docker exportはコンテナを指定する必要があり、docker saveのようにイメージとコンテナのどちらかを指定することはできません。

パックされたコンテナを docker import で読み込む、など。

docker import postgres-export.tar postgres:latest

上記のコマンドからわかるように、docker importはコンテナに戻すのではなく、イメージとしてインポートします。

もう一つのポイントは、docker importではIMAGE[:TAG]を指定できることで、イメージに新しい名前を指定できることを表しています。同じ名前のミラーがすでにローカルのミラーリポジトリに存在する場合、元のミラーの名前は取り除かれ、新しいミラーに割り当てられます。元のミラーはゴーストとなり、IMAGE ID によってのみ操作できるようになります。

例えば、ubuntuのイメージからコンテナを起動し、いくつかのソフトウェアをインストールし、いくつかの設定を行った後、docker exportを使用してベースイメージとして保存する場合。そして、そのイメージを他の人に配布し、例えば開発環境のベースとすることができます。

docker saveとdocker exportの違いについて

docker saveとdocker exportの違いをまとめると。

  1. docker save はイメージを保存し、docker export はコンテナを保存します。
  2. docker load でイメージパッケージの読み込み、docker import でコンテナパッケージの読み込みを行いますが、どちらもイメージに戻されます。
  3. docker load は読み込んだイメージの名前を変更できませんが、 docker import はイメージに新しい名前を指定することができます。

ブレーンストーミング

前節は、公式ドキュメントをよく見ている読者なら知っているであろう、基本的なことばかりでした。このセクションでは、ドキュメントに書かれていないことについてお話します。

docker load と docker import はどちらも tarball をイメージとしてインポートできるので、docker load は docker export コンテナパッケージを、docker import は docker save イメージパッケージをインポートできるのでしょうか?

では、以下の2つのファイルを用意して実験を始めてみましょう。

>ls -al
-rwxrwxrwx 1 root root 271760384 Aug 26 12:15 postgres-export.tar
-rwxrwxrwx 1 root root 398292480 Aug 26 12:13 postgres-save.tar


ここで postgres-export.tar はdocker exportでエクスポートされたコンテナパッケージで postgres-save.tar は docker save で保存されたイメージパッケージで、どちらも postgres:9.6 画像になります。ファイルサイズから視覚的にわかるように postgres-export.tar の方が明らかに大きいです。 postgres-save.tar は100M以上小さい。

次に、docker load コンテナパッケージを試してみましょう。 postgres-export.tar :

>docker load -i postgres-export.tar
open /var/lib/docker/tmp/docker-import-082344818/bin/json: no such file or directory

どうやら、docker load はコンテナ・パッケージをロードできないようです。

では逆に、docker importはイメージパッケージを読み込むことができるのでしょうか?

>docker import postgres-save.tar postgres
sha256:8910feec1ee2fac8c152dbdd0aaab360ba0b833af5c3ad59fcd648b9a24d4838
>docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres latest 8910feec1ee2 2 minutes ago 398MB

うわーん、うまくいったーーーー。

慌てずに、もう一度postgresコンテナを起動してみてください。

>docker run postgres
C:\Program Files\Docker\Docker\resources\bin\docker.exe: Error response from daemon: No command specified.
See 'C:\Program Files\Docker\Docker\resources\bin\docker.exe run --help'.

画像として正常に取り込まれましたが、画像は使用できません。

何が起こっているのかを知るために、ミラーパッケージとコンテナパッケージの違いを見てみましょう。

上から見てわかるように、右の postgres-export.tar はlinuxのシステムファイルのディレクトリで、linuxのイメージと思われる。そして postgres-save.tar 中身は一体何なのでしょうか?フォルダをクリックして見てください。

Dockerのイメージは、実はレイヤー型のファイルシステムで、ファイルの層が重なっており、上の層のファイルは下の層の同名のファイルを上書きしていきます。もしあなたが postgres-save.tar の場合、イメージ内のファイルのレイヤーはマージされるため、基本的には postgres-export.tar の中身は、「曖昧」なので postgres-save.tar は、中のレイヤーに多くの重複ファイルが存在することになり、そのために postgres-save.tar よりも多くの重複ファイルを持つことになります。 postgres-export.tar は100M以上大きい。

docker loadが読み込まなければならないのは、階層型ファイルシステムであり postgres-export.tar はそのような構造を持っていないため、読み込むことができません。

docker importはtarball内のファイルをコピーするだけなので、tarball内のファイルの構造がどうであれ、読み込むことは可能です。 postgres-save.tar . しかし postgres-save.tar は有効なOSイメージではないので、別のイメージでコンテナを起動しようとすると、コンテナは起動しません。

docker importのヘルプに戻りましょう。

Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

Import the contents from a tarball to create a filesystem image

Options:
  -c, --change list Apply Dockerfile instruction to the created image
      --help Print usage
  -m, --message string Set commit message for imported image

docker commit とよく似ているようです。

Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

Options:
  -a, --author string Author (e.g., "John Hannibal Smith
                         
 Found that both docker import and docker commit have
--change
and
--message
options. We can think of docker import as copying in external files to form an image with one layer of filesystems, and docker commit as committing the current changes to one layer of filesystems and then overlaying it on top of the original image.
 The difference between docker save and docker export is pretty much covered, so bye bye.

--change