【问题标题】:How to clean up Docker ZFS legacy shares如何清理 Docker ZFS 遗留共享
【发布时间】:2019-02-22 12:42:32
【问题描述】:

总结

鉴于:

  • 存储驱动dockerusers是ZFS;
  • 只有docker 创建legacy 数据集;

重击:

$ docker ps -a | wc -l
16

$ docker volume ls | wc -l
12

$ zfs list | grep legacy | wc -l
157

16 个容器(运行和停止)。 12 卷。 157 个数据集。 这似乎是一大堆遗留数据集。我想知道他们中的很多人是不是如此孤儿,以至于连docker 都不知道他们了,所以他们没有得到清理。

基本原理

我的 Debian zfs 池中有大量遗留卷。当我开始在这台机器上使用 Docker 时,它们开始出现:

$ sudo zfs list | grep legacy | wc -l
486

它们的形式都是:

pool/var/<64-char-hash>                  202K  6,18T   818M  legacy

此位置仅供 docker 使用。

$ docker info | grep -e Storage -e Dataset
Storage Driver: zfs
 Parent Dataset: pool/var

我开始清理了。

$ docker system prune -a
  (...)
$ sudo zfs list | grep legacy | wc -l
154

这样更好。但是,我只运行了大约 15 个容器,并且在运行docker system prune -a 之后,历史或每个容器都显示只有最后一个图像层仍然可用。剩下的都是&lt;missing&gt;(因为已经清理过了)。

$ docker images | wc -l
15

如果所有容器在剪除其余部分后只使用最后一个镜像层,不应该 docker 只使用 15 个镜像层和 15 个正在运行的容器,总共 30 个卷吗?

$ sudo zfs list | grep legacy | wc -l
154

我能否查明它们是否正在被容器/映像使用?是否有一个命令可以遍历 ZFS 中的所有 pool/var/&lt;hash&gt; 数据集并确定它们属于哪个 docker 容器/映像?要么可以删除很多,要么我不明白如何弄清楚(除了信任docker system prune)他们不能。

docker 过度使用 zfs 卷在视觉和性能方面都搞乱了我的 zfs list 命令。列出 zfs 卷现在需要大约 10 秒,而不是

证明 docker 不再看到悬空计数

$ docker ps -qa --no-trunc --filter "status=exited"
  (no output)
$ docker images --filter "dangling=true" -q --no-trunc
  (no output)
$ docker volume ls -qf dangling=true
  (no output)

zfs list 示例:

NAME                                                                                       USED  AVAIL  REFER  MOUNTPOINT
pool                                                                                      11,8T  5,81T   128K  /pool
pool/var                                                                                   154G  5,81T   147G  /mnt/var
pool/var/0028ab70abecb2e052d1b7ffc4fdccb74546350d33857894e22dcde2ed592c1c                 1,43M  5,81T  1,42M  legacy
pool/var/0028ab70abecb2e052d1b7ffc4fdccb74546350d33857894e22dcde2ed592c1c@211422332       10,7K      -  1,42M  -
# and 150 more of the last two with different hashes

【问题讨论】:

  • 您是否尝试过此处建议的说明? stackoverflow.com/questions/35655849/…
  • 我现在做了,谢谢你的建议。不幸的是,它不适用于查找用于图像或图层的挂载。它只查找具有特定 volumes 的容器,例如docker volume ls 中的那些 - 只有大约 15 卷(如预期的那样)
  • 我确实阅读了您的问题超过 10 次。然后我意识到也许你根本不是指 Docker 中的卷。由于 docker 中的卷不能从空中出现,我们必须通过“-v”标志指定它们。你能把'sudo zfs list'的内容放上去吗?也许我应该在那之后编辑我的答案......
  • @Light.G 由于zfs 存储驱动程序,它们很可能是也是 Docker 层。但我怀疑他们是古代版本的孤儿。请参阅问题末尾编辑的示例输出。
  • @Redsandro:可以用最新的 Docker 确认行为,做了修剪舞,看起来像 Docker 中的(又一个)错误:/ 这有效(但会杀死所有卷/图像/etc.pp ) 对于 Docker:zfs list -r rpool/docker | awk '/docker\// { print $1 }' | xargs -l zfs destroy -Rrpool/docker 替换为您的本地 Docker 数据集。

标签: docker zfs volumes


【解决方案1】:

我有同样的问题,但找不到满意的答案。添加what I eventually found,因为该问题是热门搜索结果之一。

背景

Docker 的 ZFS 存储驱动程序将每个图像的每一层存储为单独的旧数据集。

即使只有少量图像也可能产生大量层,每个层对应一个legacy ZFS 数据集。

  • 引用Docker ZFS driver docs:

    映像的基础层是 ZFS 文件系统。每个子层都是基于其下层的 ZFS 快照的 ZFS 克隆。容器是基于创建它的映像顶层的 ZFS 快照的 ZFS 克隆。

调查

您可以通过运行检查一张图像使用的数据集:

 $ docker image inspect [IMAGE_NAME]

示例输出:

...
"RootFS": {
    "Type": "layers",
    "Layers": [
        "sha256:f2cb0ecef392f2a630fa1205b874ab2e2aedf96de04d0b8838e4e728e28142da",
        ...
        ...
        ...
        "sha256:2e8cc9f5313f9555a4decca744655ed461e21fbe48a0f078ed5f7c4e5292ad2e",
    ]
},
...

这解释了为什么只运行十几个容器就可以看到 150 多个数据集。

解决方案

  1. 修剪并删除未使用的图像。

    $ docker image prune -a
    
  2. 为避免zfs list 速度变慢,请指定感兴趣的数据集。
    假设您将 docker 存储在 tank/docker 中,而将其他文件存储在 tank/data 中。通过递归选项仅列出data 数据集:

    # recursively list tank/data/*
    $ zfs list tank/data -r
    

【讨论】:

    【解决方案2】:

    Prune introductions 在 docker.com 上。

    我假设您的 docker 版本低于 V17.06。因为你已经执行了docker system prune -a,所以旧层的建筑信息和体积丢失了。而-a/--all 标志意味着所有没有至少一个容器的图像都将被删除。如果没有-a/--all 标志,只会删除悬空的图像。

    另外,我认为您对&lt;missing&gt; 标记和悬空图像有误解。 &lt;missing&gt; 并不意味着标记为缺失的图层真的缺失了。这只是意味着这些层可能建立在其他机器上。悬空图像是非参考图像。即使名称和标签标记为&lt;none&gt;,该图像仍然可以被其他图像引用,可以与docker history image_id进行检查。

    在您的情况下,这些图层被标记为缺失,因为您已删除包含建筑信息的旧版本图像。您在上面说过--只有最新版本的图像可用--因此,只有最新的图层没有标记为缺失。

    注意这一点:docker system prune 是管理 Docker 的所有对象(图像/容器/卷/网络/缓存)的一种惰性方式。

    【讨论】:

    • 感谢您与我一起思考。但是,system prune 暗示了volume prune,所以我已经这样做了。可以肯定的是,我做了一个volume prune。它返回“总回收空间:0B”。
    • @Redsandro Aha 是的,到目前为止,system prune 似乎没有撤消操作。下次试试volume prune吧。
    猜你喜欢
    • 2011-04-27
    • 1970-01-01
    • 2017-05-08
    • 2020-07-15
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多