これは、なにをしたくて書いたもの?
前にDockerのストレージについて見てみました。
Dockerのストレージ(コンテナデータの永続性)について学ぶ(Volumes、Bind mounts、tmpfs mounts) - CLOVER🍀
この時、Docker Daemonのストレージバックエンドについては扱いませんでした。今回はここを少しだけ見ておこうと
思います。
主にDocker Engine 29.0以降ではデフォルトのストレージバックエンドがcontainerdイメージストアになっていた
という話です。
Docker Daemonのストレージバックエンド
Docker Daemonのストレージバックエンドは、ここで少しだけ触れられています。
これらは、Dockerがコンテナイメージとコンテナレイヤーを保存する方法に関するものです。そして次の2つが
挙げられています。
- containerdイメージストア
- ストレージドライバー
containerdイメージストアという言葉に馴染みがなかったので、今回見てみようと思ったのがこのエントリーを
書き始めた動機です。
containerdイメージストア
containerdイメージストアのドキュメントはこちら。
containerd image store | Docker Docs
containerdイメージストアは、Docker Engine 29.0以降の新規インストールにおけるデフォルトの
ストレージバックエンドです。
The containerd image store is the default storage backend for Docker Engine 29.0 and later on fresh installations.
以前のバージョンからのアップグレードの場合は、引き続きレガシーなグラフドライバー(overlay2)が
使われ続けるとされています。
If you upgraded from an earlier version, your daemon continues using the legacy graph drivers (overlay2) until you enable the containerd image store.
overlay2がレガシー扱いということを知りませんでした…。
ちなみにDocker Engine 29.0のリリースがいつかというと、2025年11月10日なのでごくごく最近の話ですね。
Docker Engine version 29 release notes / 29.0.0
今回、containerd自体については深追いしないので、かなり薄いエントリーになります…。
containerdイメージストアを使うことで、コンテナイメージとコンテナデータはスナップショットを使用した保存
およびアクセス方法になるようです。
containerdイメージストアにより以下のことができるようになるとか。
- マルチプラットフォームイメージをローカルでビルド、保存可能
- 従来のストレージドライバーではマルチプラットフォームイメージには外部ビルダーが必要
- ProvenanceやSBOMを含むコンテナイメージの操作ができるようになる
- 従来のストアではサポートしていないイメージインデックスを使用するため
- WebAssemblyワークロードをサポートしているため、Wasmコンテナを実行できる
- イメージの遅延Pull(stargz)、Peer-to-Peerのイメージ配布(nydus、dragonfly)などの機能を提供するプラガブルなスナップショットツールのサポート
containerd image store with Docker Engine / Why use the containerd image store
ちなみにディスク使用量は増加するようです。
containerd image store with Docker Engine / Disk space usage
これはなぜかというと、containerdはイメージを圧縮形式と非圧縮形式の両方を保存するのに対して、レガシーな
ストレージドライバーは非圧縮レイヤーのみを保存していたからです。
The containerd image store uses more disk space than the legacy storage drivers for the same images. This is because containerd stores images in both compressed and uncompressed formats, while the legacy drivers stored only the uncompressed layers.
つまり、containerdイメージストアでは二重にデータを持っていることになります。圧縮形式の利点はPullとPushの
高速化になるようですね。
containerdイメージストアが圧縮形式と非圧縮形式の両方を持つというのは、複数のイメージが同じベースイメージを
共有する場合に特に顕著に違いとして現れるようです。
従来のストレージドライバーでは共有されるベースレイヤーは1度ローカルに保存されると再利用されていたのに
対して、containerdでは非圧縮レイヤーはスナップショットにより重複排除されるものの圧縮レイヤーについては
各イメージが個別に保存する振る舞いになるようです。
つまり、同じベースイメージを共有するイメージが増えるとオーバーヘッドが追加されていくことを意味します。
containerdイメージストアを有効にするには、/etc/docker/daemon.jsonに以下のように設定して
{ "features": { "containerd-snapshotter": true } }
Docker Daemonを再起動します。
$ sudo systemctl restart docker
containerd image store with Docker Engine / Enable containerd image store on Docker Engine
docker infoで見た時に、Storage Driverが「overlayfs」、driver-typeが「io.containerd.snapshotter.v1」
となっていればcontainerdイメージストアが有効になっています。
$ docker info | grep -E 'Storage Driver|driver-type' Storage Driver: overlayfs driver-type: io.containerd.snapshotter.v1 $ docker info -f '{{ .Driver}} {{ .DriverStatus }}' overlayfs [[driver-type io.containerd.snapshotter.v1]]
従来のストレージドライバーからの実験的な自動移行機能もあるようですが、推奨としては最初から構築しなおすことに
なっているようです。
containerd image store with Docker Engine / Experimental automatic migration
ストレージドライバー
従来のストレージドライバーについてのドキュメントはこちら。
ストレージドライバーはイメージレイヤーの保存と、コンテナの書き込み可能なレイヤーにデータを保存する際に
使われます。
Storage drivers / Storage drivers versus Docker volumes
コンテナの書き込み可能なレイヤーはコンテナが終了すると破棄されます。
ストレージドライバーはスペース効率に最適化されているとされていますが、選択したストレージドライバーによっては
書き込み速度がネイティブファイルシステムのパフォーマンスよりも悪くなります。特にコピーオンライトを
使用するストレージドライバーの場合は顕著になるようです。
よって、書き込み負荷が高いデータやコンテナが終了しても保持する必要があるデータ、コンテナ間で共有する
必要があるデータについてはボリュームを使用することになります。
こちらでは、Dockerfileでのファイルシステムを変更するコマンドはレイヤーを作成することが書かれています。
FROMでレイヤーが作成され、COPYやRUNで変更されていきます。
Storage drivers / Images and layers
LABELやCMDはイメージのメタデータのみを変更するため、レイヤーは作成されません。
こちらはイメージとコンテナの違いで、コンテナには最上位に書き込み可能なレイヤーが存在することが
挙げられます。
Storage drivers / Container and layers
イメージを構成するレイヤーの数を把握するには、以下のコマンドを実行するとよさそうです。
$ docker image inspect --format "{{json .RootFS.Layers}}" [イメージ名] | jq
こういう感じになります。
[ "sha256:72e830a4dff5f0d5225cdc0a320e85ab1ce06ea5673acfe8d83a7645cbd0e9cf", "sha256:07b4a9068b6af337e8b8f1f1dae3dd14185b2c0003a9a1f0a6fd2587495b204a" ]
また以下のようにdocker image historyでイメージが作られる際のステップを確認することもできます。
$ docker image history ubuntu:24.04 IMAGE CREATED CREATED BY SIZE COMMENT c35e29c94501 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 2 months ago /bin/sh -c #(nop) ADD file:ddf1aa62235de6657… 87.6MB <missing> 2 months ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B <missing> 2 months ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B <missing> 2 months ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B <missing> 2 months ago /bin/sh -c #(nop) ARG RELEASE 0B
ストレージドライバーは以下の種類があります。
- OverlayFS(overlay2)
- OverlayFS storage driver | Docker Docs
- 従来のデフォルトのストレージドライバー
- BTRFS
- ZFS
- VFS
- windowsfilter
Select a storage driver | Docker Docs
各ストレージドライバーを有効にする方法には触れませんが、OverlayFS(overlay2)だけ取り上げておくと
/etc/docker/daemon.jsonに以下のように設定して、Docker Daemonを再起動すればOKです。
{ "storage-driver": "overlay2" }
docker infoには以下のような表示が含まれます。
Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false
もしくはこうですね。
$ docker info -f '{{ .Driver}} {{ .DriverStatus }}' overlay2 [[Backing Filesystem extfs] [Supports d_type true] [Using metacopy false] [Native Overlay Diff true] [userxattr false]]
OverlayFS storage driver / Configure Docker with the overlay2 storage driver
OverlayFSの仕組みはこちら。時々見かける/var/lib/docker/overlay2などが出てきます。
OverlayFS storage driver / How the overlay2 driver works
ドキュメントを見るのは今回はこれくらいにしておくのですが、あとはコンテナイメージがcontainerdイメージストアに
保存されているようになっていることを見ておきましょうか。
環境
今回の環境はこちら。
$ docker version Client: Docker Engine - Community Version: 29.1.3 API version: 1.52 Go version: go1.25.5 Git commit: f52814d Built: Fri Dec 12 14:49:32 2025 OS/Arch: linux/amd64 Context: default Server: Docker Engine - Community Engine: Version: 29.1.3 API version: 1.52 (minimum version 1.44) Go version: go1.25.5 Git commit: fbf3ed2 Built: Fri Dec 12 14:49:32 2025 OS/Arch: linux/amd64 Experimental: false containerd: Version: v2.2.1 GitCommit: dea7da592f5d1d2b7755e3a161be07f43fad8f75 runc: Version: 1.3.4 GitCommit: v1.3.4-0-gd6d73eb8 docker-init: Version: 0.19.0 GitCommit: de40ad0
containerd。
$ containerd --version containerd containerd.io v2.2.1 dea7da592f5d1d2b7755e3a161be07f43fad8f75 $ ctr --version ctr containerd.io v2.2.1
ctrというのはcontainerd CLIです。
$ ctr --help NAME: ctr - __ _____/ /______ / ___/ __/ ___/ / /__/ /_/ / \___/\__/_/ containerd CLI USAGE: ctr [global options] command [command options] VERSION: v2.2.1 DESCRIPTION: ctr is an unsupported debug and administrative client for interacting with the containerd daemon. Because it is unsupported, the commands, options, and operations are not guaranteed to be backward compatible or stable from release to release of the containerd project. COMMANDS: plugins, plugin Provides information about containerd plugins version Print the client and server versions containers, c, container Manage containers content Manage content events, event Display containerd events images, image, i Manage images leases Manage leases namespaces, namespace, ns Manage namespaces pprof Provide golang pprof outputs for containerd run Run a container snapshots, snapshot Manage snapshots tasks, t, task Manage tasks install Install a new package oci OCI tools sandboxes, sandbox, sb, s Manage sandboxes info Print the server info deprecations shim Interact with a shim directly help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug Enable debug output in logs (default: false) --address value, -a value Address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS] --timeout value Total timeout for ctr commands (default: 0s) --connect-timeout value Timeout for connecting to containerd (default: 0s) --namespace value, -n value Namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE] --help, -h Show help (default: false) --version, -v Print the version (default: false)
containerdイメージストアが使われている環境です。
$ docker info -f '{{ .Driver}} {{ .DriverStatus }}' overlayfs [[driver-type io.containerd.snapshotter.v1]]
containerdイメージストアが使われているかどうか見てみる
コンテナイメージをPullしてみます。ここではubuntu:24.04を対象としましょう。
$ docker image pull ubuntu:24.04
確認。
$ docker image ls i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA ubuntu:24.04 c35e29c94501 119MB 31.7MB
このコンテナイメージをcontainerd側でも確認できます。
namespaceを確認すると、「moby」というnamespaceがあります。
$ sudo ctr namespaces list NAME LABELS moby
containerdでイメージの一覧を確認してみます。
$ sudo ctr --namespace moby images list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/library/ubuntu:24.04 application/vnd.oci.image.index.v1+json sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54 28.4 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x -
すると、先ほどdocker image pullしたubuntu:24.04のコンテナイメージと同じハッシュ値が確認できます。
しかもプラットフォーム数が多いですね。これがマルチプラットフォームイメージを保存可能という
ことなのでしょう。
OverlayFSストレージドライバー環境で見てみる
ところで、OverlayFSストレージドライバー環境だとどうなるのでしょう。
コンテナイメージをPull。
$ docker image pull ubuntu:24.04
コンテナイメージの一覧。
$ docker image ls i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA ubuntu:24.04 c3a134f2ace4 78.1MB 0B
よくよく見ると、表示がすでに違いますね。containerdイメージストアの場合はこうでした。
$ docker image ls i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA ubuntu:24.04 c35e29c94501 119MB 31.7MB
確かにcontainerdイメージストアを使った方がディスクサイズは大きいようです。
OverlayFSストレージドライバー環境でcontainerdでイメージの一覧を見ても、当然ながら空っぽです。
$ sudo ctr --namespace moby images list
REF TYPE DIGEST SIZE PLATFORMS LABELS
containerdイメージストアでのコンテナイメージはどこに?
ちょっと気になるのが、containerdイメージストアでのコンテナイメージはどこに保存されているのか?という
ところなのですが。
docker infoでこのように表示される環境であれば
Storage Driver: overlayfs driver-type: io.containerd.snapshotter.v1
/var/lib/containerd/io.containerd.snapshotter.v1.overlayfsディレクトリーにあるみたいですね。
しかもファイルが見れそうな感じがします。
$ sudo cat /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/88/fs/etc/os-release PRETTY_NAME="Ubuntu 24.04.3 LTS" NAME="Ubuntu" VERSION_ID="24.04" VERSION="24.04.3 LTS (Noble Numbat)" VERSION_CODENAME=noble ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=noble LOGO=ubuntu-logo
これが「非圧縮レイヤーはスナップショットで管理される」ということなのでしょうか。
まあ、このあたりはまた機会があれば…。
オマケ
OverlayFSストレージドライバーを使っている既存の環境から再構築して移行する場合は、Docker Engine自体を
再インストールするだけではなくて/var/lib/dockerディレクトリーごと削除した方がよさそうです。
$ sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin $ sudo rm -rf /var/lib/docker $ sudo rm -rf /var/lib/containerd $ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Install Docker Engine on Ubuntu / Uninstall Docker Engine
自分の環境だと、再インストールしてもOverlayFSストレージドライバーのままだったのでなんでだろう?と
思いました。
おわりに
Docker Daemonのストレージバックエンドについて見てみました。
かなり最近、デフォルトのストレージバックエンドが変更されていたんですね。ちょっと驚きました。
それにcontainerdの世界をほんの少しだけとはいえ見ることになるとは思っていませんでしたよ。
ストレージドライバーについてもほとんど見てきていなかったので、良い勉強の機会になりました。