IPv6 在 Docker 群中不起作用?

Sit*_*_NO 7 ipv6 docker docker-swarm

我有一台运行 IPv4 和 IPv6(双栈)的 Ubuntu 服务器 16.04 LTS。该服务器也在运行 Docker。但是,每当我尝试访问群中的容器时都会遇到问题,但只能通过 IPv6。这是我的步骤:

我创建了一个运行 gnuicron 网络服务器的简单应用程序:

def app(environ, start_response):
    """Simplest possible application object"""
    data = b'Hello, World!\n'
    status = '200 OK'
    response_headers = [
        ('Content-type', 'text/plain'),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
return iter([data])
Run Code Online (Sandbox Code Playgroud)

gunicorn -w 4 -b [::]:5678 myapp:app在我的服务器上运行它,并通过在我的网络中的双栈客户端上运行它来验证它是否有效:

$ curl --connect-timeout 15 http://[2001:db8:db0::5]:5678
Hello, World!
$ curl --connect-timeout 15 http://192.168.10.5:5678
Hello, World!
Run Code Online (Sandbox Code Playgroud)

我写了一个Dockerfile并运行它:

docker build -t docker_ipv6_test .
docker run --rm --init -p 5678:5678 docker_ipv6_test
Run Code Online (Sandbox Code Playgroud)

我运行与 about 相同的验证,它按预期工作。然后我写了一个docker-compose.yml:

version: '3'
services:
  ipv6_test:
    image: docker_ipv6_test:latest
    deploy:
      replicas: 1
      restart_policy: 
        condition: on-failure
      ports:
        - '5678:5678/tcp'
Run Code Online (Sandbox Code Playgroud)

并运行它:

docker stack deploy -c docker-compose.yml ipv6_test
Run Code Online (Sandbox Code Playgroud)

然后发生这种情况:

$ curl --connect-timeout 15 http://[2001:db8:db0::5]:5678
curl: (28) Operation timed out after 0 milliseconds with 0 out of 0 bytes received
$ curl --connect-timeout 15 http://192.168.10.5:5678
Hello, World!
Run Code Online (Sandbox Code Playgroud)

但我想知道是我做错了什么,还是我遇到了错误?

我所有的代码和文件都可以在这里找到:https : //github.com/SitronNO/docker_ipv6_test

pmc*_*pmc 2

您遇到了错误并做了错误的事情。从许多 github 问题和https://docs.docker.com/compose/compose-file/#ipv4_address-ipv6_address上的评论来看,ipv6 目前无法在 swarms 中工作:

如果需要 IPv6 寻址,则必须设置 enable_ipv6 选项,并且必须使用版本 2.x Compose 文件。IPv6 选项当前不适用于集群模式。

你可能想尝试 IPv6 NAT https://github.com/robbertkl/docker-ipv6nat但这似乎也很难设置,特别是如果你没有 ipv6tables 等。

你做错的不是设置一个启用了 ipv6 的 docker swarm 范围桥接网络,或者启动启用了 ipv6 的 docker - 但考虑到当前的文档,这并不奇怪。

-我建议没有人回答这个问题,因为还没有一个好的答案。-

但一个答案是让 docker 做它最擅长的事情,让 linux 的其余部分做剩下的事情。将 docker swarm 保留为纯 ipv4 网络,并将 ipv6 流量转发到该网络。ip 表从 ipv4 转发到 ipv6 是不可能的,但可以使用socat例如:

sudo socat TCP6-LISTEN:80,,su=nobody,fork,reuseaddr TCP4:127.0.0.1:81

注意,我将 docker 端口移至侦听端口 81,因为虽然 swarm 的 docker_gwbridge 可能没有“启用”ipv6,但它仍会绑定到 ipv6:80 端口(叹气)。注意 socat 现在会将 ipv4 和 ipv6 流量转发到 ipv4 端口 80。

您可以使用sudo nohup socat ... &该命令将其置于后台。

请参阅如何以透明方式将端口从 IPv4 隧道传输到远程 IPv6 设备?等人。