Docker - 无主机路由

Ric*_*ckD 7 docker

当我尝试连接到我的容器内的端口到另一个容器时,我不成功并得到,

root@ac1590a59fe5:/opt/f5massupgrade# curl -v https://172.17.0.1:6379
* Rebuilt URL to: https://172.17.0.1:6379/
* Hostname was NOT found in DNS cache
*   Trying 172.17.0.1...
* connect to 172.17.0.1 port 6379 failed: No route to host
* Failed to connect to 172.17.0.1 port 6379: No route to host
* Closing connection 0
Run Code Online (Sandbox Code Playgroud)

从docker主机我成功了,

[root@docker-host ~]# curl -v https://172.17.0.1:6379/0
* About to connect() to 172.17.0.1 port 6379 (#0)
*   Trying 172.17.0.1...
* Connected to 172.17.0.1 (172.17.0.1) port 6379 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
Run Code Online (Sandbox Code Playgroud)

如果我检查iptables我可以看到问题,

[root@docker-host ~]#  iptables -S INPUT
-P INPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i docker0 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
Run Code Online (Sandbox Code Playgroud)

所以我添加以下内容并且一切正常,

iptables -I INPUT 4 -i docker0 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

[root@docker-host ~]# docker version
Client:
 Version:         1.9.1
 API version:     1.21
 Package version: docker-common-1.9.1-40.el7.centos.x86_64
 Go version:      go1.4.2
 Git commit:      ab77bde/1.9.1
 Built:
 OS/Arch:         linux/amd64

Server:
 Version:         1.9.1
 API version:     1.21
 Package version: docker-common-1.9.1-40.el7.centos.x86_64
 Go version:      go1.4.2
 Git commit:      ab77bde/1.9.1
 Built:
 OS/Arch:         linux/amd64
Run Code Online (Sandbox Code Playgroud)

谢谢,

al.*_*al. 38

我们在运行的 RHEL 机器上遇到了这个问题firewalld。防火墙阻止容器访问主机(icmp流量除外)。

我们需要配置防火墙以允许从 docker 容器到主机的流量。在我们的例子中,容器位于子网上的桥接网络中172.27.0.0/16(通过docker network ls和确定docker inspect <network-name>)。firewalld可以通过以下方式更新防火墙规则:

firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=172.27.0.0/16 accept'
firewall-cmd --reload
Run Code Online (Sandbox Code Playgroud)

这是解决问题的有用参考

  • 它对我不起作用。我需要运行 `firewall-cmd --zone=public --add-masquerade --permanent` (4认同)

小智 25

如果有人在 CentOS 8 或任何使用 firewalld 的系统上仍然遇到此问题

为 firewalld 尝试以下设置

# Allows container to container communication, the solution to the problem
firewall-cmd --zone=public --add-masquerade --permanent

# standard http & https stuff
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
# + any other port you may need

# reload the firewall
firewall-cmd --reload
Run Code Online (Sandbox Code Playgroud)

如果 docker 服务不能立即工作,您可能还需要重新启动它,没有必要将docker0接口添加到受信任区域,因为我已经阅读了许多指南

我正在努力为我的 docker 容器设置 Traefik 反向代理,我只收到了 502 个响应,没有从 Traefik 日志到我的容器的路由错误。起初我以为这是我的 Traefik 设置,但事实证明这是@al 的防火墙限制。提及。它为我指明了正确的方向,我从https://serverfault.com/questions/987686/no-network-connectivity-to-from-docker-ce-container-on-centos-8得到了答案


Iqb*_*bal 9

这些在 Fedora 32 上对我有用

$ sudo firewall-cmd --zone=public --add-masquerade --permanent
$ sudo firewall-cmd --reload
$ sudo systemctl restart docker
Run Code Online (Sandbox Code Playgroud)


Ale*_*red 7

自定义下面的内核可调参数正在解决 docker 容器之间的“无主机路由”问题:

sysctl net.bridge.bridge-nf-call-iptables=0
sysctl net.bridge.bridge-nf-call-arptables=0
sysctl net.bridge.bridge-nf-call-ip6tables=0
Run Code Online (Sandbox Code Playgroud)

这些控制是否将穿过网桥的数据包​​发送到 iptables 进行处理。

请注意,如果您将它添加到 sysctl.conf,根据您的 linux 发行版,它可能不会在重启期间作为已知错误自动应用。


小智 5

尝试在标志 --net 设置为 host 的情况下运行容器。

docker run --net host image 
Run Code Online (Sandbox Code Playgroud)


Sam*_*uel 5

对我来说问题是 MAC 地址冲突...不知道这是怎么发生的...

  • 你的回答救了我一命。我能够解决我的问题并找到原因。我的答案的 TL;DR:Docker 组合,多个网络,MAC 地址是根据自动创建的网络选择的,但也用于已加入的网络以及已在使用的网络中 (2认同)