首页 » 翻译 » Docker » 正文

docker 端口绑定到ipv6 导致ipv4请求无法转发

核心的原因, docker 对与ipv6默认是没有打开forwarding 设置的

首先官方的介绍:

在默认的配置中,流量的端口转发分为两种:内部流量转发(本机),外部流量转发(跨机器)

举个例子:

这个操作会在iptables中增加如下策略(是的,docker所有的端口转发都是靠iptables实现的)

防火墙的大致意思:所有的对本地的流量请求要走DOCKER这条链(chain)

所以只要请求到达Docker 这条链路,任何从docker0返回的数据会立即返回,因为在PREROUTING链中并没有相关docker0的流量控制

你还会发现有一个docker-proxy在运行,这用来处理来“桥”的请求的,docker-proxy会监听物理主机的80端口,然后将所有的请求转发到docker 容器中,这仅仅是本地的流量请求处理,不包含其他

 

你还会发现在DNAT的规则最后(Docker),任何来自80段口的流量,如果源地址不是来自docker0,会被转发到容器的ip地址的80段口,这一段,是为外部请求设定的,外部请求会直接转发到容器,不会经过任何的物理主机的network stack.

这样看来,通过命令curl localhost 足以来验证我们的容器是否可用来,或者也可以使用netstat来看一下docker-proxy是否监听到tcp4上,但是,这只能证明我们的容器,本地可用,仅仅本地

其实我们的docker-proxy的策略可以更加深层的设置为: 仅仅转发    源ip是目标ip并且段口是指定桥的名字的,但是这会额外增加特别多的防火墙规则,而且有一个kernel bug 和这个相关,所以我们默认是关闭的

netstat output:

也可以通过lsof来判定:

其实我们有两种方案解决:

1:关闭ipv6 ubuntu:

注意: ubuntu 14 :  vim /etc/sysctl.conf

然后执行:

2:打开ipv6的forwarding (sysctl -w net.ipv6.conf.all.forwarding=1  长久的修改: 编辑/etc/sysctl.conf 然后执行 sysctl -p /etc/sysctl.conf)

 

参考链接:https://access.redhat.com/solutions/3114021

https://github.com/moby/moby/issues/2174#issuecomment-289049493

 

 

 

 

 

 

 

 

 

 

 

 

Zhiming Zhang

Senior devops at Appannie
一个奔跑在运维路上的胖子
Zhiming Zhang

发表评论