docker深入2-容器删除操作失败

2017/9/26


1、报错
Error response from daemon: driver "overlay" failed to remove root filesystem for xxx: remove /var/lib/docker/overlay/xxx/merged: device or resource busy

原因:被其他容器占用了资源。
分析方法:查找 /proc/*/mountinfo 来确认是哪个 pid 在 mount 资源。
解决办法:重启监控类型的 service


2、版本信息
[root@test_node_02 ~]# docker info

Server Version: 17.06.0-ce
Storage Driver: overlay
 Backing Filesystem: extfs
 Supports d_type: true
Logging Driver: json-file
Cgroup Driver: cgroupfs

Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: active

Kernel Version: 3.10.0-514.21.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.797GiB

Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false



3、分析过程
1)尝试删除一个处于 dead 状态的容器:
[root@test_node_02 ~]# docker rm -f $(docker ps -a --filter status=dead -q |head -n 1)
Error response from daemon: driver "overlay" failed to remove root filesystem for 808acab2716420275cdb135ab964071cfc33406a34481354127635d3a282fa31: remove /var/lib/docker/overlay/88440438ea95b47e7459049fd765b51282afee4ad974107b0bf96d08d9c7763e/merged: device or resource busy


2)查找 /proc/*/mountinfo 来确认是哪个 pid 在 mount 资源:
[root@test_node_02 ~]# grep -l --color `docker ps -a --filter status=dead -q |head -n 1` /proc/*/mountinfo


3)查找 pid 确认进程的用途
[root@test_node_02 ~]# ps -f 7360
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
root      7360  7344  1 Aug16 ?        Ssl   73:57 /usr/bin/cadvisor -logtostderr

  
4)还可以验证,使用的不是同一个 mount namespace
[root@test_node_02 ~]# ls -l /proc/$(cat /var/run/docker.pid)/ns/mnt /proc/7360/ns/mnt
lrwxrwxrwx 1 root root 0 Aug 21 15:55 /proc/11460/ns/mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Aug 21 15:55 /proc/7360/ns/mnt -> mnt:[4026532279]
[root@test_node_02 ~]# 



5)尝试重启 cadvisor 服务:
[root@test_node_01 ~]# docker service ls |grep cadvisor
5f001c9293cf        cadvisor            global              3/3                 google/cadvisor:latest
     
[root@test_node_01 ~]# docker service update --force cadvisor
[root@test_node_01 ~]#
  
  
6)再次删除:
[root@test_node_02 ~]# docker rm -f $(docker ps -a --filter status=dead -q |head -n 1)
808acab27164
[root@test_node_02 ~]#
 
 
  
符合预期。



4、结论
有其他的容器或服务,挂载的卷包含了 '/var/lib/docker' or '/' 后,将导致资源占用,从而引发异常。
如何绕过:找到这样的容器或者服务,重启,然后再重试删除操作
如何解决:未知,待跟进。

来自:
https://github.com/moby/moby/issues/34652#issuecomment-325352551

cpuguy83 commented 7 days ago
Let's close this because this is exactly the same as #22260 which is still open.
Thanks!
In order to fix your current situation, the easiest thing is a reboot.

The issue is the mount has leaked into another mount namespace... likely another container by bind-mounting /var/lib/docker (or one of it's parents) into a container.


因此,目前的结论是:挂载点泄漏,暂无最终的解决方案。


20170926更新:
https://github.com/moby/moby/issues/22260#issuecomment-329322860

Vanuan commented 12 days ago  edited
Looks like RHEL/CentOS 7.4 has a "detached mount" option:
https://bugzilla.redhat.com/show_bug.cgi?id=1441737
It is "0" by default. Does it mean we should set it to "1"? Or does a recent docker yum package has this option included?

RHEL 7.4 kernel has introduced a new sysctl knob to control kernel behavior. This is called /proc/sys/fs/may_detach_mounts. This knob is set to value 0 by default. Container run times (docker and others) need the new behavior and
want it to be set to 1.

So modify runc package to drop a file say /usr/lib/sysctl.d/99-docker.conf. Contents of this file can be say following.

fs.may_detach_mounts=1


https://github.com/moby/moby/issues/22260#issuecomment-329716346
owhen commented 11 days ago
@antoinetran CentOS 7.4 is available. https://lists.centos.org/pipermail/centos-announce/2017-September/022532.html
Check out some mirrors: http://mirror.wiuwiu.de/centos/7.4.1708/


https://github.com/moby/moby/issues/22260#issuecomment-330214623
cpuguy83 commented 8 days ago
fs.may_detach_mounts=1 should resolve this on 7.4
 @xdexter
 
https://github.com/moby/moby/issues/22260#issuecomment-330217256
xdexter commented 8 days ago
Hello,

The option fs.may_detach_mounts=1 fixed my problem in CentOS 7.4.

Regards

https://github.com/moby/moby/issues/22260#issuecomment-330222776
cpuguy83 commented 8 days ago
Working on a patch to make Docker set this param on startup.


https://github.com/moby/moby/pull/34886

因此,目前的结论是:在 CentOS 7.4 可以解决这个问题,待自行验证。




ZYXW、参考
1、github
https://github.com/moby/moby/issues/22260
https://github.com/moby/moby/issues/22260#issuecomment-323645024

2、docker: devicemapper fix for “device or resource busy” (EBUSY)
http://blog.hashbangbash.com/2014/11/docker-devicemapper-fix-for-device-or-resource-busy-ebusy/