docker 更新后的奇怪问题

起因

我的 armbian 安装的是 docker-ce,而不是内置的 docker.io。这是 docker 官方推荐的,好处是更新快,有很多新的功能。但在某次更新后,用 docker system prune -a 不能清理无用的镜像了。

分析

通过查资料、问 AI,docker 官方从 v29 开始默认启用配置 containerd image store(容器镜像存储后端),而不再完全依赖旧的 overlay2 graph driver。即现在下载的镜像目录存储在 /var/lib/containerd/io.containerd.content.v1.content/blobs/sha256/ 目录下,而不再是 /var/lib/docker/overlay2/ 目录下。通过以下命令验证:
file

也可以用 docker info | grep -i -E "storage|snapshotter|driver|root dir" 查看。如果文件系统是 overlay2 是 docker 控制(旧模式),文件系统是 overlayfs 是 containerd 控制(新模式)。

现在,docker system prune -a 只会对不再使用镜像去掉标签,保留再系统内作为缓存,而不是直接删除。而进一步的操作交给更底层的 containerd

containerd 使用 leases (租期)来“锁定”某些资源,防止它们在垃圾回收(GC)时被删除。只要在租期内,关联的资源就被认为是“正在使用中”,即使镜像被 untagged 或看起来 unused,也不会被释放。如图,它定义了一个过期时间,到时候会自动释放。
可以用 ctr -n moby leases ls 查看,其中的 moby 是 dockers 默认的命名空间。
file

处理

有两个选择——

保持

适应新特性,什么都不用做,让它自动管理。

回退

如果想回到旧模式,编辑 /etc/docker/daemon.json

{
  "features": {
    "containerd-snapshotter": false
  }
}

然后 systemctl restart docker。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注