Проблемы с удалением docker-контейнеров: device or resource busy
Oct 30, 2017 08:37 · 489 words · 3 minute read
Столкнулся с проблемой на одном из серверов с установленной ОС Centos 7 — при обновлении docker-контейнеров запускается новый экземпляр контейнера, но старый при этом не удаляется. Давайте разберемся!
В консоли при этом можно увидеть ошибку примерно следующего содержания:
Error response from daemon: Driver overlay failed to remove root filesystem 88189a16be60761a2c04a455206650048e784d750533ce2858bcabe2f528c92e: rename /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21 /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21-removing: device or resource busy
Информация об установленном docker’е:
docker version
Client:
Version: 17.06.0-ce
API version: 1.30
Go version: go1.8.3
Git commit: 02c1d87
Built: Fri Jun 23 21:20:36 2017
OS/Arch: linux/amd64
Server:
Version: 17.06.0-ce
API version: 1.30 (minimum version 1.12)
Go version: go1.8.3
Git commit: 02c1d87
Built: Fri Jun 23 21:21:56 2017
OS/Arch: linux/amd64
Experimental: false
docker info
Containers: 9
Running: 8
Paused: 0
Stopped: 1
Images: 9
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: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: cfb82a876ecc11b5ca0977d1733adbe58599088a
runc version: 2d41c047c83e09a6d61d464906feb2a2f3c52aa4
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-514.26.2.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.13GiB
Name: example.com
ID: 7ZTI:WFHT:H5N5:PJBW:DE64:DPKN:PQFD:7HFH:2F5Q:DAUG:H5FH:EKK2
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: ealebed
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Удаление контейнера с ключом -f
также не помогает, примерно в половине случаев проблема уходит после перезапуска сервиса docker
. Выяснить, какой еще процесс использует каталог не удалось ни через mount
, ни через lsof
, ни с помощью fuser
…
Как оказалось, проблема давно известна и связана с контейнером cAdvisor, который часто используется для мониторинга запущенных контейнеров:
It seems Cadvisor, with permission to access other container’s volumes could lock them on the run
Здесь написано, что у каждого pid
есть свой mountinfo
, который находится в /proc/[pid]/mountinfo
и отличается от mountinfo
машины-хоста.
Делаем следующим образом:
grep docker /proc/*/mountinfo | grep 2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21
/proc/1495/mountinfo:634 537 0:92 / /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged rw,relatime shared:244 - overlay overlay rw,lowerdir=/var/lib/docker/overlay/5e43c3efd86aba4c2a2d13699b61ae93dcb15e4cdb425ffe5f2de290abb94b26/root,upperdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/upper,workdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/work
/proc/7080/mountinfo:632 586 0:92 / /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged rw,relatime shared:253 - overlay overlay rw,lowerdir=/var/lib/docker/overlay/5e43c3efd86aba4c2a2d13699b61ae93dcb15e4cdb425ffe5f2de290abb94b26/root,upperdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/upper,workdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/work
/proc/16445/mountinfo:632 586 0:92 / /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged rw,relatime shared:253 - overlay overlay rw,lowerdir=/var/lib/docker/overlay/5e43c3efd86aba4c2a2d13699b61ae93dcb15e4cdb425ffe5f2de290abb94b26/root,upperdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/upper,workdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/work
/proc/16446/mountinfo:632 586 0:92 / /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged rw,relatime shared:253 - overlay overlay rw,lowerdir=/var/lib/docker/overlay/5e43c3efd86aba4c2a2d13699b61ae93dcb15e4cdb425ffe5f2de290abb94b26/root,upperdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/upper,workdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/work
/proc/16447/mountinfo:632 586 0:92 / /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged rw,relatime shared:253 - overlay overlay rw,lowerdir=/var/lib/docker/overlay/5e43c3efd86aba4c2a2d13699b61ae93dcb15e4cdb425ffe5f2de290abb94b26/root,upperdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/upper,workdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/work
Видим, что процессы 16447, 16446, 16445, 7080, 1495 все еще ссылаются на данный каталог и не дают нам его удалить. Подключаемся как суперпользователь в пространство имен (namespace
) интересующего нас процесса с помощью команды:
nsenter -m -t 16447 /bin/bash
Смотрим список примонтированных каталогов (с помощью grep
выбираем только интересующие):
[root@example /]# mount | grep 2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21
overlay on /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay/5e43c3efd86aba4c2a2d13699b61ae93dcb15e4cdb425ffe5f2de290abb94b26/root,upperdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/upper,workdir=/var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/work)
Отмонтируем, проверяем результат и выходим из пространства имен процесса:
[root@example /]# umount /var/lib/docker/overlay/2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21/merged
[root@example /]# mount | grep 2b70ddff2ab1de78ca8c6f04b89c1cef6234bc1c880439b989ef4f0acb3c5b21
[root@example /]# exit
Повторяем данную процедуру для всех процессов, ссылающихся на данный каталог (16447, 16446, 16445, 7080, 1495). После проделанных действий можно удалить старый контейнер с помощью команды:
docker rm <id_контейнера>