LoginSignup
42
38

More than 3 years have passed since last update.

[Docker] containerが使ってる全てのvolumeをCSV出力するワンライナー

Last updated at Posted at 2019-03-31

これは何?

  • dockerやdocker-composeで多くのコンテナを動かすと、「このvolumeは、どのconteinerで使ってるんだ?」と悩むことがあります。
  • 当初は docker volume inspect <ボリューム名> で、調べられるんじゃないかと思っていたのですが、残念ながらこの方法では「そのvolumeが、どのcontainerで使われているか」は表示されませんでした。
  • 代わりに Dockerfile や docker-compose.yml を grep したり、docker container inspect <コンテナ名> で調べてましたが、毎回これをするのは手間がかかります。

解決方法

  • ワンライナーを考えました。以下の通りです。
    • jq を使ってますので、事前に apt install jq などしておいてください。
    • 出力はCSVで、Name(コンテナ名)、Type(bind or volume)、Src(ホストリソース)、Dst(コンテナ側リソース) の順です。
      • Type=bind は、ホストのファイル(フォルダ)をコンテナへマウント
      • Type=volumeは、ボリュームをコンテナへマウントを意味します。
$ docker ps -a --format "{{.Names}}" | xargs docker inspect | jq -r '["Name","Type","Src","Dst"], (.[] | { Name:.Name, Mounts:.Mounts[] } | [ .Name, .Mounts.Type, .Mounts.Source, .Mounts.Destination ]) | @csv' 
"Name","Type","Src","Dst"
"/c4x","bind","/tmp","/mount/tmp"
"/c4x","volume","/var/lib/docker/volumes/cc445a32103d6285d6f62694a74016c61255bbfbdcb4bed018ecda82f72f48fa/_data","/mount/unnamedvolume"
"/c4x","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c4","volume","/var/lib/docker/volumes/1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5/_data","/mount/unnamedvolume"
"/c4","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c4","bind","/tmp","/mount/tmp"
"/c3x","bind","/tmp","/mount/tmp"
"/c3","bind","/tmp","/mount/tmp"
"/c2x","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c2","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c1x","volume","/var/lib/docker/volumes/cc445a32103d6285d6f62694a74016c61255bbfbdcb4bed018ecda82f72f48fa/_data","/mount/unnamedvolume"
"/c1","volume","/var/lib/docker/volumes/1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5/_data","/mount/unnamedvolume"

参考、解決方法に至るまでの過程

docker volume inspect で調べてみる(期待した結果を得られず)

  • ある時、volumeの一覧を見てみました。
$ docker volume ls
DRIVER              VOLUME NAME
local               1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5
local               cc445a32103d6285d6f62694a74016c61255bbfbdcb4bed018ecda82f72f48fa
local               nemedvolume
$ 
  • 1543500c35・・・ って誰が使ってるんだろう?
  • dockerコマンドのお決まりパターンとして、各リソースは inspect で詳細が見られるので、これを使ってみます。
$ docker volume inspect 1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5
[
    {
        "CreatedAt": "2019-04-01T00:28:19+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5/_data",
        "Name": "1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5",
        "Options": null,
        "Scope": "local"
    }
]
  • 残念ながらこの方法(volume inspect)では、どの container が使っているかという情報は、表示されませんでした。

各 container が使用している volume をリストアップするワンライナー

  • アプローチを変えて、conteiner inspect から、volume を抽出してみます。
    • jq を使ってますので、事前に apt install jq などしておいてください。
$ docker ps -a --format "{{.Names}}" | xargs docker inspect | jq -r '["Name","Type","Src","Dst"], (.[] | { Name:.Name, Mounts:.Mounts[] } | [ .Name, .Mounts.Type, .Mounts.Source, .Mounts.Destination ]) | @csv' 
"Name","Type","Src","Dst"
"/c4x","bind","/tmp","/mount/tmp"
"/c4x","volume","/var/lib/docker/volumes/cc445a32103d6285d6f62694a74016c61255bbfbdcb4bed018ecda82f72f48fa/_data","/mount/unnamedvolume"
"/c4x","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
★"/c4","volume","/var/lib/docker/volumes/1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5/_data","/mount/unnamedvolume"
"/c4","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c4","bind","/tmp","/mount/tmp"
"/c3x","bind","/tmp","/mount/tmp"
"/c3","bind","/tmp","/mount/tmp"
"/c2x","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c2","volume","/var/lib/docker/volumes/nemedvolume/_data","/mount/namedvolume"
"/c1x","volume","/var/lib/docker/volumes/cc445a32103d6285d6f62694a74016c61255bbfbdcb4bed018ecda82f72f48fa/_data","/mount/unnamedvolume"
★"/c1","volume","/var/lib/docker/volumes/1543500c35fd8a7d4a63abf281733a83eac0ae4f863f36bda31f3d1aff1200d5/_data","/mount/unnamedvolume"

  • 1543500c35・・・ を使っているのは、c1 c4 コンテナでした。 (行頭★印)

参考、検証するのに使ったスクリプト

# c1: 名前無しボリューム
docker container run -d -v /mount/unnamedvolume --name c1 alpine tail -f /dev/null
docker container run -d --mount type=volume,target=/mount/unnamedvolume --name c1x alpine tail -f /dev/null

# c2: 名前有りボリューム
docker container run -d -v nemedvolume:/mount/namedvolume --name c2 alpine tail -f /dev/null
docker container run -d --mount type=volume,source=nemedvolume,target=/mount/namedvolume --name c2x alpine tail -f /dev/null

# c3: ローカルフォルダをマウント
docker container run -d -v /tmp:/mount/tmp --name c3 alpine tail -f /dev/null
docker container run -d --mount type=bind,source=/tmp,target=/mount/tmp --name c3x alpine tail -f /dev/null

# c4: c1,c2,c3 と同じものを自分にマウント
docker container run -d --volumes-from c1 --volumes-from c2 --volumes-from c3 --name c4 alpine tail -f /dev/null
docker container run -d --volumes-from c1x --volumes-from c2x --volumes-from c3x --name c4x alpine tail -f /dev/null

# 全コンテナのボリューム、マウント状況
docker ps -a --format "{{.Names}}" | xargs docker inspect | jq -r ".[] | { Name:.Name, Status:.State.Status, Mounts:.Mounts, Binds:.HostConfig.Binds }" 

#
docker container ps --all
docker volume ls

# 全コンテナ停止
docker stop $(docker ps -aq)

# 停止コンテナ削除、未使用ボリューム削除など
docker system prune --volumes
  • 実行結果
$ # c1: 名前無しボリューム
$ docker container run -d -v /mount/unnamedvolume --name c1 alpine tail -f /dev/null
39476806bd6de03df0959bb3a3090e0578b7195041d59b8d9dfd496f53ab8788
$ docker container run -d --mount type=volume,target=/mount/unnamedvolume --name c1x alpine tail -f /dev/null
f9ff47a6e53e5f13503c4fefe4d25cee38b6aff40fdb4d1a8be00b4bdad2b792
$ 
$ # c2: 名前有りボリューム
$ docker container run -d -v nemedvolume:/mount/namedvolume --name c2 alpine tail -f /dev/null
c5d02e034ba4131017a306023ed709ec4eb58716d2096419cb5f42457f074f47
$ docker container run -d --mount type=volume,source=nemedvolume,target=/mount/namedvolume --name c2x alpine tail -f /dev/null
83aaa13c98846accef04c4866ce421896d6483d3d6ad279a68a4bd3f46b34e79
$ 
$ # c3: ローカルフォルダをマウント
$ docker container run -d -v /tmp:/mount/tmp --name c3 alpine tail -f /dev/null
fc5499024b21e6eb2198668b3fbfe17d36f1d8bc8979ae366c5e7c9a8ba6b178
$ docker container run -d --mount type=bind,source=/tmp,target=/mount/tmp --name c3x alpine tail -f /dev/null
14e026db8f80ae011ea95c9b6a7ea07d8ebddf0f1f2b6d0a83b3cb9cbd90159c
$ 
$ # c4: c1,c2,c3 と同じものを自分にマウント
$ docker container run -d --volumes-from c1 --volumes-from c2 --volumes-from c3 --name c4 alpine tail -f /dev/null
c5d7f45ec7e42099692a446f65e64a40389342ac0e225811bed4c798817309bd
$ docker container run -d --volumes-from c1x --volumes-from c2x --volumes-from c3x --name c4x alpine tail -f /dev/null
7a3823a7c0421d3c56d101301caa79c2542eadbd1177f9bab93caeed5184629f
$ 
$ # 全コンテナのボリューム、マウント状況
$ docker ps -a --format "{{.Names}}" | xargs docker inspect | jq -r ".[] | { Name:.Name, Status:.State.Status, Mounts:.Mounts, Binds:.HostConfig.Binds }" 
{
  "Name": "/c4x",
  "Status": "running",
  "Mounts": [
    {
      "Type": "volume",
      "Name": "31712e5037e79400b29fa2d58369845bdb1c56a8ca34e7b34da1842e5a65c6ee",
      "Source": "/var/lib/docker/volumes/31712e5037e79400b29fa2d58369845bdb1c56a8ca34e7b34da1842e5a65c6ee/_data",
      "Destination": "/mount/unnamedvolume",
      "Driver": "local",
      "Mode": "",
      "RW": true,
      "Propagation": ""
    },
    {
      "Type": "volume",
      "Name": "nemedvolume",
      "Source": "/var/lib/docker/volumes/nemedvolume/_data",
      "Destination": "/mount/namedvolume",
      "Driver": "local",
      "Mode": "",
      "RW": true,
      "Propagation": ""
    },
    {
      "Type": "bind",
      "Source": "/tmp",
      "Destination": "/mount/tmp",
      "Mode": "",
      "RW": true,
      "Propagation": "rprivate"
    }
  ],
  "Binds": null
}
{
  "Name": "/c4",
  "Status": "running",
  "Mounts": [
    {
      "Type": "volume",
      "Name": "cc056258411e7f796fbdc682a34079a241cd3bb9f52e8d9e697b1d3e7c5eaf7c",
      "Source": "/var/lib/docker/volumes/cc056258411e7f796fbdc682a34079a241cd3bb9f52e8d9e697b1d3e7c5eaf7c/_data",
      "Destination": "/mount/unnamedvolume",
      "Driver": "local",
      "Mode": "",
      "RW": true,
      "Propagation": ""
    },
    {
      "Type": "volume",
      "Name": "nemedvolume",
      "Source": "/var/lib/docker/volumes/nemedvolume/_data",
      "Destination": "/mount/namedvolume",
      "Driver": "local",
      "Mode": "",
      "RW": true,
      "Propagation": ""
    },
    {
      "Type": "bind",
      "Source": "/tmp",
      "Destination": "/mount/tmp",
      "Mode": "",
      "RW": true,
      "Propagation": "rprivate"
    }
  ],
  "Binds": null
}
{
  "Name": "/c3x",
  "Status": "running",
  "Mounts": [
    {
      "Type": "bind",
      "Source": "/tmp",
      "Destination": "/mount/tmp",
      "Mode": "",
      "RW": true,
      "Propagation": "rprivate"
    }
  ],
  "Binds": null
}
{
  "Name": "/c3",
  "Status": "running",
  "Mounts": [
    {
      "Type": "bind",
      "Source": "/tmp",
      "Destination": "/mount/tmp",
      "Mode": "",
      "RW": true,
      "Propagation": "rprivate"
    }
  ],
  "Binds": [
    "/tmp:/mount/tmp"
  ]
}
{
  "Name": "/c2x",
  "Status": "running",
  "Mounts": [
    {
      "Type": "volume",
      "Name": "nemedvolume",
      "Source": "/var/lib/docker/volumes/nemedvolume/_data",
      "Destination": "/mount/namedvolume",
      "Driver": "local",
      "Mode": "z",
      "RW": true,
      "Propagation": ""
    }
  ],
  "Binds": null
}
{
  "Name": "/c2",
  "Status": "running",
  "Mounts": [
    {
      "Type": "volume",
      "Name": "nemedvolume",
      "Source": "/var/lib/docker/volumes/nemedvolume/_data",
      "Destination": "/mount/namedvolume",
      "Driver": "local",
      "Mode": "z",
      "RW": true,
      "Propagation": ""
    }
  ],
  "Binds": [
    "nemedvolume:/mount/namedvolume"
  ]
}
{
  "Name": "/c1x",
  "Status": "running",
  "Mounts": [
    {
      "Type": "volume",
      "Name": "31712e5037e79400b29fa2d58369845bdb1c56a8ca34e7b34da1842e5a65c6ee",
      "Source": "/var/lib/docker/volumes/31712e5037e79400b29fa2d58369845bdb1c56a8ca34e7b34da1842e5a65c6ee/_data",
      "Destination": "/mount/unnamedvolume",
      "Driver": "local",
      "Mode": "z",
      "RW": true,
      "Propagation": ""
    }
  ],
  "Binds": null
}
{
  "Name": "/c1",
  "Status": "running",
  "Mounts": [
    {
      "Type": "volume",
      "Name": "cc056258411e7f796fbdc682a34079a241cd3bb9f52e8d9e697b1d3e7c5eaf7c",
      "Source": "/var/lib/docker/volumes/cc056258411e7f796fbdc682a34079a241cd3bb9f52e8d9e697b1d3e7c5eaf7c/_data",
      "Destination": "/mount/unnamedvolume",
      "Driver": "local",
      "Mode": "",
      "RW": true,
      "Propagation": ""
    }
  ],
  "Binds": null
}
$ 
$ #
$ docker container ps --all
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                  PORTS               NAMES
7a3823a7c042        alpine              "tail -f /dev/null"   1 second ago        Up Less than a second                       c4x
c5d7f45ec7e4        alpine              "tail -f /dev/null"   2 seconds ago       Up 1 second                                 c4
14e026db8f80        alpine              "tail -f /dev/null"   3 seconds ago       Up 2 seconds                                c3x
fc5499024b21        alpine              "tail -f /dev/null"   4 seconds ago       Up 3 seconds                                c3
83aaa13c9884        alpine              "tail -f /dev/null"   5 seconds ago       Up 4 seconds                                c2x
c5d02e034ba4        alpine              "tail -f /dev/null"   6 seconds ago       Up 5 seconds                                c2
f9ff47a6e53e        alpine              "tail -f /dev/null"   7 seconds ago       Up 6 seconds                                c1x
39476806bd6d        alpine              "tail -f /dev/null"   8 seconds ago       Up 7 seconds                                c1
$ docker volume ls
DRIVER              VOLUME NAME
local               31712e5037e79400b29fa2d58369845bdb1c56a8ca34e7b34da1842e5a65c6ee
local               cc056258411e7f796fbdc682a34079a241cd3bb9f52e8d9e697b1d3e7c5eaf7c
local               nemedvolume
$ 
$ # 全コンテナ停止
$ docker stop $(docker ps -aq)
7a3823a7c042
c5d7f45ec7e4
14e026db8f80
fc5499024b21
83aaa13c9884
c5d02e034ba4
f9ff47a6e53e
39476806bd6d
$ 
$ # 停止コンテナ削除、未使用ボリューム削除など
$ docker system prune --volumes
WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all volumes not used by at least one container
        - all dangling images
        - all build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
7a3823a7c0421d3c56d101301caa79c2542eadbd1177f9bab93caeed5184629f
c5d7f45ec7e42099692a446f65e64a40389342ac0e225811bed4c798817309bd
14e026db8f80ae011ea95c9b6a7ea07d8ebddf0f1f2b6d0a83b3cb9cbd90159c
fc5499024b21e6eb2198668b3fbfe17d36f1d8bc8979ae366c5e7c9a8ba6b178
83aaa13c98846accef04c4866ce421896d6483d3d6ad279a68a4bd3f46b34e79
c5d02e034ba4131017a306023ed709ec4eb58716d2096419cb5f42457f074f47
f9ff47a6e53e5f13503c4fefe4d25cee38b6aff40fdb4d1a8be00b4bdad2b792
39476806bd6de03df0959bb3a3090e0578b7195041d59b8d9dfd496f53ab8788

Deleted Volumes:
nemedvolume
cc056258411e7f796fbdc682a34079a241cd3bb9f52e8d9e697b1d3e7c5eaf7c
31712e5037e79400b29fa2d58369845bdb1c56a8ca34e7b34da1842e5a65c6ee

Total reclaimed space: 0B
$ 
42
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
38