我在AWS EC2上运行了一些docker容器,/var/lib/docker/overlay2文件夹的磁盘大小增长得非常快。

我想知道删除它的内容是否安全? 或者如果docker有某种命令来释放一些磁盘使用。


更新:

我实际上已经尝试了docker系统prune -a,它回收了0Kb。

此外,我的/docker/overlay2磁盘大小比docker系统df的输出大得多

在阅读docker文档和BMitch的回答后,我相信触摸这个文件夹是一个愚蠢的想法,我会尝试其他方法来回收我的磁盘空间。


Docker使用/var/lib/docker来存储映像、容器和本地命名卷。删除它可能导致数据丢失,并可能停止引擎运行。overlay2子目录专门包含图像和容器的各种文件系统层。

要清除未使用的容器和映像,请参阅docker系统修剪。还有一些选项可以删除卷,甚至是带标签的图像,但默认情况下由于数据丢失的可能性而不启用:

$ docker system prune --help

Usage:  docker system prune [OPTIONS]

Remove unused data

Options:
  -a, --all             Remove all unused images not just dangling ones
      --filter filter   Provide filter values (e.g. 'label=<key>=<value>')
  -f, --force           Do not prompt for confirmation
      --volumes         Prune volumes

剪枝永远不会删除的内容包括:

正在运行的容器(使用docker ps列出它们) 这些容器上的日志(有关限制日志大小的详细信息,请参阅这篇文章) 由这些容器所做的文件系统更改(通过docker diff可见)

此外,在这个垃圾收集过程中,docker可能不会看到在普通docker文件夹之外创建的任何内容。这可能是其他应用写到这个目录,或者docker引擎之前的配置(例如,从AUFS切换到overlay2,或者可能在启用用户名称空间之后)。

What would happen if this advice is ignored and you deleted a single folder like overlay2 out from this filesystem? The container filesystems are assembled from a collection of filesystem layers, and the overlay2 folder is where docker is performing some of these mounts (you'll see them in the output of mount when a container is running). Deleting some of these when they are in use would delete chunks of the filesystem out from a running container, and likely break the ability to start a new container from an impacted image. See this question for one of many possible results.


为了完全刷新docker到一个干净的状态,你可以删除整个目录,而不仅仅是像overlay2这样的子目录:

# danger, read the entire text around this code before running
# you will lose data
sudo -s
systemctl stop docker
rm -rf /var/lib/docker
systemctl start docker
exit

引擎将在完全空的状态下重新启动,这意味着你将失去所有:

图片 容器 名叫卷 用户创建的网络 群状态


我使用了“docker system prune -a”,它清洗了卷和overlay2下的所有文件

    [root@jasontest volumes]# docker system prune -a
    WARNING! This will remove:
            - all stopped containers
            - all networks not used by at least one container
            - all images without at least one container associated to them
            - all build cache
    Are you sure you want to continue? [y/N] y
    Deleted Images:
    untagged: ubuntu:12.04
    untagged: ubuntu@sha256:18305429afa14ea462f810146ba44d4363ae76e4c8dfc38288cf73aa07485005
    deleted: sha256:5b117edd0b767986092e9f721ba2364951b0a271f53f1f41aff9dd1861c2d4fe
    deleted: sha256:8c7f3d7534c80107e3a4155989c3be30b431624c61973d142822b12b0001ece8
    deleted: sha256:969d5a4e73ab4e4b89222136eeef2b09e711653b38266ef99d4e7a1f6ea984f4
    deleted: sha256:871522beabc173098da87018264cf3e63481628c5080bd728b90f268793d9840
    deleted: sha256:f13e8e542cae571644e2f4af25668fadfe094c0854176a725ebf4fdec7dae981
    deleted: sha256:58bcc73dcf4050a4955916a0dcb7e5f9c331bf547d31e22052f1b5fa16cf63f8
    untagged: osixia/openldap:1.2.1
    untagged: osixia/openldap@sha256:6ceb347feb37d421fcabd80f73e3dc6578022d59220cab717172ea69c38582ec
    deleted: sha256:a562f6fd60c7ef2adbea30d6271af8058c859804b2f36c270055344739c06d64
    deleted: sha256:90efa8a88d923fb1723bea8f1082d4741b588f7fbcf3359f38e8583efa53827d
    deleted: sha256:8d77930b93c88d2cdfdab0880f3f0b6b8be191c23b04c61fa1a6960cbeef3fe6
    deleted: sha256:dd9f76264bf3efd36f11c6231a0e1801c80d6b4ca698cd6fa2ff66dbd44c3683
    deleted: sha256:00efc4fb5e8a8e3ce0cb0047e4c697646c88b68388221a6bd7aa697529267554
    deleted: sha256:e64e6259fd63679a3b9ac25728f250c3afe49dbe457a1a80550b7f1ccf68458a
    deleted: sha256:da7d34d626d2758a01afe816a9434e85dffbafbd96eb04b62ec69029dae9665d
    deleted: sha256:b132dace06fa7e22346de5ca1ae0c2bf9acfb49fe9dbec4290a127b80380fe5a
    deleted: sha256:d626a8ad97a1f9c1f2c4db3814751ada64f60aed927764a3f994fcd88363b659
    untagged: centos:centos7
    untagged: centos@sha256:2671f7a3eea36ce43609e9fe7435ade83094291055f1c96d9d1d1d7c0b986a5d
    deleted: sha256:ff426288ea903fcf8d91aca97460c613348f7a27195606b45f19ae91776ca23d
    deleted: sha256:e15afa4858b655f8a5da4c4a41e05b908229f6fab8543434db79207478511ff7

    Total reclaimed space: 533.3MB
    [root@jasontest volumes]# ls -alth
    total 32K
    -rw-------  1 root root  32K May 23 21:14 metadata.db
    drwx------  2 root root 4.0K May 23 21:14 .
    drwx--x--x 14 root root 4.0K May 21 20:26 ..

警告:不要在生产系统中使用

/# df
...
/dev/xvda1      51467016 39384516   9886300  80% /
...

好的,让我们先尝试系统修剪

#/ docker system prune --volumes
...
/# df
...
/dev/xvda1      51467016 38613596  10657220  79% /
...

不太好,好像清理了几兆。让我们疯狂起来吧:

/# sudo su
/# service docker stop
/# cd /var/lib/docker
/var/lib/docker# rm -rf *
/# service docker start
/var/lib/docker# df
...
/dev/xvda1      51467016 8086924  41183892  17% /
...

好了! 只需要记住,除了一次性服务器,不建议使用这种方法。此时,Docker的内部数据库将无法找到任何这些覆盖,这可能会导致意想不到的后果。


我有这样的问题…那是一根巨大的木头。日志如下:

/var/lib/docker/containers/<container id>/<container id>-json.log

您可以在运行命令行或撰写文件中进行管理。参见:配置日志记录驱动程序

我个人将这3行添加到我的docker-compose中。Yml文件:

my_container:
  logging:
    options:
      max-size: 10m

也有快速增长的覆盖2的问题

/var/lib/docker/overlay2 -是docker存储容器可写层的文件夹。 只有当容器停止并删除时,Docker系统修剪-a才能工作。

在我的作品中,我能够通过研究overlay2来计算出什么占用了空间。

该文件夹包含其他命名为哈希的文件夹。每个都有几个文件夹,包括diff文件夹。

Diff文件夹——包含一个容器所写的实际差异,该容器具有与你的容器相同的文件夹结构(至少在我的情况下- ubuntu 18…)

所以我用du -hsc /var/lib/docker/overlay2/ longhashhhhhhh /diff/tmp来找出我的容器中的/tmp是被污染的文件夹。

因此,作为一个解决方案,我已经使用-v /tmp/container-data/tmp:/tmp参数为docker运行命令来映射内部/tmp文件夹到主机,并在主机上设置一个cron来清理该文件夹。

Cron任务很简单:

Sudo nano /etc/crontab */30 * * * * root rm -rf /tmp/container-data/tmp/* .使用实例 保存并退出

注意:overlay2是系统docker文件夹,他们可以随时改变它的结构。以上一切都是基于我在里面看到的。不得不进入docker文件夹结构,因为系统完全没有空间,甚至不允许我ssh进入docker容器。


我发现这个方法最适合我:

docker image prune --all

默认情况下,Docker不会删除已命名的图像,即使它们未使用。该命令将删除未使用的映像。

注意,图像中的每一层都是/usr/lib/docker/overlay2/文件夹中的一个文件夹。


背景

The blame for the issue can be split between our misconfiguration of container volumes, and a problem with docker leaking (failing to release) temporary data written to these volumes. We should be mapping (either to host folders or other persistent storage claims) all of out container's temporary / logs / scratch folders where our apps write frequently and/or heavily. Docker does not take responsibility for the cleanup of all automatically created so-called EmptyDirs located by default in /var/lib/docker/overlay2/*/diff/*. Contents of these "non-persistent" folders should be purged automatically by docker after container is stopped, but apparently are not (they may be even impossible to purge from the host side if the container is still running - and it can be running for months at a time).

解决方案

解决方案需要仔细的手动清理,虽然已经在其他地方描述过,但您仍然可以从我的案例研究中找到一些提示,我试图使其尽可能具有启发性和普遍性。

所以发生的事情是罪魁祸首应用程序(在我的案例中是claire -scanner)设法在几个月内向docker的overlay2的/diff/tmp子文件夹写入了数百gb的数据

du -sch /var/lib/docker/overlay2/<long random folder name seen as bloated in df -haT>/diff/tmp

271G total

因此,由于/diff/tmp中的所有子文件夹都是相当自解释的(都是克莱尔-scanner-*的形式,并且有过时的创建日期),我停止了相关的容器(docker stop clair),并小心地从diff/tmp中删除了这些过时的子文件夹,谨慎地从一个(最古老的)单一文件夹开始,并测试了对docker引擎的影响(这需要重新启动[systemctl restart docker]来回收磁盘空间):

rm -rf $(ls -at /var/lib/docker/overlay2/<long random folder name seen as bloated in df -haT>/diff/tmp | grep clair-scanner | tail -1)

我回收了数百gb的磁盘空间,而不需要重新安装docker或清除它的整个文件夹。所有正在运行的容器都必须在某一时刻停止,因为需要重新启动docker守护进程来回收磁盘空间,因此首先要确保您的故障转移容器在某个/其他节点上正确运行。我希望docker的prune命令也能覆盖过时的/diff/tmp(甚至/diff/*)数据(通过另一个开关)。

这是一个有3年历史的问题,你可以在Docker论坛上阅读它丰富多彩的历史,其中针对上述解决方案的应用程序日志的变体在2019年被提出,并且似乎在几个设置中起了作用:https://forums.docker.com/t/some-way-to-clean-up-identify-contents-of-var-lib-docker-overlay/30604


不要在生产环境中这样做

@ravi-luthra给出的答案在技术上是有效的,但它有一些问题!

在我的例子中,我只是试图恢复磁盘空间。lib/docker/overlay文件夹占用了30GB的空间,我只定期运行几个容器。看起来docker有一些数据泄漏的问题,一些临时数据在容器停止时没有被清除。

所以我删除了lib/docker/overlay文件夹的所有内容。在那之后,我的docker实例变得不可用。当我试图运行或构建任何容器时,它给了我这个错误:

failed to create rwlayer: symlink ../04578d9f8e428b693174c6eb9a80111c907724cc22129761ce14a4c8cb4f1d7c/diff /var/lib/docker/overlay2/l/C3F33OLORAASNIYB3ZDATH2HJ7: no such file or directory

经过反复试验,我通过跑步解决了这个问题

(警告:这将删除docker卷内的所有数据)

docker system prune --volumes -a

所以不建议做这样的脏清理,除非你完全了解系统是如何工作的。


/var/lib/docker中的所有内容都是容器的文件系统。如果你停止所有的容器并修剪它们,你应该以文件夹为空结束。你可能并不想那样做,所以不要随意删除里面的内容。不要直接删除/var/lib/docker中的内容。有时你可能会侥幸逃脱,但出于很多原因,这是不可取的。

你可以这样做:

sudo bash
cd /var/lib/docker
find . -type f | xargs du -b  | sort -n

您将看到的是底部显示的最大文件。如果你想,找出这些文件在什么容器里,用docker exec -ti containername——/bin/sh输入这些容器,然后删除一些文件。

你也可以把docker系统prune -a -f放在每日/每周的cron作业中,只要你不留下你所关心的停止的容器和卷。最好是找出它增长的原因,并在容器级别上纠正它们。


我最近遇到了一个类似的问题,overlay2变得越来越大,但我不知道是什么消耗了大量的空间。

df告诉我overlay2的大小大约是24GB。

对于du,我试图找出是什么占据了空间,但失败了。

区别来自于删除的文件(在我的情况下主要是日志文件)仍然被一个进程(Docker)使用。因此,文件不会显示du,但它占用的空间将显示df。

重新启动主机有帮助。重新启动docker容器可能已经有所帮助了…… org上的这篇文章帮助我找到了答案。


在上面的评论中,人们建议修剪系统,如清除悬空卷,图像,退出容器等,有时你的应用程序成为罪魁祸首,它在很短的时间内产生了太多的日志,如果你使用一个空的目录卷(本地卷),这会填满/var分区。在这种情况下,我发现下面的命令非常有趣,要弄清楚是什么在消耗我的/var分区磁盘上的空间。

du -ahx /var/lib | sort -rh | head -n 30

This command will list top 30, which is consuming most space on a single disk. Means if you are using external storage with your containers, it consumes a lot of time to run du command. This command will not count mount volumes. And is much faster. You will get the exact directories/files which are consuming space. Then you can go to those directories and check which files are useful or not. if these files are required then you can move them to some persistent storage by making change in app to use persistent storage for that location or change location of that files. And for rest you can clear them.


朋友们,为了保持一切清洁,你可以使用命令:

docker system prune -a && docker volume prune

Docker显然为运行的容器保留了映像的旧版本的映像层。如果你更新运行中的容器的镜像(相同的标签)而没有停止它,可能会发生这种情况,例如:

docker-compose pull
docker-compose up -d

在更新之前运行docker-compose down解决了它,停机时间在我的情况下不是一个问题。


我也有同样的问题,在我的实例中,这是因为' var/lib/docker '目录被挂载到一个运行的容器(在我的情况下谷歌/cadvisor),因此它阻止了docker修剪清理文件夹。停止容器,运行docker prune -然后重新运行容器解决了问题。


docker system prune -af && docker image prune -af

“官方”回答,用“修剪”命令清理,实际上不清理overlay2文件夹中的垃圾。

所以,要回答最初的问题,我们可以做的是:

免责声明:应用此功能时请小心。这可能会导致Docker对象中断!

List folder names (hashes) in overlay2 Inspect your Docker objects (images, containers, ...) that you need (A stopped container or an image currently not inside any container do not mean that you do not need them). When you inspect, you will see that it gives you the hashes that are related with your object, including overlay2's folders. Do grep against overlay2's folders Note all folders that are found with grep Now you can delete folders of overlay2 that are not referred by any Docker object that you need.

例子:

假设在overlay2目录中有这些文件夹,

a1b28095041cc0a5ded909a20fed6dbfbcc08e1968fa265bc6f3abcc835378b5
021500fad32558a613122070616963c6644c6a57b2e1ed61cb6c32787a86f048

您只有一个ID为c777cf06a6e3的图像。

然后,这样做:

docker inspect c777cf06a6e3 | grep a1b2809
docker inspect c777cf06a6e3 | grep 021500

想象一下,第一个命令找到了一些东西,而第二个命令什么也没有。

然后,您可以删除0215…overlay2文件夹:

rm -r 021500fad32558a613122070616963c6644c6a57b2e1ed61cb6c32787a86f048

回答问题的题目:

是的,如果你发现它没有被使用,直接删除overlay2文件夹是安全的。 不,如果你发现它正在被使用或者你不确定,直接删除它是不安全的。


如果你的系统也用于构建映像,你可以看看如何清理由构建器创建的垃圾,使用:

docker buildx prune --all

and

docker builder prune --all

也许这个文件夹不是你的问题,不要用docker的df -h的结果。 使用下面的命令查看每个文件夹的大小:

echo; pwd; echo; ls -AlhF; echo; du -h --max-depth=1; echo; du-sh

基于Mert Mertce的回答,我编写了以下脚本,包括旋转器和进度条。

然而,自从写了脚本之后,我注意到我们构建服务器上的额外目录是暂时的——也就是说,Docker似乎正在清理,尽管速度很慢。我不知道如果存在删除目录的竞争,Docker是否会感到不安。我们目前的解决方案是使用documentum,但是有很多额外的开销(150+GB)。

#!/bin/bash
[[ $(id -u) -eq 0 ]] || exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
progname=$(basename $0)
quiet=false
no_dry_run=false
while getopts ":qn" opt
do
    case "$opt" in
      q)
          quiet=true
          ;;
      n)
          no_dry_run=true
          ;;
      ?)
          echo "unexpected option ${opt}"
          echo "usage: ${progname} [-q|--quiet]"
          echo "    -q: no output"
          echo "    -n: no dry run (will remove unused directories)"
          exit 1
          ;;
    esac
done
shift "$(($OPTIND -1))"

[[ ${quiet} = false ]] || exec /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")" > /dev/null

echo "Running as: $(id -un)"

progress_bar() {
    local w=80 p=$1;  shift
    # create a string of spaces, then change them to dots
    printf -v dots "%*s" "$(( $p*$w/100 ))" ""; dots=${dots// /.};
    # print those dots on a fixed-width space plus the percentage etc.
    printf "\r\e[K|%-*s| %3d %% %s" "$w" "$dots" "$p" "$*";
}

cd /var/lib/docker/overlay2
echo cleaning in ${PWD}
i=1
spi=1
sp="/-\|"
directories=( $(find . -mindepth 1 -maxdepth 1 -type d | cut -d/ -f2) )
images=( $(docker image ls --all --format "{{.ID}}") )
total=$((${#directories[@]} * ${#images[@]}))
used=()
for d in "${directories[@]}"
do
    for id in ${images[@]}
    do
        ((++i))
        progress_bar "$(( ${i} * 100 / ${total}))" "scanning for used directories ${sp:spi++%${#sp}:1} "
        docker inspect $id | grep -q $d
        if [ $? ]
        then
            used+=("$d")
            i=$(( $i + $(( ${#images[@]} - $(( $i % ${#images[@]} )) )) ))
            break
        fi
    done
done
echo -e "\b\b " # get rid of spinner
i=1
used=($(printf '%s\n' "${used[@]}" | sort -u))
unused=( $(find . -mindepth 1 -maxdepth 1 -type d | cut -d/ -f2) )
for d in "${used[@]}"
do
    ((++i))
    progress_bar "$(( ${i} * 100 / ${#used[@]}))" "scanning for unused directories ${sp:spi++%${#sp}:1} "
    for uni in "${!unused[@]}"
    do
        if [[ ${unused[uni]} = $d ]]
        then
            unset 'unused[uni]'
            break;
        fi
    done
done
echo -e "\b\b " # get rid of spinner
if [ ${#unused[@]} -gt 0 ]
then
    [[ ${no_dry_run} = true ]] || echo "Could remove:  (to automatically remove, use the -n, "'"'"no-dry-run"'"'" flag)"
    for d in "${unused[@]}"
    do
        if [[ ${no_dry_run} = true ]]
        then
            echo "Removing $(realpath ${d})"
            rm -rf ${d}
        else
            echo " $(realpath ${d})"
        fi
    done
    echo Done
else
    echo "All directories are used, nothing to clean up."
fi

我导航到包含overlay2的文件夹。使用du -shc overlay2/*,我发现overlay2中有25G的垃圾。运行docker系统prune -af显示总回收空间:1.687MB,所以我认为它未能清理它。然而,我然后再次运行du -shc overlay2/*,只看到overlay2只有80K,所以它确实工作。

小心,docker撒谎:)。


在我的例子中,systemctl stop docker然后systemctl start docker以某种方式自动释放空间/var/lib/docker/*