我让它工作正常,但现在它停止了。我尝试了以下命令但无济于事:
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
有任何想法吗?
PSufw
也禁用了
首先要检查的是cat /etc/resolv.conf
在docker 容器中运行。如果它有一个无效的 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 将/etc/resolv.conf
使用来自daemon.json
.
2.修复主机的/etc/resolv.conf
A. Ubuntu 16.04 及更早版本
对于 Ubuntu 16.04 及更早版本,/etc/resolv.conf
由 NetworkManager 动态生成。
注释掉中的行dns=dnsmasq
(带有#
) /etc/NetworkManager/NetworkManager.conf
重新启动 NetworkManager 以重新生成/etc/resolv.conf
:
sudo systemctl restart network-manager
在主机上验证:cat /etc/resolv.conf
B. Ubuntu 18.04 及更高版本
Ubuntu 18.04 改为使用systemd-resolved
生成/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 复制到容器中。
按照以下建议修复:
[...] 您可以尝试重置所有内容吗?
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 的预期方法不是手动执行,而是使用service
orsystemctl
命令:
service docker restart
或者
systemctl restart docker
用 OSX 的答案更新这个问题(使用 Docker Machine)
如果您使用 Docker Machine 在 OSX 上运行 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 一切都会好起来的。
我不知道我在做什么,但这对我有用:
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
我正在使用DOCKER_OPTS="--dns 8.8.8.8"
,后来发现我的容器不能直接访问互联网,但可以访问我的公司内部网。我更改DOCKER_OPTS
为以下内容:
DOCKER_OPTS="--dns <internal_corporate_dns_address"
替换internal_corporate_dns_address
为我们的 DNS 的 IP 地址或 FQDN 并使用重新启动 docker
sudo service docker restart
然后生成我的容器并检查它是否可以访问互联网。
缺少代理设置也可能导致无法访问 Internet 。在这种情况下,--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 的请求)都将通过代理。
更多信息: Archlinux Wiki 中的代理设置。
当我的一个容器随机发生这种情况时,我被难住了,而其他容器很好。容器连接到至少一个非内部网络,因此定义没有问题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
对我来说,我的问题是因为 iptables-services 没有安装,这对我有用(CentOS):
sudo yum install iptables-services
sudo service docker restart
对我来说,这是主机的防火墙。我必须在主机的防火墙上允许 DNS。并且在更改主机防火墙设置后还必须重新启动 docker。
在 centos 8 上,我的问题是在启动 docker 服务之前我没有安装和启动 iptables。在启动 docker 服务之前,请确保 iptables 服务已启动并正在运行。
您可能已经使用 dns 选项启动了 docker--dns 172.x.x.x
我有同样的错误,并从/etc/default/docker
这些行:
# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="--dns 172.x.x.x"
对我来说,这是一个 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
我在 Ubuntu 18.04 上遇到了问题。但是,问题出在 DNS 上。我在一个拥有自己的 DNS 服务器并阻止其他 DNS 服务器的公司网络中。这是为了阻止某些网站(色情、种子等)
解决您的问题
按照@jobin的建议使用 --dns your_dns
docker run --dns your_dns -it --name cowsay --hostname cowsay debian bash
对于使用 openconnect 8.3 for VPN 的 Ubuntu 19.04,我必须将 /etc/resolve.conf 符号链接到 systemd 中的那个(与 answerby wisbucky 相对)
sudo ln -sf /etc/resolv.conf /run/systemd/resolve/resolv.conf
调试步骤
Docker版本:Docker版本19.03.0-rc2,构建f97efcc
为后代分享一个简单而有效的解决方案。当我们在没有明确提及标志的情况下运行 docker 容器时--network
,它会连接到其默认的桥接网络,该网络禁止连接到外部世界。要解决这个问题,我们必须创建自己的桥接网络(用户定义的桥接),并且必须使用 docker run 命令明确提及它。
docker network create --driver bridge mynetwork
docker run -it --network mynetwork image:version
其他答案表明docker0
接口(桥)可能是问题的根源。在 Ubuntu 20.04 上,我观察到接口缺少其 IP 地址(要检查ip addr show dev docker0
)。单独重启 Docker 并没有帮助。我不得不手动删除网桥接口。
sudo ip link delete docker0
sudo systemctl restart docker
如果您使用的是 OSX,则可能需要在安装 Docker 后重新启动计算机。这有时是一个问题。
在 Windows(8.1)上,我杀死了 virtualbox 界面(通过 taskmgr),它解决了这个问题。
最初我的 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>
对我来说,使用 centos 7.4,这不是 /etc/resolve.conf、iptables、iptables nat 规则的问题,也不是 docker 本身的问题。问题是主机缺少 docker 使用命令 brctl 构建网桥所需的包 bridge-utils。yum install -y bridge-utils 并重启docker,问题解决。
它帮助我:
sudo ip link delete docker0
sudo systemctl stop docker.socket
sudo systemctl stop docker.service
sudo systemctl start docker.socket
sudo systemctl start docker.service
注意:在此之后,接口 docker0 必须具有这样的 ip 地址:
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
只需在此处添加此内容,以防有人在运行 docker 的 virtualbox 容器中遇到此问题。我将virtualbox网络重新配置为桥接而不是nat,问题就消失了。
尝试了所有答案,没有一个对我有用。
在尝试了我能找到的所有其他东西几个小时后,这成功了:
reboot
-_-
我在这里尝试了大多数答案,但唯一有效的是重新创建网络:
$ docker network rm the-network
$ docker network create --driver=bridge the-network
我还需要重新创建使用它的 docker 容器:
$ sudo docker create --name the-name --network the-network
然后它从互联网访问开始。
我在 Ubuntu 上尝试使用 Docker-Compose 设置项目时也遇到了这样的问题。
当我尝试 ping 任何 IP 地址或 nslookup 某个 URL 时,Docker 根本无法访问互联网 - 它一直失败。
我尝试了上述所有可能的 DNS 解析解决方案,但均无济于事。
我花了一整天的时间试图找出到底发生了什么,最后发现所有麻烦的原因是防病毒软件,特别是防火墙,它出于某种原因阻止了 Docker 获取 IP 地址和端口。
当我禁用它时 - 一切正常。
因此,如果您安装了防病毒软件并且没有任何帮助解决问题 - 问题可能是防病毒软件的防火墙。
最近几天我遇到了类似的问题。对我来说,原因是 systemd、docker 和我的托管服务提供商的结合。我正在运行最新的 CentOS (7.7.1908)。
我的托管服务提供商会自动为 systemd-networkd 生成一个配置文件。从 CentOS 7 的当前版本 systemd 219 开始,systemd-networkd 控制了与网络相关的 sysctl 参数。Docker 似乎与此版本不兼容,并且每次启动容器时都会重置 IP-Forwarding 标志。
我的解决方案是IPForward=true
在[Network]
我的提供程序生成的配置文件的 - 部分中添加。该文件可能位于多个位置,最有可能位于/etc/systemd/network
.
该过程也在官方 docker 文档中有所描述:https ://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/#ip-forwarding-problems
赶紧跑
sudo apt install bridge-utils
已经有很多好的答案了。我最近在运行 armbian 的橙色 pi 电脑上遇到了类似的问题。Docker 容器被阻止到 Internet。这个命令解决了我的问题。所以我喜欢分享
docker run --security-opt seccomp=unconfined imageName
问题是linux使用旧版本的libseccomp2
rpi ~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138
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
我在 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
}