关于Vmware虚拟机挂起后恢复主机无法访问docker的container服务

  • 问题展示
  • 问题原因
  • 知识点拓展
  • Docker 和 iptables 的关系。
  • Linux系统数据包转发
  • 解决方法
  • 治标不治本之重启Docker服务大法
  • 临时开启ipv4的转发功能
  • 永久开启ipv4的转发功能
  • 探索过程


问题展示

最近每次挂起虚拟机后恢复,主机总是无法正常访问虚拟机中docker的container。

宿主机不进入容器执行容器内脚本命令是什么_重启

问题原因

Vmware 网桥配置没有开启转发功能

知识点拓展

Docker 和 iptables 的关系。

Docker 能为我们提供很强大和灵活的网络能力,很大程度上要归功于与 iptables 的结合。Docker 在启动的时候已经帮我们自动完成了相关的配置。

[root@zbx-agent01 ~]# dockerd --help |grep iptables
      --iptables                                Enable addition of iptables rules (default true)
[root@zbx-agent01 ~]#

docker daemon 的 --iptables 就是用来控制是否要自动启用 iptables 规则的,默认已经设置成了开启(true)。
当我们运行容器时(STATUS:up),docker 会在 iptables 自定义链 DOCKER 中定义转发规则,如果此时系统的 net.ipv4.ip_forward 为0,主机将无法正常访问服务。

Linux系统数据包转发

出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功

  1. 通过访问sysctl的内核ipv4.ip_forward来判断转发是否开启。
    说明:现在有些网络已经普及ipv6的,所以下面的命令可以从ipv4改为ipv6即可
# 使用sysctl:
[root@zbx-agent01 ~]# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
# 检查/proc下的文件:
[root@zbx-agent01 ~]# cat /proc/sys/net/ipv4/ip_forward
1
[root@zbx-agent01 ~]#
# ipv4转发没有开启 (值为 0)
  1. 启动IP转发
####################    临时    ################################

# 通过sysctl可以开启ipv4的转发功能 (无需重启):
[root@zbx-agent01 ~]# sysctl -w net.ipv4.ip_forward=1
# 或者
[root@zbx-agent01 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

####################    永久    ################################
# 通过在/etc/sysctl.conf设置参数,增加一条net.ipv4.ip_forward = 1
[root@zbx-agent01 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@zbx-agent01 ~]# systemctl restart network

解决方法

治标不治本之重启Docker服务大法

Docker 在重启的时候,会进行 iptables 相关规则的清理和重建。
[root@zbx-agent01 ~]# systemctl restart docker \
> docker start $(docker ps -qa)

临时开启ipv4的转发功能

# 通过sysctl可以开启ipv4的转发功能 (无需重启):
[root@zbx-agent01 ~]# sysctl -w net.ipv4.ip_forward=1
# 或者
[root@zbx-agent01 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
上述方法对于经常挂起需求的很麻烦。

永久开启ipv4的转发功能

# 通过在/etc/sysctl.conf设置参数,增加一条net.ipv4.ip_forward = 1
[root@zbx-agent01 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@zbx-agent01 ~]# systemctl restart network

探索过程

以下为探索过程

主机ping虚拟机

宿主机不进入容器执行容器内脚本命令是什么_网络_02


重启虚拟机相关

# 重启虚拟机网络 (无效)
[root@zbx-agent01 ~]# systemctl restart network

# 重启container (无效)
[root@zbx-agent01 ~]# docker restart $(docker ps | awk '/prometheus/ {print $1}')
23c24acd8961