我的 docker 容器没有互联网
Posted
技术标签:
【中文标题】我的 docker 容器没有互联网【英文标题】:My docker container has no internet 【发布时间】:2013-12-24 04:28:20 【问题描述】:我让它正常工作,但现在它停止了。我尝试了以下命令但无济于事:
docker run -dns 8.8.8.8 base ping google.com
docker run base ping google.com
sysctl -w net.ipv4.ip_forward=1
- 在主机和容器上都有
我得到的只是unknown host google.com
。 Docker 版本 0.7.0
有什么想法吗?
附: ufw
也禁用了
【问题讨论】:
你的问题解决了我的问题:必须运行sysctl -w net.ipv4.ip_forward=1
(在 Centos 6 上)
由于您可能遇到 docker dns 路由的问题,请查看此类似的解决方案***.com/questions/35515203/…
同样,在我将 /etc/resolv.conf 固定在主机箱上之后,如果没有sysctl -w net.ipv4.ip_forward=1
,它就无法工作
还要检查主机机器上/etc/resolv.conf
的值是否正确
在sysctl -w net.ipv4.ip_forward=1
之后我必须运行sudo service docker restart
。
【参考方案1】:
首先要检查的是在 docker 容器 中运行 cat /etc/resolv.conf
。如果它有一个无效的DNS服务器,例如nameserver 127.0.x.x
,那么容器将无法将域名解析为ip地址,所以ping google.com
会失败。
要检查的第二件事是在主机上运行cat /etc/resolv.conf
。 Docker基本上每次启动容器时都会将主机的/etc/resolv.conf
复制到容器中。所以如果宿主的/etc/resolv.conf
错了,那么docker容器也会错。
如果你发现宿主的/etc/resolv.conf
是错误的,那么你有2个选择:
在 daemon.json 中硬编码 DNS 服务器。这很容易,但如果您希望 DNS 服务器发生变化,这并不理想。
修复主机的/etc/resolv.conf
。这有点棘手,但它是动态生成的,而且您不会对 DNS 服务器进行硬编码。
1.在 docker daemon.json 中硬编码 DNS 服务器
编辑/etc/docker/daemon.json
"dns": ["10.1.2.3", "8.8.8.8"]
重新启动 docker 守护程序以使这些更改生效:sudo systemctl restart docker
现在,当您运行/启动容器时,docker 将使用来自 daemon.json
的值填充 /etc/resolv.conf
。
2。修复主机的/etc/resolv.conf
A. Ubuntu 16.04 及更早版本
对于 Ubuntu 16.04 及更早版本,/etc/resolv.conf
由 NetworkManager 动态生成。
注释掉/etc/NetworkManager/NetworkManager.conf
中的dns=dnsmasq
行(带有#
)
重启 NetworkManager 以重新生成/etc/resolv.conf
:sudo systemctl restart network-manager
在主机上验证:cat /etc/resolv.conf
B. Ubuntu 18.04 及更高版本
Ubuntu 18.04 改为使用systemd-resolved
to generate /etc/resolv.conf
。现在默认情况下它使用本地 DNS 缓存 127.0.0.53。这在容器内是行不通的,因此 Docker 将默认使用 Google 的 8.8.8.8 DNS 服务器,这可能会被防火墙后面的人破坏。
/etc/resolv.conf
实际上是一个符号链接 (ls -l /etc/resolv.conf
),在 Ubuntu 18.04 中默认指向 /run/systemd/resolve/stub-resolv.conf
(127.0.0.53)。
只需将符号链接更改为指向/run/systemd/resolve/resolv.conf
,它会列出真实的 DNS 服务器:sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
在主机上验证:cat /etc/resolv.conf
现在您应该在主机上拥有一个有效的/etc/resolv.conf
,以便 docker 将其复制到容器中。
【讨论】:
这解决了 Ubuntu 16.04 和 Docker 17.09 上的问题。 这解决了我的问题(与 OP、Ubuntu 14.04 / Docker 18.01.0-ce 相同)。如果您的 docker 映像上没有 ping 命令,此链接可能很有用 test internet connection without ping。如果您的主机没有systemctl
(Ubuntu 14.04),请尝试 How to restart the networking service? 和/或重新启动计算机。
这适用于 Ubuntu 18.04(选项 B)。然而 docker 并没有将现在正确的/etc/resolv.conf
转移到正在构建的容器中,我不得不手动将文件复制到容器中。
在我的机器(RedHat 7.4)上,主机的配置文件是正确的,但容器文件仍然指向 172.0.0.11。那么现在该怎么办?
Ubuntu 20 有什么变化吗?请更新一下好吗?【参考方案2】:
按照以下建议修复:
[...] 你可以尝试重置所有内容吗?
pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
docker -d
它将强制 docker 重新创建网桥并重新初始化所有网络规则
https://github.com/dotcloud/docker/issues/866#issuecomment-19218300
似乎界面以某种方式“挂起”。
更新 docker 的最新版本:
上面的答案可能仍然可以为您完成工作,但是自从发布此答案以来已经很长时间了,并且 docker 现在更加完善,因此请确保您先尝试这些,然后再使用 iptables
和所有内容进行修改.
sudo service docker restart
或(如果您使用的是不使用 upstart 的 linux 发行版)sudo systemctl restart docker
【讨论】:
docker -d
失败。没有-d
标志。
对于那些仍然有问题的人,Moby 的 github 上有一个开放的问题,已经开放了一年多:github.com/moby/moby/issues/26567
@Pawan: ip link del docker0
或安装 bridge-utils
docker -d
在较新的版本中不存在。而是:service docker stop
,然后是 dockerd
,然后是 service docker start
【参考方案3】:
重新启动 docker 的预期方法不是手动执行,而是使用 service
或 systemctl
命令:
service docker restart
或
systemctl restart docker
【讨论】:
如果你在一个不使用 upstart 的 linux 发行版中,sudo systemctl restart docker 为我工作 重启工作正常。我不知道这是否与我启用它“自动启动”这一事实有关 (systemctl enable docker
)
似乎与 OP 的问题无关。
确实如此,因为在 OP 所描述的情况下,重置 docker 会重新初始化网络接口,从而重新启用互联网访问。确实,这并没有解决为什么它有时会中断,但它提供了解决问题的方法。
但是在生产环境中,重启docker是不可能的。本案的问题如何解决?【参考方案4】:
用 OSX 的答案更新这个问题(使用 Docker 机器)
如果您在 OSX 上使用 Docker Machine 运行 Docker,那么以下对我有用:
docker-machine restart
<...wait for it to restart, which takes up to a minute...>
docker-machine env
eval $(docker-machine env)
那么(至少根据我的经验),如果您从容器中 ping google.com,一切都会好起来的。
【讨论】:
还在 Windows 中工作以使网络访问再次正常工作。 这对我有用。我在顶部菜单栏中有一个泊坞窗图标,在菜单中我有一个“重新启动”选项。之后,网络又好了【参考方案5】:我不知道我在做什么,但这对我有用:
OTHER_BRIDGE=br-xxxxx # this is the other random docker bridge (`ip addr` to find)
service docker stop
ip link set dev $OTHER_BRIDGE down
ip link set dev docker0 down
ip link delete $OTHER_BRIDGE type bridge
ip link delete docker0 type bridge
service docker start && service docker stop
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.18.0.0/16 -j MASQUERADE
service docker start
【讨论】:
漂亮的胶带! 您的回答有助于解决类似问题。我花了几个小时在上面!在不完整的 Kubespray 安装后,Docker 容器在尝试 ping 任何公共主机或 IP 时失去了互联网并显示“临时故障解决”消息。所以我没有这个强制性的规则 -iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
。您可以使用iptables -t nat -L POSTROUTING
检查您是否有此规则
无论这个问题是什么,我都讨厌它。我非常讨厌它,哈哈。 Docker 在启动时从不连接到互联网,但如果我运行这些东西,它就会神奇地工作。直到下次重新启动...
使用OTHER_BRIDGE=$(ip addr | grep -E -m 1 -o 'br-[0-9a-f]+')
自动抓取第一个网桥ID【参考方案6】:
我使用DOCKER_OPTS="--dns 8.8.8.8"
,后来发现我的容器无法直接访问互联网,但可以访问我的公司内部网。我将DOCKER_OPTS
更改为以下内容:
DOCKER_OPTS="--dns <internal_corporate_dns_address"
用我们的 DNS 的 IP 地址或 FQDN 替换 internal_corporate_dns_address
并使用重新启动 docker
sudo service docker restart
然后生成我的容器并检查它是否可以访问互联网。
【讨论】:
【参考方案7】:缺少代理设置也可能导致无法访问互联网。在这种情况下,--network host
也可能不起作用。可以通过设置环境变量http_proxy
和https_proxy
来配置代理:
docker run -e "http_proxy=YOUR-PROXY" \
-e "https_proxy=YOUR-PROXY"\
-e "no_proxy=localhost,127.0.0.1" ...
不要忘记设置 no_proxy,否则 所有 请求(包括到 localhost 的请求)将通过代理。
更多信息:Proxy Settings Archlinux Wiki。
【讨论】:
这是我的解决方案。但请注意:我使用的是 alpine,它有一个 wget 的 busybox 实现,似乎忽略了代理设置,所以我没有看到设置环境变量的好处。 感谢有关busybox的提示;我还不知道! 请注意,有些操作系统需要大写,例如文档link。 这个语法给了我docker: invalid reference format.
我认为正确的是在@Flo 提到的链接中:-e HTTP_PROXY="proxy.."...
另外,分配到多行的`\` 给出了类似的错误【参考方案8】:
当我的一个容器随机发生这种情况时,我被难住了,而其他容器都很好。该容器连接到至少一个非内部网络,因此Compose
的定义没有任何问题。重新启动 VM / docker 守护程序没有帮助。这也不是 DNS 问题,因为容器甚至无法 ping
外部 IP。为我解决的问题是重新创建 docker 网络。就我而言,docker-compose down && docker-compose up
有效。
撰写
这会强制重新创建所有容器的所有网络:
docker-compose down
&& docker-compose up
群模式
我想您只是删除并重新创建服务,从而重新创建服务的网络:
docker service rm some-service
docker service create ...
如果容器的网络是外部的
只需删除并重新创建该服务的外部网络:
docker network rm some-external-network
docker network create some-external-network
【讨论】:
【参考方案9】:对我来说,我的问题是因为没有安装 iptables-services,这对我有用(CentOS):
sudo yum install iptables-services
sudo service docker restart
【讨论】:
记得启动并启用 iptable 服务 也适用于红帽 7.3【参考方案10】:对我来说,这是主机的防火墙。我必须在主机的防火墙上允许 DNS。并且在更改主机防火墙设置后还必须重新启动 docker。
【讨论】:
或者您可以通过sudo service iptables stop
和 sudo chkconfig iptables off
禁用 iptables(在 CentOS/RHEL 上)。【参考方案11】:
在 centos 8 上, 我的问题是在启动 docker 服务之前我没有安装和启动 iptables。在启动 docker 服务之前,请确保 iptables 服务已启动并正在运行。
【讨论】:
我在 centos8 上遇到了同样的问题【参考方案12】:对我来说,这是一个 iptables 转发规则。出于某种原因,以下规则与 docker 的 iptables 规则结合使用时,导致来自容器的所有出站流量都命中localhost:8080
:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
【讨论】:
那么...解决方案是什么? :) 我有第一条规则,需要它将 80 上的入站流量重定向到 8080。如何更改此规则以不影响出站流量? 抱歉,我对 iptables 的记忆已经褪色,但在我的设置脚本中,我看到iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
是最后一行,位于默认值(iptables -P INPUT DROP
等)之后。没有 OUTPUT...REDIRECT 行。【参考方案13】:
您可能已经使用 dns 选项 --dns 172.x.x.x
启动了您的 docker
我遇到了同样的错误,并从 /etc/default/docker
中删除了选项
线条:
# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="--dns 172.x.x.x"
【讨论】:
【参考方案14】:我在 Ubuntu 18.04 上遇到了问题。但是,问题出在 DNS 上。我在一个拥有自己的 DNS 服务器并阻止其他 DNS 服务器的公司网络中。这是为了阻止某些网站(色情、种子等)
解决您的问题
-
find your DNS 在主机上
按照建议使用 --dns your_dns 通过@jobin
docker run --dns your_dns -it --name cowsay --hostname cowsay debian bash
【讨论】:
【参考方案15】:对于使用 openconnect 8.3 for *** 的 Ubuntu 19.04,我必须将 /etc/resolve.conf 符号链接到 systemd 中的那个(与 answerby wisbucky 相对)
sudo ln -sf /etc/resolv.conf /run/systemd/resolve/resolv.conf
调试步骤
-
连接到公司 ***
在 /etc/resolv.conf 或 /run/systemd/resolve/resolv.conf 中查找正确的 *** 设置
无论哪个具有正确的 DNS 设置,我们都会将其符号链接到另一个文件
(提示:在作业左侧放置一个设置正确的)
Docker 版本:Docker 版本 19.03.0-rc2,构建 f97efcc
【讨论】:
谢谢。使用 Ubuntu 18.04,在连接到公司 *** 时,只有 /etc/resolve.conf 被 DHCP 更新,而 /run/systemd/resolve/resolve/conf 保持不变/静态。该解决方案有所帮助。现在,本地机器中的容器连接到 *** 中的服务器(这对我来说之前没有发生)【参考方案16】:在 windows (8.1) 上,我杀死了 virtualbox 界面(通过 taskmgr),它解决了这个问题。
【讨论】:
【参考方案17】:最初我的 docker 容器能够访问外部互联网(这是在 Amazon EC2 上运行的 docker 服务/容器)。
由于我的应用程序是一个 API,因此我在创建容器(它成功提取了它需要的所有包)之后更新了我的 IP 表,以将所有流量从端口 80 路由到我的 API(在其上运行)的端口docker) 正在监听。
然后,后来当我尝试重建容器时,它失败了。经过一番挣扎,我发现我之前的步骤(设置 IPTable 端口转发规则)搞砸了 docker 的外部网络能力。
解决方案:停止您的 IPTable 服务:
sudo service iptables stop
重启 Docker 守护进程:
sudo service docker restart
然后,尝试重建您的容器。希望这会有所帮助。
跟进
我完全忽略了我不需要弄乱 IP 表来将传入流量转发到 80 到在 docker 上运行的 API 正在运行的端口。相反,我只是将端口 80 别名为 docker 中的 API 正在运行的端口:
docker run -d -p 80:<api_port> <image>:<tag> <command to start api>
【讨论】:
就我而言,我只需要重新启动 docker Daemon,它就可以工作了【参考方案18】:对我来说,使用 centos 7.4,这不是 /etc/resolve.conf、iptables、iptables nat 规则的问题,也不是 docker 本身的问题。问题是主机缺少 docker 使用命令 brctl 构建网桥所需的包 bridge-utils。 yum install -y bridge-utils 重启docker,问题解决。
【讨论】:
这就是我支持它的原因。但我的评论是为了温和地提醒您,原因和缺陷有时会有些不同,提交票证可以帮助其他人解决问题,即使第一直觉是解决根本问题。【参考方案19】:为后代分享一个简单而有效的解决方案。当我们在没有明确提及 --network
标志的情况下运行 docker 容器时,它会连接到其默认的桥接网络,该网络禁止连接到外部世界。为了解决这个问题,我们必须创建自己的桥接网络(用户定义的桥接),并且必须使用 docker run 命令明确提及它。
docker network create --driver bridge mynetwork
docker run -it --network mynetwork image:version
【讨论】:
【参考方案20】:其他答案表明docker0
接口(网桥)可能是问题的根源。在 Ubuntu 20.04 上,我观察到接口丢失了它的 IP 地址(通过ip addr show dev docker0
进行检查)。单独重启 Docker 并没有帮助。我不得不手动删除桥接接口。
sudo ip link delete docker0
sudo systemctl restart docker
【讨论】:
【参考方案21】:如果您使用的是 OSX,则可能需要在安装 Docker 后重新启动计算机。这有时是个问题。
【讨论】:
【参考方案22】:只需在此处添加此内容,以防有人在运行 docker 的 virtualbox 容器中遇到此问题。我将 virtualbox 网络重新配置为桥接而不是 nat,问题就消失了。
【讨论】:
【参考方案23】:我在这里尝试了大多数答案,但唯一有效的是重新创建网络:
$ docker network rm the-network
$ docker network create --driver=bridge the-network
我还需要重新创建使用它的 docker 容器:
$ sudo docker create --name the-name --network the-network
然后它开始访问互联网。
【讨论】:
【参考方案24】:我在 Ubuntu 上尝试使用 Docker-Compose 设置项目时也遇到了这样的问题。
当我尝试 ping 任何 IP 地址或 nslookup 某个 URL 时,Docker 根本无法访问互联网 - 它一直失败。
我尝试了上述所有可能的 DNS 解析解决方案,但均无济于事。
我花了一整天的时间试图找出到底发生了什么,最后发现所有问题的原因是防病毒软件,特别是防火墙,它出于某种原因阻止了 Docker 获取 IP 地址和港口。
当我禁用它时 - 一切正常。
所以,如果您安装了防病毒软件,但没有任何帮助解决问题 - 问题可能是防病毒软件的防火墙。
【讨论】:
【参考方案25】:过去几天我遇到了类似的问题。对我来说,原因是 systemd、docker 和我的托管服务提供商的结合。我正在运行最新的 CentOS (7.7.1908)。
我的托管服务提供商会自动为 systemd-networkd 生成一个配置文件。从 CentOS 7 的当前版本 systemd 219 开始,systemd-networkd 控制了与网络相关的 sysctl 参数。 Docker 似乎与此版本不兼容,每次启动容器时都会重置 IP-Forwarding 标志。
我的解决方案是在我的提供程序生成的配置文件的[Network]
-部分中添加IPForward=true
。该文件可能位于多个位置,最有可能位于 /etc/systemd/network
。
官方 docker 文档中也描述了这个过程:https://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/#ip-forwarding-problems
【讨论】:
能否指定您设置此参数的确切位置?我的位置与您完全相同,在 Google Cloud Platform 上运行虚拟机,但在服务器上找不到任何 *.network 文件。仅在/usr/lib/sysctl.d/50-default.conf
上,但语法不同。
我的集群是自我管理的,我的提供商只在设置时进行基本的引导。我的网络配置是/etc/systemd/network/10-mainif.network
。根据 systemd 手册页,您可能会检查的其他位置是 /usr/local/lib/systemd/
和 /usr/lib/systemd/
。【参考方案26】:
快跑
sudo apt install bridge-utils
【讨论】:
【参考方案27】:已经有很多好的答案了。我最近在运行 armbian 的橙色 pi 电脑上遇到了类似的问题。 Docker 容器被阻止到 Internet。这个命令解决了我的问题。所以我喜欢分享它
docker run --security-opt seccomp=unconfined imageName
【讨论】:
【参考方案28】:尝试了所有答案,没有一个对我有用。
在尝试了我能找到的所有其他方法几个小时后,这成功了:
reboot
-_-
【讨论】:
【参考方案29】:经过几个小时的努力,我终于解决了我的问题
问题在于 linux 使用旧版本的 libseccomp2
获取签名密钥以验证新包,否则将无法安装
rpi ~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138
将 Buster backport 存储库添加到 apt sources.list
rpi ~$ echo 'deb http://httpredir.debian.org/debian buster-backports main contrib non-free' | sudo tee -a /etc/apt/sources.list.d/debian-backports.list
rpi ~$ sudo apt update
rpi ~$ sudo apt install libseccomp2 -t buster-backports
尝试后
rpi ~$ docker run -it --rm alpine:3.15.0
(alpine shell)# apk update
apk update
将获取并因此您已连接到互联网
我正在使用
Linux raspberrypi 5.10.63-v7l+ #1496 SMP Wed Dec 1 15:58:56 GMT 2021 armv7l GNU/Linux
您可以使用uname -a
查看
【讨论】:
【参考方案30】:我在 Arch Linux 上,在尝试了上述所有答案后,我意识到我在我的机器上启用了防火墙 nftables
,然后禁用它就可以了。我做到了:
sudo systemctl disable nftables
sudo systemctl stop nftables
sudo reboot
我的网卡:
➜ ~ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
link/ether 68:f7:28:84:e7:fe brd ff:ff:ff:ff:ff:ff
3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
link/ether d0:7e:35:d2:42:6d brd ff:ff:ff:ff:ff:ff
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:43:3f:ff:94 brd ff:ff:ff:ff:ff:ff
5: br-c51881f83e32: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:ae:34:49:c3 brd ff:ff:ff:ff:ff:ff
6: br-c5b2a1d25a86: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:72:d3:6f:4d brd ff:ff:ff:ff:ff:ff
8: veth56f42a2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether 8e:70:36:10:4e:83 brd ff:ff:ff:ff:ff:ff link-netnsid 0
还有我的防火墙配置/etc/nftables.conf
,我现在禁用了它,以后会尝试改进,以便我可以正确设置docker0
网卡规则:
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:
# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.
table inet filter
delete table inet filter
table inet filter
chain input
type filter hook input priority filter
policy drop
ct state invalid drop comment "early drop of invalid connections"
ct state established, related accept comment "allow tracked connections"
iifname lo accept comment "allow from loopback"
ip protocol icmp accept comment "allow icmp"
meta l4proto ipv6-icmp accept comment "allow icmp v6"
#tcp dport ssh accept comment "allow sshd"
pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
counter
chain forward
type filter hook forward priority filter
policy drop
【讨论】:
以上是关于我的 docker 容器没有互联网的主要内容,如果未能解决你的问题,请参考以下文章
我怎么知道第三方 docker 镜像可以访问我们的上传数据到容器