cadvisor node-exporter引发的容器文件系统泄漏

问题

在2017年底,我们对自己的产品添加了监控功能,监控组件包括prometheus、grafana、cadvisor、node-exporter。监控功能集成进产品后,经过一段时间的使用,在卸载产品(主要是停止并删除各应用对应的docker容器)时经常会出现如下的错误信息:

Error response from daemon: Unable to remove filesystem for e1f4db20d043e73b997375c1db06c72127f22b5fa9b0163e98b311532fbbb257: remove /var/lib/docker/containers/e1f4db20d043e73b997375c1db06c72127f22b5fa9b0163e98b311532fbbb257/shm: device or resource busy
被删除失败的容器即刻变为Dead状态

上述错误信息可知,被删除的容器的shm文件系统一直被占用导致删除容器失败

cadvisor容器启动参数
docker run -itd --name cadvisor --network host --restart always -v /:/rootfs:ro -v /var/run:/var/run:rw -v /sys:/sys:ro -v /var/lib/docker:/var/lib/docker:ro -v /dev/disk:/dev/disk:ro -v /etc/localtime:/etc/localtime:ro cadvisor:v0.27.2 -port 8090


node-exporter容器启动参数
docker run -itd --name node-exporter --network host --restart always -v /proc:/host/proc -v /sys:/host/sys -v /:/rootfs -v /etc/localtime:/etc/localtime:ro node-exporter:v0.14.0 -collector.procfs /host/proc -collector.sysfs /host/sys -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"


解决问题的过程
  1. 考虑到是因为添加了监控组件才导致卸载失败的问题,因此首先把注意力放在了四个组件的停止、删除操作上。处理的方法是:先停止四个监控组件的容器服务,其次删除四个监控组件的容器服务,最后停止并删除各应用的容器服务。经过大量的测试验证得知:此问题已经得到解决(服务停止正常、容器卸载正常、存储空间释放正常)。但心里还是想彻底地弄清楚错误提示device or resource busy产生的根本原因,因此开始了进一步的研究
  2. 于是开始把注意力放在了docker的存储引擎devicemapper上面,之前在使用devicemapper的时候偶尔也会出现device or resource busy的错误,主要是因为docker的devicemapper存储引擎自身所导致。因此想到了替换docker的存储引擎devicemapper为overlay(之前的一次分享会上学习到Centos7.2系统存储引擎devicemapper的坑要比overlay多一些)。实践更改docker的存储引擎为overlay后发现device or resource busy的错误依然存在,可见此解决方案又失败了
  3. 调整注意力到docker自身上,浏览docker官网文档的Troubleshoot一栏,里面确实提到了遇到的这个问题,但按照提示的做法并没有解决问题,这一思路又行不通了
  4. 再一次调整注意力到四个监控组件的容器服务上,考虑到:产品是因为引入了四个监控组件的容器后才出现的卸载失败的错误,所以问题肯定是由引入的监控组件所导致,于是开始采用对四个组件容器进行一一排查的策略。经过实践排查发现,一旦引入cadvisor与node-exporter两个中的任一个,均会出现上述错误。于是开始对cadvisor、node-exporter两个容器进行深入研究,以cadvisor研究为例:首先确定容器的启动参数设置正确;然后开始停止并删除测试容器的操作,查找导致device or resource busy的shm文件系统,确定宿主机上没有进程占用此shm文件系统;于是开始尝试进入cadvisor容器内查看挂载信息,发现cadvisor容器内挂载了自身与其他容器的存储文件系统与shm文件系统;开始实践查找此处的shm文件系统的挂载与产生device or resource busy错误的关系,最终发现确实是由于cadvisor容器内的shm文件系统的挂载导致的上述错误。node-exporter的问题与cadvisor一样,此时终于找到了卸载失败的原因
  5. 于是开始浏览github上cadvisor、docker的相关issues,想要找到彻底的解决方案。阅读完所有的issues后得出:一、这是一个文件系统泄漏的问题(内核<=3.10);二、Centos7.3的版本提供了解决方案;三、Centos7.4新版本的内核会尝试解决这个问题。由于我们当前用的是Centos7.2,内核是3.10,因此这里无法找到彻底的解决方案
  6. 将注意力调整到cadvisor容器启动的参数上,思路:cadvisor将其他容器的文件系统一并挂载的原因是因为在创建cadvisor容器的时候,将包含docker存储的根路径(默认为/var/lib/docker)作为容器的映射卷映射到了cadvisor的容器中,因此想要深入研究一下cadvisor的实现,在确保cadvisor正常功能的基础上绕开docker存储根路径的映射,对cadvisor容器的启动采用细粒度的挂载方式。花了大把的时间研究cadvisor的源码得知cadvisor实现的监控功能必须要映射docker存储的根路径,否则关于容器的监控信息将全部丢失,因此采用细粒度映射的思路又是行不通的
  7. 对于当前Centos7.2+Docker1.12.6的环境,最终采用shell脚本的方式对创建完成的cadvisor与node-exporter两个容器将其他容器的文件系统进行卸载操作。安装脚本(install.sh)会在安装完所有容器服务后进行文件系统的卸载操作;卸载脚本(uninstall.sh)会在卸载之前进行文件系统的卸载操作。依靠这种方式解决了device or resource busy的问题

卸载cadvisor、node-exporter容器文件系统的脚本

cadvisor与node-exporter容器的操作方式一样,这里以cadvisor为例说明,因为要在容器中做umount文件系统的操作因此这里需要对cadvisor、node-exporter容器添加--privileged参数,代码段如下:

function exec_cadvisor_container
{
    cadvisor_container='cadvisor'
    docker_root_dir='/var/lib/docker'
    cadvisor_container_id=`docker ps --no-trunc -q --filter "name=${cadvisor_container}"`

    for container_id in `docker ps --no-trunc -a -q | grep -v ${cadvisor_container_id}`
    do
        container_mount_id=`cat ${docker_root_dir}/image/devicemapper/layerdb/mounts/${container_id}/mount-id`
        for container_fs in `docker exec ${cadvisor_container} cat /proc/mounts | awk '{print $2}' | grep -E "${container_id}|${container_mount_id}"`
        do
            if [ -n $container_fs ]
            then
                docker exec ${cadvisor_container} umount $container_fs
            fi
        done
    done
}


引用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容