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 服务内没有互联网的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose常用模板

how do you quit docker-compose up @ macOS?

docker-compose部署模板

docker-compose示例与命令介绍

尝试在运行 docker-toolbox 的 Windows 上使用 docker-compose 在 docker 容器内运行 webpack-dev-server 时出现“来自服务器的空回复”

有没有办法在不构建的情况下将 docker-compose 容器无缝传输到另一台主机? [复制]