如何列出docker容器中的卷?

使用registry中的docker映像时,我经常需要查看映像容器创build的卷。

注意:我在Red Hat 7上使用Docker版本1.3.2。

Docker Registry的postgres官方镜像在/var/lib/postgresql/data为容器configuration了一个卷。

postgres容器中显示/var/lib/postgresql/data的卷时,最简洁的命令是什么?

使用docker ps来获取容器ID。

然后docker inspect -f '{{ .Mounts }}' containerid

例:

terminal1

 $ docker run -it -v /tmp:/tmp ubuntu:14.04 /bin/bash 

terminal2

 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ddb7b55902cc ubuntu:14.04 "/bin/bash" About a minute ago Up About a minute distracted_banach $ docker inspect -f "{{ .Mounts }}" ddb7 map[/tmp:/tmp] 

输出

 map[/tmp:/tmp] 

显然是由于使用Go语言来实现docker命令工具。

没有-f formatdocker inspect命令是非常冗长的。 既然是JSON,你可以将它pipe道到python或nodejs,并提取你需要的东西。

 paul@home:~$ docker inspect ddb7 [{ "AppArmorProfile": "", "Args": [], "Config": { "AttachStderr": true, "AttachStdin": true, "AttachStdout": true, "Cmd": [ "/bin/bash" ], "CpuShares": 0, "Cpuset": "", "Domainname": "", "Entrypoint": null, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "ExposedPorts": null, "Hostname": "ddb7b55902cc", "Image": "ubuntu:14.04", "MacAddress": "", "Memory": 0, "MemorySwap": 0, "NetworkDisabled": false, "OnBuild": null, "OpenStdin": true, "PortSpecs": null, "StdinOnce": true, "Tty": true, "User": "", "Volumes": null, "WorkingDir": "" }, "Created": "2015-05-08T22:41:44.74862921Z", "Driver": "devicemapper", "ExecDriver": "native-0.2", "ExecIDs": null, "HostConfig": { "Binds": [ "/tmp:/tmp" ], "CapAdd": null, "CapDrop": null, "ContainerIDFile": "", "Devices": [], "Dns": null, "DnsSearch": null, "ExtraHosts": null, "IpcMode": "", "Links": null, "LxcConf": [], "NetworkMode": "bridge", "PidMode": "", "PortBindings": {}, "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "RestartPolicy": { "MaximumRetryCount": 0, "Name": "" }, "SecurityOpt": null, "VolumesFrom": null }, "HostnamePath": "/var/lib/docker/containers/ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a/hostname", "HostsPath": "/var/lib/docker/containers/ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a/hosts", "Id": "ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a", "Image": "ed5a78b7b42bde1e3e4c2996e02da778882dca78f8919cbd0deb6694803edec3", "MountLabel": "", "Name": "/distracted_banach", "NetworkSettings": { "Bridge": "docker0", "Gateway": "172.17.42.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.4", "IPPrefixLen": 16, "IPv6Gateway": "", "LinkLocalIPv6Address": "fe80::42:acff:fe11:4", "LinkLocalIPv6PrefixLen": 64, "MacAddress": "02:42:ac:11:00:04", "PortMapping": null, "Ports": {} }, "Path": "/bin/bash", "ProcessLabel": "", "ResolvConfPath": "/var/lib/docker/containers/ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a/resolv.conf", "RestartCount": 0, "State": { "Error": "", "ExitCode": 0, "FinishedAt": "0001-01-01T00:00:00Z", "OOMKilled": false, "Paused": false, "Pid": 6115, "Restarting": false, "Running": true, "StartedAt": "2015-05-08T22:41:45.367432585Z" }, "Volumes": { "/tmp": "/tmp" }, "VolumesRW": { "/tmp": true } } ] 

docker history <image name>将显示烘焙到图像中的图层。 不幸的是, docker history似乎因为格式化和缺乏选项来select显示内容而受到阻碍。

您可以通过–no-trunc标志select简洁和详细的格式。

 $ docker history drpaulbrewer/spark-worker IMAGE CREATED CREATED BY SIZE 438ff4e1753a 2 weeks ago /bin/sh -c #(nop) CMD [/bin/sh -c /spark/my-s 0 B 6b664e299724 2 weeks ago /bin/sh -c #(nop) ADD file:09da603c5f0dca7cc6 296 B f6ae126ae124 2 weeks ago /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaf 0 B 70bcb3ffaec9 2 weeks ago /bin/sh -c #(nop) EXPOSE 2222/tcp 4040/tcp 60 0 B 1332ac203849 2 weeks ago /bin/sh -c apt-get update && apt-get --yes up 1.481 GB 8e6f1e0bb1b0 2 weeks ago /bin/sh -c sed -e 's/archive.ubuntu.com/www.g 1.975 kB b3d242776b1f 2 weeks ago /bin/sh -c #(nop) WORKDIR /spark/spark-1.3.1 0 B ac0d6cc5aa3f 2 weeks ago /bin/sh -c #(nop) ADD file:b6549e3d28e2d149c0 25.89 MB 6ee404a44b3f 5 weeks ago /bin/sh -c #(nop) WORKDIR /spark 0 B c167faff18cf 5 weeks ago /bin/sh -c adduser --disabled-password --home 335.1 kB f55d468318a4 5 weeks ago /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaf 0 B 19c8c047d0fe 8 weeks ago /bin/sh -c #(nop) CMD [/bin/bash] 0 B c44d976a473f 8 weeks ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/ 1.879 kB 14dbf1d35e28 8 weeks ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic 701 B afa7a164a0d2 8 weeks ago /bin/sh -c #(nop) ADD file:57f97478006b988c0c 131.5 MB 511136ea3c5a 23 months ago 0 B 

这是一个详细的例子。

 docker history --no-trunc=true drpaulbrewer/spark-worker IMAGE CREATED CREATED BY SIZE 438ff4e1753a60779f389a3de593d41f7d24a61da6e1df76dded74a688febd64 2 weeks ago /bin/sh -c #(nop) CMD [/bin/sh -c /spark/my-spark-worker.sh] 0 B 6b664e29972481b8d6d47f98167f110609d9599f48001c3ca11c22364196c98a 2 weeks ago /bin/sh -c #(nop) ADD file:09da603c5f0dca7cc60f1911caf30c3c70df5e4783f7eb10468e70df66e2109f in /spark/ 296 B f6ae126ae124ca211c04a1257510930b37ea78425e31a273ea0b1495fa176c57 2 weeks ago /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaftc.com 0 B 70bcb3ffaec97a0d14e93b170ed70cc7d68c3c9dfb0222c1d360a300d6e05255 2 weeks ago /bin/sh -c #(nop) EXPOSE 2222/tcp 4040/tcp 6066/tcp 7077/tcp 7777/tcp 8080/tcp 8081/tcp 0 B 1332ac20384947fe1f15107213b675e5be36a68d72f0e81153d6d5a21acf35af 2 weeks ago /bin/sh -c apt-get update && apt-get --yes upgrade && apt-get --yes install sed nano curl wget openjdk-8-jdk scala && echo "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64" >>/etc/environment && export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m" && ./build/mvn -Phive -Phive-thriftserver -DskipTests clean package && chown -R spark:spark /spark && mkdir /var/run/sshd 1.481 GB 8e6f1e0bb1b0b9286947d3a4b443cc8099b00f9670aab1d58654051e06f62e51 2 weeks ago /bin/sh -c sed -e 's/archive.ubuntu.com/www.gtlib.gatech.edu\/pub/' /etc/apt/sources.list > /tmp/sources.list && mv /tmp/sources.list /etc/apt/sources.list 1.975 kB b3d242776b1f1f1ae5685471d06a91a68f92845ef6fc6445d831835cd55e5d0b 2 weeks ago /bin/sh -c #(nop) WORKDIR /spark/spark-1.3.1 0 B ac0d6cc5aa3fdc3b65fc0173f6775af283c3c395c8dae945cf23940435f2785d 2 weeks ago /bin/sh -c #(nop) ADD file:b6549e3d28e2d149c0bc84f69eb0beab16f62780fc4889bcc64cfc9ce9f762d6 in /spark/ 25.89 MB 6ee404a44b3fdd3ef3318dc10f3d002f1995eea238c78f4eeb9733d00bb29404 5 weeks ago /bin/sh -c #(nop) WORKDIR /spark 0 B c167faff18cfecedef30343ef1cb54aca45f4ef0478a3f6296746683f69d601b 5 weeks ago /bin/sh -c adduser --disabled-password --home /spark spark 335.1 kB f55d468318a4778733160d377c5d350dc8f593683009699c2af85244471b15a3 5 weeks ago /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaftc.com 0 B 19c8c047d0fe2de7239120f2b5c1a20bbbcb4d3eb9cbf0efa59ab27ab047377a 8 weeks ago /bin/sh -c #(nop) CMD [/bin/bash] 0 B c44d976a473f143937ef91449c73f2cabd109b540f6edf54facb9bc2b4fff136 8 weeks ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list 1.879 kB 14dbf1d35e2849a00c6c2628055030fa84b4fb55eaadbe0ecad8b82df65cc0db 8 weeks ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/policy-rc.d && echo 'exit 101' >> /usr/sbin/policy-rc.d && chmod +x /usr/sbin/policy-rc.d && dpkg-divert --local --rename --add /sbin/initctl && cp -a /usr/sbin/policy-rc.d /sbin/initctl && sed -i 's/^exit.*/exit 0/' /sbin/initctl && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes 701 B afa7a164a0d215dbf45cd1aadad2a4d12b8e33fc890064568cc2ea6d42ef9b3c 8 weeks ago /bin/sh -c #(nop) ADD file:57f97478006b988c0c68e5bf82684372e427fd45f21cd7baf5d974d2cfb29e65 in / 131.5 MB 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158 23 months ago 0 B 

使用docker 1.10,您现在有了用于数据容器的新命令。
(对于普通的容器,请参阅docker 1.8+的下一节):

  • docker volume ls
  • docker volume inspect

通过docker 1.8.1(2015年8月), docker inspect -f '{{ .Volumes }}' containerid将会是空的!

您现在需要检查Mounts ,挂载的path列表如下:

  "Mounts": [ { "Name": "7ced22ebb63b78823f71cf33f9a7e1915abe4595fcd4f067084f7c4e8cc1afa2", "Source": "/mnt/sda1/var/lib/docker/volumes/7ced22ebb63b78823f71cf33f9a7e1915abe4595fcd4f067084f7c4e8cc1afa2/_data", "Destination": "/home/git/repositories", "Driver": "local", "Mode": "", "RW": true } ], 

如果你想要第一个挂载的path(例如),那将是(使用索引0):

 docker inspect -f '{{ (index .Mounts 0).Source }}' containerid 

正如Mike Mitterer所说:

漂亮打印整个事情:

  docker inspect -f '{{ json .Mounts }}' containerid | python -m json.tool 

或者,如Mitja所述 ,使用jq命令 。

 docker inspect -f '{{ json .Mounts }}' containerid | jq 

显示容器使用的卷的名称和装入点目标:

 docker container inspect \ -f '{{ range .Mounts }}{{ .Name }}:{{ .Destination }} {{ end }}' \ CONTAINER_ID_OR_NAME 

这与Docker 1.13兼容。

您可以通过检查容器并查看JSON输出并比较几个字段来获取有关哪些卷专门烘焙到容器中的信息。 当您运行VolumesRW docker inspect myContainerVolumesVolumesRW字段将为您提供有关容器内所有卷的信息,包括使用VOLUME指令在Dockerfile中挂载的卷以及使用docker docker run -v命令在命令行上挂载的VOLUME 。 但是,可以使用HostConfig.Binds docker run -v命令通过检查HostConfig.Binds docker inspect JSON输出中的HostConfig.Binds字段来隔离哪些卷已装载到容器中。 为了说明,这个HostConfig.Binds字段告诉你哪些卷是专门在HostConfig.Binds docker run命令中用-v选项安装的。 因此,如果您与Volumes字段交叉引用此字段,则可以使用Dockerfile中的VOLUME指令来确定哪些卷已被烘焙到容器中。

grep可以做到这一点:

 $ docker inspect myContainer | grep -C2 Binds ... "HostConfig": { "Binds": [ "/var/docker/docker-registry/config:/registry" ], 

和…

 $ docker inspect myContainer | grep -C3 -e "Volumes\":" ... "Volumes": { "/data": "/var/lib/docker...", "/config": "/var/lib/docker...", "/registry": "/var/docker/docker-registry/config" 

在我的例子中,你可以看到我已经使用docker run命令中的-v选项将/var/docker/docker-registry/config挂载到容器中,并且挂载了/data/config使用我的Dockerfile中的VOLUME指令。 容器不需要运行来获取这个信息,但是它至less需要运行一次才能填充HostConfig docker inspect命令的HostConfig JSON输出。

对于Docker 1.8,我使用:

 $ docker inspect -f "{{ .Config.Volumes }}" 957d2dd1d4e8 map[/xmount/dvol.01:{}] $ 

下面是一行命令来获取运行容器的卷信息:

 for contId in `docker ps -q`; do echo "Container Name: " `docker ps -f "id=$contId" | awk '{print $NF}' | grep -v NAMES`; echo "Container Volume: " `docker inspect -f '{{.Config.Volumes}}' $contId`; docker inspect -f '{{ json .Mounts }}' $contId | jq '.[]'; printf "\n"; done 

输出是:

 root@ubuntu:/var/lib# for contId in `docker ps -q`; do echo "Container Name: " `docker ps -f "id=$contId" | awk '{print $NF}' | grep -v NAMES`; echo "Container Volume: " `docker inspect -f '{{.Config.Volumes}}' $contId`; docker inspect -f '{{ json .Mounts }}' $contId | jq '.[]'; printf "\n"; done Container Name: freeradius Container Volume: map[] Container Name: postgresql Container Volume: map[/run/postgresql:{} /var/lib/postgresql:{}] { "Propagation": "", "RW": true, "Mode": "", "Driver": "local", "Destination": "/run/postgresql", "Source": "/var/lib/docker/volumes/83653a53315c693f0f31629f4680c56dfbf861c7ca7c5119e695f6f80ec29567/_data", "Name": "83653a53315c693f0f31629f4680c56dfbf861c7ca7c5119e695f6f80ec29567" } { "Propagation": "rprivate", "RW": true, "Mode": "", "Destination": "/var/lib/postgresql", "Source": "/srv/docker/postgresql" } Container Name: rabbitmq Container Volume: map[] 

Docker版本:

 root@ubuntu:~# docker version Client: Version: 1.12.3 API version: 1.24 Go version: go1.6.3 Git commit: 6b644ec Built: Wed Oct 26 21:44:32 2016 OS/Arch: linux/amd64 Server: Version: 1.12.3 API version: 1.24 Go version: go1.6.3 Git commit: 6b644ec Built: Wed Oct 26 21:44:32 2016 OS/Arch: linux/amd64 

docker组成用户的有用变化:

 docker-compose ps -q | xargs docker container inspect \ -f '{{ range .Mounts }}{{ .Name }}:{{ .Destination }} {{ end }}' 

这将非常整齐地输出可parsing的音量信息。 来自我的wordpress docker-compose的例子:

 ubuntu@core $ docker-compose ps -q | xargs docker container inspect -f '{{ range .Mounts }}{{ .Name }}:{{ .Destination }} {{ end }}' core_wpdb:/var/lib/mysql core_wpcode:/code core_wphtml:/var/www/html 

输出包含每个容器的一行,列出使用的卷(和安装点)。 改变{{.Name}}:{{.Destination}}部分以输出您想要的信息。

如果你只想要一个简单的卷列表,每行一个

 $ docker-compose ps -q | xargs docker container inspect \ -f '{{ range .Mounts }}{{ .Name }} {{ end }}' \ | xargs -n 1 echo core_wpdb core_wpcode core_wphtml 

很好,生成一个卷列表备份。 我使用这种技术与Blacklabelops Volumerize一起备份docker构件中所有容器使用的所有卷。 Volumerize的文档不会调用它,但是您不需要在持久容器中使用它,或者使用内置设施来启动和停止服务。 我更喜欢将关键操作(如备份和服务控制)留给实际用户(在docker外部)。 我的备份由实际(非泊坞窗)用户帐户触发,并使用docker-compose stop停止服务,备份所有正在使用的卷,最后docker-compose开始重新启动。

 docker inspect -f '{{ json .Mounts }}' containerid | jq '.[]' 

这里是我的版本来find一个泊坞窗的挂载点组成。 在使用这个来备份卷。

  # for Id in $(docker-compose -f ~/ida/ida.yml ps -q); do docker inspect -f '{{ (index .Mounts 0).Source }}' $Id; done /data/volumes/ida_odoo-db-data/_data /data/volumes/ida_odoo-web-data/_data 

这是以前解决scheme的组合。

如果要列出所有容器名称以及附加到每个容器的相关卷,请尝试以下操作:

 docker ps -q | xargs docker container inspect -f '{{ .Name }} {{ .HostConfig.Binds }}' 

示例输出:

/ opt_rundeck_1 [/ opt / var / lib / mysql:/ var / lib / mysql:rw / var / lib / rundeck / var / storage:/ var / lib / rundeck / var / storage:rw / opt / var / rundeck / .ssh:/var/lib/rundeck/.ssh:rw / opt / etc / rundeck:/ etc / rundeck:rw / var / log / rundeck:/ var / log / rundeck:rw / opt / rundeck-plugins:/ opt / rundeck-plugins:rw / opt / var / rundeck:/ var / rundeck:rw]

/ opt_rundeck_1 – 容器名称

[…] – 附在容纳人员身上的卷