docker-compose 服务内没有互联网
Posted
技术标签:
【中文标题】docker-compose 服务内没有互联网【英文标题】:no internet inside docker-compose service 【发布时间】:2017-02-13 12:32:58 【问题描述】:我无法从 docker-compose 容器访问外部网络。
考虑以下 docker-compose 文件:
version: '2'
services:
nginx:
image: nginx
使用简单的docker run -it nginx bash
我设法访问外部 IP 或 Internet IP (ping www.google.com
)。
另一方面,如果我使用 docker-compose 并附加到容器,我无法访问外部 IP 地址/DNS。
码头信息:
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
docker-compose 1.8.1,构建 878cff1
daemon.json 文件:
"iptables" : false,
"dns" : ["8.8.8.8","8.8.4.4"]
【问题讨论】:
你使用docker exec -it <container-name> ping google.com
吗?那应该可以。
这正是我所做的
您研究过网络吗? docker network inspect bridge 显示了什么?假设“桥”是默认网络。
您能否为这两个容器显示docker inspect <container-id>
?
【参考方案1】:
上次遇到这样的问题,我是这样解决的:
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上复现的可靠方式。
EDIT 根据您使用的 docker 版本,docker -d
命令可能不适合您,但不用担心,您可以省略该命令。
【讨论】:
ip link del docker0
如果您不使用 ifconfig,那么您可能不会在 2020 年使用。
感谢@ChaimEliyah 帮助了我,但现在我得到了这个brctl delbr docker0
-> ` 找不到命令“brctl”,但可以安装:`
@Zaffer 我猜你使用的系统默认不包含 brctl。此处假定为 Linux。【参考方案2】:
检查/etc/default/docker
以确保它没有以下行:
DOCKER_OPTS="--iptables=false"
还要检查/etc/docker/daemon.json
以确保它没有以下密钥:
"iptables":false
我们在一台服务器上添加了这个,以使 UFW 与 docker 一起工作。然后我们改为外部防火墙。花了很长时间寻找外部网络无法正常工作的原因,因为它已从我们的部署指南中删除。希望这对其他人有帮助。
【讨论】:
感谢这对我有帮助。不久前,我注意到 docker 在主机上打开端口,并覆盖 ufw。我已经按照这个禁用了 iptables:link 再次反转这个启用的容器网络。【参考方案3】:我刚碰到这个。使用docker run -it <image> bash
运行任何容器,我可以做任何我需要的与网络相关的事情,但是附加到通过 docker-compose 和docker exec -it <conatiner> bash
启动的容器不能运行任何东西。即使apt-get
也会因“名称解析错误中的临时失败”而失败。
我发现将network_mode: "bridge"
添加到每个服务将启用每个容器中的外部网络,但代价是将所有内容附加到默认 docker 网络。不过,我想保持堆栈隔离,因此请考虑另一种解决方案。
我运行docker inspect network bridge
来查看默认网络,我的堆栈网络也是如此。我发现的唯一显着差异是子网/网关的差异(我相信这是意料之中的,但是列出的 IP 差异显着,192.* vs 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】:Docker 容器默认具有访问互联网的能力。 以下是我上周解决问题的方法:docker container can only access internet with net host
或者你只是让容器处于主机模式:
version: '2'
service:
nginx:
image: nginx
network_mode: host
但正如@peedee 在评论中指出的那样,这种解决方案将失去主机和容器之间的网络分离。
【讨论】:
这样做你失去了主机和容器之间的所有分离。 @peedee 是的,我必须承认这一点。我检查了 [faas](get-faas.com) 项目的撰写文件,它只使用覆盖网络,似乎应该能够访问互联网。但我无法在我的计算机上执行此操作。 来自 Docker 文档:“注意:--network="host" 使容器可以完全访问本地系统服务,例如 D-bus,因此被认为是不安全的。”【参考方案5】:默认情况下,您正在拉取的图像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
创建的行为不同的容器。
不过,更清楚地了解如何检查互联网访问会有所帮助。
【讨论】:
【参考方案6】:在我的情况下,我通过snap
安装了 docker,在按照official website 的说明删除并安装后,它开始正常工作。
【讨论】:
以上是关于docker-compose 服务内没有互联网的主要内容,如果未能解决你的问题,请参考以下文章
how do you quit docker-compose up @ macOS?
尝试在运行 docker-toolbox 的 Windows 上使用 docker-compose 在 docker 容器内运行 webpack-dev-server 时出现“来自服务器的空回复”