Docker容器DEAD状态问题处理笔记

遇到一个容器状态为Dead的情况, 记录一下处理过程

状态

容器状态异常

可以观察到状态为Dead, 并且镜像已经变成id而非名称

解决过程

尝试删除

删除容器

可以看到强制删除依旧无效

尝试重启docker服务

状态变了

重启后依旧是Dead状态, 不过等待一段时间后可以看到状态变为Removal In Progress

查询文档

「 Docker」容器Removal In Progress删除方案 - 简书

按照上面的博文, 我尝试执行了以下内容, 但验证无效

1
2
3
4
(base) [root@gitlab ~]# docker rm -f 0c
Error response from daemon: container 0c2cf2a4cd9ba7529c90888fd3fdef4dea95814ddca114895cd5c2c2178a5bef: driver "overlay2" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates/default: directory not empty

(base) [root@gitlab ~]# grep docker /proc/*/mountinfo | grep 405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168
image-20220901095753951

尝试自行解决

尝试进入目录检查情况

1
2
3
4
5
6
7
8
9
10
(base) [root@gitlab ~]# docker rm 0c
Error response from daemon: container 0c2cf2a4cd9ba7529c90888fd3fdef4dea95814ddca114895cd5c2c2178a5bef: driver "overlay2" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates/default: directory not empty
(base) [root@gitlab ~]#
(base) [root@gitlab ~]# cd /var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates/default
(base) [root@gitlab default]#
(base) [root@gitlab default]#
(base) [root@gitlab default]# ls -al
总用量 0
drwxr-xr-x 1 root root 6 8月 31 17:07 .
drwxr-xr-x 3 root root 21 8月 23 17:01 ..
其实目录是空的

观察报错directory not empty提示目录非空, 进入检查下, 发现目录确实是空的, 但是为啥删不掉呢?

尝试手工删除目录

1
2
3
4
5
6
7
8
9
10
(base) [root@gitlab default]# cd ..
(base) [root@gitlab templates]# pwd
/var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates
(base) [root@gitlab templates]# ls
default
(base) [root@gitlab templates]# rmdir default/
rmdir: 删除 "default/" 失败: 目录非空
(base) [root@gitlab templates]# rm -rf default/
rm: 无法删除"default/": 目录非空

手动仍然无法删除

尝试进入上层目录, 手动执行删除操作, 报错目录非空, 无法强制删除

检查文件占用情况

1
2
3
4
(base) [root@gitlab templates]# lsof 2>/dev/null |head  -1
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
(base) [root@gitlab templates]# lsof 2>/dev/null | grep /var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates/default/
(base) [root@gitlab templates]#
文件并未被占用

可以看到检查/var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates/default目录并未被占用, 而图片下方的到templates目录被占用是因为我在执行lsof命令导致

检查文件属性情况

1
2
3
4
5
6
7
8
(base) [root@gitlab templates]# pwd
/var/lib/docker/overlay2/405d18bdb7b2fcdb1de8a18b156a5ef34ccd5d0dabbe2dc350d72529bc471168/diff/opt/gitlab/embedded/cookbooks/cache/cookbooks/crond/templates
(base) [root@gitlab templates]# lsattr default/
(base) [root@gitlab templates]# chattr -i default/
(base) [root@gitlab templates]# rmdir default/
rmdir: 删除 "default/" 失败: 目录非空
(base) [root@gitlab templates]# rm -rf default/
rm: 无法删除"default/": 目录非空
检查文件属性

可以看到仍然无法删除文件, 不是文件属性问题导致的

关闭docker服务后尝试删除

停服后尝试删除

可以看到仍然无法删除

继续搜索文档

files - How do I delete a directory that contains only '.' and '..', but rm says is not empty? - Unix & Linux Stack Exchange

看了这个文档, 其中提到可能是由于硬盘故障导致

尝试扫描文件系统

fsck不支持xfs类型的分区格式

使用xfs_repair修复磁盘

系统磁盘由于使用了lvm并且已挂载, 无法在线修复, 只能进入救援模式尝试修复

尝试修复硬盘

How to Repair Corrupted root filesystem in RHEL 8 | 2DayGeek

按照上面的链接一步步执行即可, 主要命令如下

1
2
lvm vgchange -ay
xfs_repair /dev/mapper/centos-root
忘记截图了, 用网上的图吧~

我当时忘记截图了, 不过效果差不多的, 修正了几个inode云云, 就用网图看下, 修复完成后, 重启服务器

再次登录服务器, 尝试删除容器.

可以正常删除了

看到这儿, 问题已解决.

总结

本次处理逻辑大体上没有什么毛病, 汇总一下大概如下步骤:

  1. 优先执行强制删除容器操作, 观察是否可行

    1
    docker rm -f XXX

  2. 尝试重启Docker服务, 检查是否可以解决问题

    1
    systemctl restart docker || service docker restart

  3. 根据报错信息directory not empty进入指定目录查看情况, 定位目录已空但无法删除情况:

    1
    2
    3
    cd XXX
    ls -la XXXX/
    # > . ..

    1. 尝试手工删除

      1
      2
      3
      4
      rmdir XXXX
      # > rmdir: 删除 "XXXX" 失败: 目录非空
      rm -rf XXXX
      # > rm: 无法删除"XXXX": 目录非空

    2. 检查文件是否被占用

      1
      2
      lsof | head -1
      lsof 2 > /dev/null | grep XXXX

    3. 检查文件是否被设置额外属性

      1
      2
      lsattr XXXX
      chattr -i XXXX

  4. 检查磁盘是否出现逻辑坏道

    1. 进入救援 Rescue模式

      选择并进入Troubleshooting
      进入Rescue模式救援
    2. 不挂载系统盘的情况下, 执行磁盘检查

      不挂载磁盘进入救援Shell
    3. 激活分区

      • 软RAID

        1
        mdadm --assemble --scan

      • LVM

        1
        lvm vgchange -ay

        激活LVM磁盘
    4. 修复磁盘文件系统

      • xfs

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        # For LVM
        xfs_repair /dev/mapper/[vg]-[lv]
        xfs_repair /dev/mapper/rhel-root

        # For RAID
        xfs_repair /dev/[md device]
        xfs_repair /dev/md0

        # For Normal
        xfs_repair /dev/[sd device]
        xfs_repair /dev/sda1

      • ext4

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        # For LVM
        e2fsck -fvy /dev/mapper/[vg]-[lv]
        e2fsck -fvy /dev/mapper/rhel-root

        # For RAID
        e2fsck -fvy /dev/[md device]
        e2fsck -fvy /dev/md0

        # For Normal
        e2fsck -fvy /dev/[sd device]
        e2fsck -fvy /dev/sda1

        参数说明:

        • -f: 强制执行
        • -y: 使用非交互式模式
        • -v: 全量日志模式
  5. 疑难问题, 后续待补充, 可能磁盘真的故障, 无法修复, 考虑更换硬盘