创建的容器都是没有指定 volume的,为什么docker volume ls命令会看到很多volume列表?

有那么一天,停止了世界所有的容器(在你电脑上),执行以下命令

docker volume ls

docker volume ls | wc -l

哎呦,我去,怎么这么多啥玩意,再执行以下命令看占了我多少磁盘空间

# 使用 docker inspect 命令(如果 volume 驱动支持大小 Size 报告):
docker volume inspect <volume_name> --format '{{ .Size }}'

# 查看所有 volumes 的详细信息(这玩意不太准,可以当做估算大小吧)
docker system df -v

# 更精确
sudo du -sh /var/lib/docker/volumes/*

# 如果你想要更精确的结果,可以直接查看 Docker volume 的存储位置的实际磁盘占用大小
# linux通常在 /var/lib/docker/volumes/ 目录下
# 在 macOS 上,Docker Desktop 使用的是一个特殊的虚拟机来运行 Docker 引擎,因此 Docker volumes 的实际存储位置比较特殊:
# ~/Library/Containers/com.docker.docker/Data/vms/0/data/docker/volumes/
# 还有一个 macOS 下的 orbstack
# OrbStack Docker volumes 的默认存储路径(跟 docker volume inspect 命令输出的不一致)
# 通过 brew 安装的 orbstack Docker volumes 的默认存储路径(通过下面命令找到了)
find / -type d -name "volumes" 2>/dev/null | grep -i orbstack
/System/Volumes/Data/Users/<your_username>/OrbStack/docker/volumes
~/OrbStack/docker/volumes

这是因为 Docker 有一个特性叫做"匿名卷"(Anonymous Volumes)。即使你没有显式指定 volume,Docker 也会在以下情况自动创建 volume:

1.Dockerfile 中的 VOLUME 指令

# 当 Dockerfile 包含这样的指令时,会自动创建匿名卷
VOLUME /data

2.Docker Compose/Swarm/Stack 中的隐式声明

services:
  db:
    image: mysql
    # MySQL 镜像的 Dockerfile 中定义了 VOLUME,会自动创建

3.某些镜像的默认行为

比如:

  • MySQL 会为数据目录创建 volume
  • Redis 会为数据文件创建 volume
  • MongoDB 会为数据库文件创建 volume

查看这些自动创建的 volume 的来源:

# 查看 volume 详细信息
docker volume inspect volume_name

# 查看容器的 volume 挂载信息
docker inspect container_name | grep -A 10 "Mounts"

那么真正需要的问题来,不知道也就算了,现在知道了,我们不希望莫名其妙多了好多莫名的 volume,应该清理?以及如何保持纯净或最佳实践?

清理建议:

1.使用 docker volume ls -f dangling=true 查看未被使用的 volume
2.使用 docker volume prune 清理未使用的 volume
3.如果要避免创建匿名卷,可以:

  • 在 docker run 时使用 --rm 参数(容器删除时自动删除匿名卷)
  • 显式定义具名卷(named volume)
  • 使用 bind mount 替代 volume

docker volume 相关命令

docker volume 帮助命令

docker volume --help

列出所有 volumes

docker volume ls

查看指定的 volume 的详细信息

docker volume inspect <volume_name>

查看哪些容器正在使用特定的 volume

docker ps -a filter volume=<volume_name>

查看 volume 的具体内容

ls /var/lib/docker/volumes/<volume_name>/_data

查看 dangling (未被使用) 的 volumes

docker volume ls -f dangling=true

删除指定的 volume

docker volume rm <volume_name>

列出并删除指定条件的 volumes

docker volume ls -qf dangling=true | xargs -r docker volume rm

删除所有未使用的 volumes

docker volume prune

最佳实践是在生产环境中使用具名卷,这样更容易管理和维护:

# 创建具名卷
docker run -v my_volume:/data image_name

非生产环境,比如开发/测试环境,使用 tmpfs,性能更高,这样容器删除或重启会直接清空,无残留

# 创建使用 tmpfs 的容器
docker run --tmpfs /app/cache nginx

# 可以指定大小和权限
docker run --tmpfs /app/cache:rw,size=1g,noexec nginx
# or
# 限制 tmpfs 大小
docker run --tmpfs /tmp:size=100M nginx
# 设置权限
docker run --tmpfs /tmp:rw,noexec,nosuid,size=100M nginx

# 临时文件
docker run --tmpfs /tmp nginx

# 会话数据
docker run --tmpfs /app/sessions my-web-app

# 缓存数据
docker run --tmpfs /app/cache redis

tmpfs 不适用的场景

  • 数据库等需要持久化的
  • 用户上传文件等需要支持持久化的
  • 配置文件
  • 日志文件

更佳的混合使用策略

# docker-compose.yml 示例
services:
  web:
    image: nginx
    volumes:
      - ./data:/app/data        # 持久化数据使用 volume
    tmpfs:
      - /tmp                    # 临时文件使用 tmpfs
      - /app/cache             # 缓存使用 tmpfs

总结:

  • tmpfs 适合处理临时数据、缓存和敏感信息
  • 需要持久化的数据还是应该使用 volume 或 bind mount
  • 建议根据数据特性选择合适的存储方式,可以混合使用不同的存储策略
posted @ 2025-01-09 09:47  taadis  阅读(248)  评论(0)    收藏  举报
扫码关注

扫码关注我