美文网首页rua
cadvisor node-exporter引发的容器文件系统泄

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

作者: 汤尼房 | 来源:发表于2019-01-02 20:39 被阅读76次
    问题

    在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
    }
    
    引用

    相关文章

      网友评论

        本文标题:cadvisor node-exporter引发的容器文件系统泄

        本文链接:https://www.haomeiwen.com/subject/abjtrqtx.html