Docker的`docker0`设备反复死亡(`inet addr`消失)

14

我正在运行 Ubuntu 14.04 上的 Docker 版本 1.4.1,构建版本为 5bc2ff8。当我使用 docker run 运行任何容器时,经过几分钟后我的 docker0 桥 "死掉",容器无法再连接网络。在连接断开之前,运行 ifconfig 命令会报告一个类似于以下格式的 docker0 设备的 inet addr

docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: xxxx::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          [... etc.]

但是连接断开后,ifconfig 显示 ipv4 地址已经消失:

docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99 
          inet6 addr: xxxx::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8116 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15995 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2444859 (2.4 MB)  TX bytes:17440729 (17.4 MB)

重新启动 Docker(例如使用 sudo service docker restart 命令)可以使设备重新运行,但是所有容器都会停止并且问题会再次出现。我无法可靠地让任何东西运行超过几分钟。对于大多数项目来说,甚至无法完成 docker build

  1. 可能是什么原因导致这种情况?
  2. 如何进行诊断?
  3. 有哪些可能的解决方案?

谢谢!


更新:我可以通过使用命令 docker run -t -i ubuntu /bin/bash 启动一个容器,然后使用 ctrl-d 退出来可靠地触发此问题。当我这样做时,我在 /var/log/syslog 中看到以下内容:

myhost kernel:  docker0: port 1(veth80ddeaf) entered disabled state
myhost kernel:  device veth80ddeaf left promiscuous mode
myhost kernel:  docker0: port 1(veth80ddeaf) entered disabled state
'

myhost dhclient: Internet Systems Consortium DHCP Client 4.2.4
myhost dhclient: Copyright 2004-2012 Internet Systems Consortium.
myhost dhclient: All rights reserved.
myhost dhclient: For info, please visit https://www.isc.org/software/dhcp/
myhost dhclient: 
myhost dhclient: Listening on LPF/docker0/56:84:7a:fe:97:99
myhost dhclient: Sending on   LPF/docker0/56:84:7a:fe:97:99
myhost dhclient: Sending on   Socket/fallback
myhost kernel:  IPv6: ADDRCONF(NETDEV_UP): docker0: link is not ready

更新 #2:失败的频率似乎取决于容器运行的时间。例如:
docker run -i -t  ubuntu   sleep 0
--> `docker0` "survives" ~100% of the time

docker run -i -t  ubuntu   sleep 1
--> `docker0` survives ~80% of the time

docker run -i -t  ubuntu   sleep 5
--> `docker0` survives ~0% of the time

尝试使用 --net="host" 作为解决方法。这样会起作用吗? - Maxim
@maxd 指定 --net="host" 会防止我将容器的网络容器化。所以这不是我的问题的解决方案 - 虽然感谢您的建议! - Bosh
4个回答

5
我曾经遇到过类似的问题:每次重启docker,docker0网桥就会启动,但是只要我运行docker run hello-world并且程序退出后,它就会消失。因为docker0消失了,我无法再让hello-world工作。
于是我检查了系统日志(通过gnome-system-log查看syslog)来自一个docker正常工作的PC和我遇到问题的PC,hello world命令的日志顺序有些不同,但本质相同。但我注意到了一件事:在有问题的PC上,docker正在使用netscript处理网络接口,所以我通过sudo apt remove netscript-2.4将其删除,并用sudo systemctl restart docker重启docker,一切都恢复正常了。

你的回复唯一的问题是不够显眼 :D,但解决了我的问题! - Hicham
1
我刚从Ubuntu 20.04升级到22.04,我的一些docker-compose服务无法启动,这是解决方法。起初我对此不以为意,但在docker错误周围的/var/log/syslog中看到了“Usage: netscript ifup|ifdown|ifqos|ifreload”,似乎compose或docker试图不正确地使用netscript。 - Caleb Fenton

3
我该如何诊断它?
docker0有一个IP地址时,如果您不启动任何容器,它会消失吗?如果它一直持续到您启动容器,我建议您首先查看Docker日志,以及在启动容器时跟踪系统日志。
IP地址是否在固定时间间隔内消失(例如每N分钟)?如果是这样,我建议查看cron的日志,以查看是否有一些定期任务负责此问题。
您正在运行NetworkManager吗?禁用NetworkManager是否可以解决问题?我在安装了NetworkManager的系统上运行Docker没有问题,但是我的配置中设置了no-auto-default=*,这可能对此类事情产生影响。
更新
这非常可疑:
myhost dhclient: Internet Systems Consortium DHCP Client 4.2.4
myhost dhclient: Copyright 2004-2012 Internet Systems Consortium.
myhost dhclient: All rights reserved.
myhost dhclient: For info, please visit https://www.isc.org/software/dhcp/
myhost dhclient: 
myhost dhclient: Listening on LPF/docker0/56:84:7a:fe:97:99
myhost dhclient: Sending on   LPF/docker0/56:84:7a:fe:97:99
myhost dhclient: Sending on   Socket/fallback

docker0上不应该有任何正在监听的dhclient进程,这绝对是导致您的IP地址消失的原因。如果您没有明确在此接口上运行dhcp客户端,则这真的表明NetworkManager实际上正在尝试管理此接口。您说您已禁用了NetworkManager,但您确认过进程是否已停止吗?正在监听docker0dhclient的父进程是什么?如果您停止dhclient进程,它是否会重新启动?问题是否解决?


感谢@larsks的建议 - 非常好!我可以报告以下行为:1)如果我不启动任何 docker 容器,则不会发生,2)它不是基于时间的,3)当network-manager被禁用时仍然存在。我已经在我的问题更新中包含了相关的syslog转储。我将非常感激任何额外的指导。 - Bosh
请参考附加更新,建议存在竞态条件(容器生存时间似乎会影响故障概率)。您对如何调试有进一步的想法吗? - Bosh
当我在主机系统上运行 ps aux | grep -i dhclientps aux | grep -i network 时,我可以确认没有结果(dhclient 没有运行)。但是我在 syslog 中看到了这些 myhost dhclient 条目 -- 可能由于容器的停止事件而某种方式地调用了 dhclient?有没有办法我可以调查这个可能性? - Bosh
我很想听听你的看法 - 在启动新的Docker容器之前/之后,似乎我的主机系统上没有运行dhclient。是否可能仅在容器退出时触发dhclient的启动,或者某个名为dhclient以外的其他进程导致myhost dhclient日志行出现在我的系统日志中? - Bosh
1
我在这里遇到了同样的问题(dhclient在docker容器退出后立即启动)。我也认为NetworkManager是问题所在。但实际上问题与wicd(有线和无线网络管理器)有关,它是我机器上安装的另一个网络管理器。禁用wicd解决了我的问题。 - Jean-François Roche

3

看起来 wcid 服务是问题的根源。我在配置文件中发现:

(/etc/wicd/manager-settings.conf): wired_interface = docker0

我将它改为了 eth0

尽管我忘了重启服务,但当停止 wicd 服务时问题消失了。 在上述更改之后,我再次启动了它,没有遇到任何问题。

显然有一些关于 wicd 的自动配置问题?

要再次使桥接工作,您可以使用:

sudo ip addr add 172.17.0.1/24 dev docker0

桥接器将重新获得IP地址。


我怀疑是wicd引起的问题,然后我卸载了它,但问题仍然存在。也许是因为服务仍然存在,所以我编辑了这个文件并重新启动了系统,现在网络正常了。 - Eduardo

1

我曾经遇到过完全相同的问题,根本原因是 wicd。运行以下命令:

sudo service wicd stop
sudo service docker restart

"...应该就可以解决问题了。"

1
你真是个救命恩人,我花了6个小时在这上面,非常感谢你。 - Immutable Brick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接