zoukankan      html  css  js  c++  java
  • Docker垃圾回收机制

    由Docker垃圾回收机制引发的一场血案

     
    AlstonWilliams 
    2017.04.01 19:00* 字数 1398 阅读 253评论 0

    今天早晨,在我还没睡醒的时候,我们团队中的一名成员就告诉我,我写的微服务中,上传头像的那个没法用.而我在发布之前,已经测试过可以使用了.那这到底是怎么回事呢?

    首先,我重新执行了一遍测试过程,发现生产服务器上的微服务上的这个上传头像的接口确实不可用.

    然后,我在本地启动了一下微服务,同样测试了一下微服务.发现还是不可用.同时,通过本地打印错误日志,发现错误是在执行保存图片这个写操作的时候:Error: socket hang up.

    开始以为是网络故障,但是访问网页以及通过SSH登陆到那台服务器都没有问题.

    既然不是网络故障的原因.那到底是什么导致的呢?

    通过查看Couchdb容器的日志,我发现了有如下错误日志:

    你能从中看出是什么原因吗?错误就隐藏在这中间.

    同样,我也是第一次使用CouchDB这个数据库,这个错误栈让我也很懵逼.这是啥意思?

    这个看不懂,只好根据Error: socket hang up这个错误来猜了.猜测是打开数据库的连接太多.

    顺着这个主线,通过查看CouchDB官方文档,我们发现默认的最大连接数就是1024,有图有真相:

    通过curl -X GET http://server_ip:5984/_stats | json_reformat这条命令,我发现,当前数据库的总共HTTP请求才有49个:

    也不是达到了最大连接数,导致不能创建新的连接的原因.那是因为什么呢?

    还记得上面的错误信息吗?其中有一条是enospc.那这个到底是什么意思呢?No space.没有空间.

    这就很容易解释为什么写操作会报错,而读操作却正常运行的原因了.

    那为什么会没有空间呢?有两个原因,一是磁盘没有空间了,二是没有Inode可用了.

    CouchDB本身是在一个容器中运行,它使用的是主机的资源.所以,很有可能是主机没有空间了.

    一个容器中的所有的东西,都是存放在/var/lib/docker文件夹下的相应的文件系统中的.我这里因为是ubuntu系统,所以是存放在/var/lib/docker/aufs/mnt这个目录中.

    而这个目录又是挂载到主机的/目录下.

    所以,只要/var/lib/docker/aufs/mnt这个目录中存满了东西,主机上的/也就没有空间了.你在主机上进行任何写操作都不会成功.

    运行df -h命令,发现果然是/目录中没有空间了.已用100%.

    那我们如何来清理/var/lib/docker/aufs/mnt或者/这两个目录,让它们腾出来空间呢?

    首先,我想到的是清理掉系统中的不必要的包,使用下面的命令:sudo apt-get autocleansudo apt-get autoremove

    然而,并没有什么作用.还是100%.

    然后,通过docker ps -a命令,我发现存在着几个已经退出或者被创建但是没有运行的容器.它们占用了一些宝贵的空间.

    然后,通过docker rm -f &(docker ps -qf status=exited)和docker rm -f &(docker ps -qf status=created)命令移除那些没用的容器.结果,发现还是不管用.

    其实,通过这种方式虽然移除了容器,但是和它们相关的卷并没有移除,我又通过docker volume ls -qf dangling=true | xargs -r docker volume rm命令,移除了那些没用的卷.

    上面的删除容器和其相关的卷的命令,我们可以简化为:docker rm -v -f &(docker ps -qf status=exited)

    这时候,再通过df -h命令,我们就能看到已用到了82%了:

    因为我这里没有没用的镜像,所以就没有进行移除镜像的操作.

    我们为什么命题为”由Docker垃圾回收机制引发的一场血案”呢?因为我一直都以为如果容器被移除掉,其对应的卷也会自动被回收.然而事实证明并没有.

    从上图中你也可以看到,我们的这台服务器总容量才20G.实际上,我们不应当使用硬盘容量这么小的服务器来运行Docker容器.

    清除了一定的空间,再测试上传头像接口,就可以正常使用了.

    出了这次事故,我专门去官网看了看Docker的垃圾回收机制,发现目前官网只提供了针对Docker Registry的垃圾回收机制.而且还是需要手动运行bin/registry garbage-collect [–dry-run] /path/to/config.yml这条命令.

    实际上,我们也完全可以自己写一个简单的脚本来进行垃圾回收.Github上也提供了相应的工具,有docker-cleanup-volumes以及其他的卷管理工具.这些我也没试过,请自行查看.

  • 相关阅读:
    解决winform DataGridView 绑定数字值列排序不对的问题
    C#中向数据库中添加注册新用户,并查询数据库中是否存在同名的用户。
    SQL数据库的脱机与联机操作
    odoo视频教程收集
    odoo10导入导出-转
    草稿-bom- 肥料生产
    freebsd 域名服务器
    freebsd启动报错:My unqualified host name unkown...Sleeping for retry.
    docker-freebsd-20150625
    supervisorctl error
  • 原文地址:https://www.cnblogs.com/xiaojikuaipao/p/7686707.html
Copyright © 2011-2022 走看看