我无法通过docker-compose容器访问外部网络。
考虑以下docker-compose文件:
#!/bin/bash
for x in `ps -ef | awk '{ print $2 }' | grep -v PID`
do
#----- do something -----
echo $x
done
使用简单的version: '2'
services:
nginx:
image: nginx
我设法访问外部IP或Internet IP(docker run -it nginx bash
)。
另一方面,如果我使用docker-compose并附加到容器,我无法访问外部IP地址/ DNS。
码头信息:
ping www.google.com
docker-compose 1.8.1,build 878cff1
daemon.json文件:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 1.12.1
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 7
Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge null host overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-38-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.859 GiB
Name: ***
ID: ****
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
Insecure Registries:
127.0.0.0/8
答案 0 :(得分:5)
上次我遇到这样的问题时,我解决了这个问题:
https://github.com/docker/docker/issues/866#issuecomment-19218300
pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
docker -d
它将强制docker重新创建网桥并重新启动所有网络规则。
至于为什么会发生这种情况的原因,我没有很好的答案。但我最近将问题追溯到journald
。当我重新启动journald
时(例如因为我更改了它的配置),docker-compose容器内的DNS解析一致/可重复地中断。我不知道为什么,我只能说这是一种可靠的方式让我在RHEL上重现它。
编辑 docker -d
命令可能不适用于你所使用的docker版本,但不用担心,你可以省略该命令。
答案 1 :(得分:3)
检查/etc/default/docker
以确保它没有以下行:
DOCKER_OPTS="--iptables=false"
同时检查/etc/docker/daemon.json
以确保它没有以下密钥:
{
"iptables":false
}
我们在一台服务器上添加了这个以使UFW与docker一起工作。然后我们改为外部防火墙。花了很长时间寻找外部网络无法正常工作的原因,因为它已从我们的部署指南中删除。希望这有助于其他人。
答案 2 :(得分:1)
您提取的图片nginx
默认情况下未安装ping
。因此,如果您确实使用ping来测试连接,则必须先安装它。
我创建了一个自定义Dockerfile来安装它:
FROM nginx:latest
RUN apt update && apt -y install iputils-ping
然后我在本地构建并标记为mynginx
。
然后我更改了docker-compose.yml
以使用自定义图片mynginx
:
version: '2'
services:
nginx:
image: mynginx
最后,我解雇了docker-compose up
,并在其中做了一个docker exec,并测试了ping。一切都很好。我也做了docker run -ti ...
并且它有效。
我的问题是,docker run
如何为您提供与docker-compose up
创建的行为不同的容器。
更清楚地了解如何检查互联网访问将会有所帮助。
答案 3 :(得分:0)
我刚遇到这个。使用 docker run -it <image> bash
运行任何容器,我可以执行任何我需要的与网络相关的操作,但是附加到通过 docker-compose 启动的容器并使用 docker exec -it <conatiner> bash
无法运行。甚至 apt-get
也会因“名称解析错误暂时失败”而失败。
我发现向每个服务添加 network_mode: "bridge"
会在每个容器中启用外部网络,代价是将所有内容附加到默认的 docker 网络。不过,我想保持堆栈隔离,因此着手寻找替代解决方案。
我运行 docker inspect network bridge
来查看默认网络,我的堆栈网络也是如此。我发现的唯一显着差异是子网/网关的差异(我认为这是意料之中的,但是列出的 IP 显着,192.* 与 172.*),以及默认网络有几个堆栈网络中不存在的选项:
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
我能够将它隔离到 "com.docker.network.bridge.default_bridge": "true"
,但是这破坏了堆栈外容器的网络,以至于我最终不得不完全删除并重新安装 docker。我假设 docker 守护进程与标记为默认的两个网络混淆,并且即使删除堆栈网络后也无法解决它。
这样做后我注意到的一件事是子网和 getway 与默认适配器仅相差一个。我确认删除上述选项会将子网和网关恢复到我最初看到的样子,它确实做到了。然后我在我的撰写文件中使用了这个网络配置:
networks:
default:
driver: "bridge"
ipam:
driver: default
config:
- subnet: X.X.0.0/16
其中子网的第一个值与默认网桥适配器相同,第二个值加一。这至少让一切正常,没有默认适配器仍然损坏。
有趣的是,当我去重新安装 docker 尝试修复默认网络时,我在查看 docker compose network documentation for external networking 后基本上运行了以下内容。
sudo snap remove docker
sudo sysctl net.ipv4.conf.all.forwarding=1
sudo iptables -P FORWARD ACCEPT
sudo snap install docker
随后删除了网络设置的 docker-compose up -d
会生成我之前定义的相同子网 IP,而没有为其提供配置。我认为潜在的问题很简单,因为某些东西阻止了 docker 守护进程正确找到可用的有效子网,一旦解决,一切都应该重新开箱即用。
答案 4 :(得分:0)
就我而言,我通过 snap
安装了 docker,按照 official website 中的说明将其删除并安装后,它开始正常工作。
答案 5 :(得分:-1)
Docker容器默认具有访问互联网的能力。 以下是我上周解决问题的方法:docker container can only access internet with net host
或者您只是让容器处于主机模式:
version: '2'
service:
nginx:
image: nginx
network_mode: host
但正如@peedee在评论中指出的那样,这个解决方案将失去主机和容器之间的网络分离。