Centos7/8 firewall 和 docker 冲突解决

介绍

  centos7/8 自带防火墙是firewalld。firewall的底层是使用iptables进行数据过滤,建立在iptables之上,这可能会与 Docker 产生冲突。当 firewalld 启动或者重启的时候,将会从 iptables 中移除 DOCKER 的规则,从而影响了 Docker 的正常工作。当你使用的是 Systemd 的时候, firewalld 会在 Docker 之前启动,但是如果你在 Docker 启动之后再启动 或者重启 firewalld ,你就需要重启 Docker 进程了。

docker 网络模式

docker 有4种网络模式 :

  1. bridge模式(默认):网桥模式,通过虚拟网桥使容器通信。容器有自己的独立ip和端口。
  2. host模式:主机模式,与主机共用一个网络,容器ip是主机的ip,端口占用主机的端口范围。
  3. container模式:与指定容器共享一个网络,类似host模式,但是是两个容器间共用一个ip。
  4. none模式:无网络模式,容器有自己的内部网络,但是没有分配ip,路由等信息,需要自己分配。

  默认是bridge 网桥模式,docker会在宿住机配置一个虚拟网卡,并将容器连接到该网卡,而docker网络与宿住机外部网络的通信,是借助nat来实现的。所以当Iptable出现问题时,就会导致docker容器网络异常centos7 自带防火墙是firewalld。在某下情况下可能导致docker 的某些网络问题。

查看 firewalld 日志

tail -10 /var/log/firewalld

  在日志中可以看到一些警告信息,是docker添加的nat规则,但是因为chain不存在,所以添加失败。一般情况下是没有什么问题,但是某些情况,比如容器内需要访问宿住机的服务,则可能出现问题。

2021-12-08 17:21:43 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -X DOCKER-ISOLATION' failed: iptables: No chain/target/match by that name.
 
2021-12-08 17:21:43 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -o docker0 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
 
2021-12-08 17:21:43 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-7407bd71b6f0 -o br-7407bd71b6f0 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).

解决

  1. 将firewalld换成iptables(推荐)
    #查看firewalld是否启用
    systemctl status firewalld
    #停止firewalld
    systemctl stop firewalld
    #禁用firewalld(否则重启系统后会再次启动)
    systemctl disable firewalld
    #查看是否安装iptables
    yum list installed | grep iptables-services
    #如果没安装则安装下
    yum install iptables-services -y
    #重启iptables
    systemctl restart iptables
    #设置开机自启
    systemctl enable iptables
    #重启docker
    systemctl restart docker
  2. 关闭防火墙(不推荐)
    #查看firewalld是否启用
    systemctl status firewalld
    #停止firewalld
    systemctl stop firewalld
    #禁用firewalld(否则重启系统后会再次启动)
    systemctl disable firewalld
  3. 修改daemon.json
      在 /etc/docker/daemon.json 文件中添加 "iptables": false
    {
        "registry-mirrors": ["http://hub-mirror.c.163.com"],
            "iptables": false
    }
      然后:
    systemctl daemon-reload
    systemctl restart docker
  4. 修改docker.service
    vi /usr/lib/systemd/system/docker.service
    
    # 找到 ExecStart=/usr/bin/dockerd -H tcp://127.0.0.1:2375 -H unix://var/run/docker.sock 在中间添加 --iptables=false
    
    ExecStart=/usr/bin/dockerd --iptables=false -H tcp://127.0.0.1:2375 -H unix://var/run/docker.sock
      然后:
    systemctl daemon-reload
    systemctl restart docker

PS

解 docker 容器端口绕过 firewall,centos7 的防火墙不能控制 docker 容器端口的问题
Centos7 firewall 和 docker冲突解决