• selinux踩坑篇-docker容器无法启动


    问题概述

    主机重启后,docker上的容器无法启动,报错如下

    # docker restart nginx-proxy
    Error response from daemon: Cannot restart container nginx-proxy: error creating overlay mount to /var/lib/docker/overlay2/7431ad53435c5cb52cc24ecc7263b580d4087e2c25e0d4c4c14c577a32ad3607/merged: invalid argument
    

    问题排查

    首先怀疑可能是镜像问题,于是尝试用同一个镜像去启动一个新的容器,可以正常启动成功,排除是镜像的问题

    # docker run -itd --name test nginx:1.14
    17a4ab4080dc347828e34b576de2d1922d16f6a0929d9eb5f513313df0a32609
    

    接着看了docker的日志,没发现有用的信息

    由于报错显示的是mount过程中出现了异常,所以接着排查了系统日志,发现如下报错

    message-log

    看到这段报错顿时有种熟悉感,system_u:object_r这种字符串很明显跟selinux有关,于是怀疑环境中肯定是开启了selinux导致容器挂载异常无法启动

    于是看了下selinux的状态,发现是disabled的状态。看到selinux是disabled的状态时,差点将selinux排除在外,还好上面的的报错我很确定是跟selinux有关

    # getenforce 
    Disabled
    

    为了验证是否跟selinux有关,我重新将selinux设置为启动状态,并重启了主机,果然容器可以启动成功

    # docker restart nginx-proxy
    nginx-proxy
    

    此时问题还未解决,因为selinux需要关闭,所以还需要进一步查看容器为什么无法启动

    接着再把selinux给关掉,再重启主机,果然容器又无法启动了

    由于新的容器可以启动成功,而旧的容器则无法启动,所以怀疑是不是容器配置有什么不一样的地方,于是查看了下容器的配置,果然在容器的配置中发现了异常

    cd /var/lib/docker/containers/<container_id>/
    cat config.v2.json
    

    docker-config

    从上图中可以发现, MountLabel和ProcessLabel中都携带了selinux的参数,于是将这两个参数的值都设置为空,然后重启docker(直接修改配置无法生效,需要重启docker才能生效),容器启动成功了!

    # vi config.v2.json
    ...
    ...
    "MountLabel":"","ProcessLabel":""
    ...
    ...
    
    # systemctl restart docker
    # docker ps |grep nginx
    037bd8327183        nginx:1.14                      "nginx -g 'daemon of…"   About 18 hour ago   Up 11 seconds                           nginx-proxy
    

    至此问题解决

    问题总结

    该问题的主要原因是操作系统之前开启过selinux,在此前提下启动docker并创建了该容器,于是docker的启动参数中会携带某些selinux配置,随后又修改了/etc/selinux/config的配置,将selinux设置为disabled的状态,但是此时selinux的disabled还未生效,而要使selinux的disabled生效,需要重启主机。所以在重启主机前,selinux的状态还是开启的,容器都是能够正常运行。

    当重启主机后,/etc/selinux/config下的配置就开始生效,selinux就会被设置为disabled的状态,此时容器的配置中还携带有selinux的配置,当启动容器时,会携带这些配置去访问selinux服务,此时selinux是不可用的状态,所以容器就会抛出异常无法启动。

    解决方法:

    1. 重新启用selinux,然后重启主机即可。selinux 主要作用就是最大限度地减小系统中服务进程可访问的资源,但是如果对selinux不是很懂的情况下,开启selinux可能还会引起其他问题,此时建议采用第二种方法
    2. 修改容器的配置,将 MountLabel 和 ProcessLabel 两个参数的值设置为空"MountLabel":"","ProcessLabel":"",然后重启docker服务,容器即可修复
  • 相关阅读:
    Java基于数据源的数据库访问
    新手接触java
    完成了第一个java
    Mysql服务器相互作用的通讯协议包括TCP/IP,Socket,共享内存,命名管道
    SQL 根据IF判断,SET字段值
    MyBatis SQL 生成方法 增删改查
    JAVA 文件转字节数组转字符串
    Word内容修改,以及转PDF
    SpringBoot编辑代码时不重启服务
    java 图片转换工具
  • 原文地址:https://www.cnblogs.com/zerchin/p/14750064.html
Copyright © 2020-2023  润新知