让 Docker 使用 IPv4进行端口绑定

我有码头主机,里面有一个集装箱。

The docker host is binding the port on IPv6 interface only, not on IPv4.

这是输出

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:55082           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::40280                :::*                    LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
tcp6       0      0 :::40122                :::*                    LISTEN      -
tcp6       0      0 :::36378                :::*                    LISTEN      -
tcp6       0      0 :::40543                :::*                    LISTEN      -
tcp6       0      0 :::111                  :::*                    LISTEN      -

现在我在主机上有40122端口来链接容器上的22端口。

我想 SSH 到该容器,但我不能作为其唯一的 IPv6绑定

这是我的码头版本 Docker version 1.5.0, build a8a31ef

docker ps

201bde6c839a        myapp:latest   "supervisord -n"    3 weeks ago         Up 2 hours          0.0.0.0:40122->22/tcp, 0.0.0.0:40280->80/tcp, 0.0.0.0:40543->443/tcp   myapp

我用 docker run -d -P -p 40122:22跑步

netstat -tlna


tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3031          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::6379                 :::*                    LISTEN

(西班牙语)

root         1  0.0  0.8  52440 16668 ?        Ss   00:53   0:03 /usr/bin/python /usr/bin/supervisord -n
root        49  0.0  0.1  17980  3048 ?        S    01:32   0:00 bash
root        64  0.0  0.1  46632  2712 ?        S    01:32   0:00 su -l vagrant
vagrant     65  0.0  0.1  21308  3760 ?        S    01:32   0:00 -su
root       288  0.0  0.1  17980  3088 ?        S    02:01   0:00 bash
root       304  0.0  0.1  46632  2720 ?        S    02:01   0:00 su -l vagrant
vagrant    305  0.0  0.1  21304  3804 ?        S    02:01   0:00 -su
vagrant    308  0.0  3.7 429616 75840 ?        Sl+  02:01   0:05 python ./manage.py shell_plus
root       654  0.0  0.4  47596  9848 ?        S    03:12   0:01 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       655  0.0  0.3  90280  7732 ?        S    03:12   0:00 nginx: master process /usr/sbin/nginx
www-data   656  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   657  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   658  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   659  0.0  0.2  90940  4500 ?        S    03:12   0:00 nginx: worker process
root       660  0.0  0.2  61372  5332 ?        S    03:12   0:00 /usr/sbin/sshd -D
root       669  0.0  0.4  37004  8892 ?        Sl   03:12   0:01 redis-server *:6379
root       856  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       857  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       858  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       859  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
vagrant    889  0.0  0.1  18692  2508 ?        R+   04:11   0:00 ps aux
141986 次浏览

正如@daniel-t 在评论中指出的那样: Github.com/docker/docker/issues/2174只是在 netstat中显示与 IPv6的绑定,但这不是问题。正如 github 所说:

当设置代理时,Docker 请求回送地址“127.0.0.1”,Linux 意识到这是一个存在于 IPv6中的地址(作为: : 0) ,并且在两个地址上都打开(但它的正式名称是 IPv6套接字)。当你运行 netstat 时,它会看到这一点并告诉你它是一个 IPv6-但它仍然在监听 IPv4。如果您稍微调整了一下设置,您可能已经通过设置 net.ipv6.bindv6only = 1禁用了 Linux 的这个技巧。

In other words, just because you see it as IPv6 only, it is still able to communicate on IPv4 unless you have IPv6 set to only bind on IPv6 with the net.ipv6.bindv6only setting. To be clear, net.ipv6.bindv6only should be 0 - you can run sysctl net.ipv6.bindv6only to verify.

如果希望容器端口绑定到 ipv4地址上,只需:

  • 找到设置文件
    • /etc/sysconfig/docker-类似于 RedHat 上的网络
    • /etc/default/docker-network
  • 编辑网络设置
    • Add DOCKER _ NETWORK _ OPTION =-ip = xx.xx.xx.xx
    • Xx.xx.xx 是真正的 ipv4(而不是0.0.0.0)
  • 重启码头恶魔

在 Docker 1.9.1上为我工作

设置 net.ipv6.conf.all.forwarding=1将修复该问题。

这可以在实时系统上使用 sudo sysctl -w net.ipv6.conf.all.forwarding=1

默认情况下,docker 使用 AF _ INET6套接字,这些套接字可用于 IPv4和 IPv6连接。这会导致 netstat 报告监听地址的 IPv6地址。

From RedHat Https://access.redhat.com/solutions/3114021

问题解决 :

使用 docker run -it -p 80:80 --name nginx --net=host -d nginx

that's issue we face with VM some time instead of bridge network try with host that will work for you

tcp     0    0 0.0.0.0:80            0.0.0.0:*             LISTEN      -
tcp6    0    0 :::80                 :::*                  LISTEN      -

对于 CentOS 用户,

我在 CentOS7上遇到了同样的问题,将 net.ipv4.ip _ forward 设置为1就解决了这个问题。详情请参阅 Docker 网络禁用: 警告: IPv4转发禁用。网络无法工作

2021年更新:

目前,Docker 默认绑定到 IPv4和 IPv6。

如果希望显式地 “让码头使用 IPv4进行端口绑定”(例如,让它绑定到 IPv4端口) ,在 -p/--publish选项中的端口之前添加 0.0.0.0:,如下所示:

$ docker run --publish "0.0.0.0:80:80" --publish "0.0.0.0:443:443" --detach nginx

当你完成的时候,结果会是这样的:

$ docker ps


CONTAINER ID   IMAGE   COMMAND                  CREATED          STATUS         PORTS                                      NAMES
2459bd225751   nginx   "/docker-entrypoint.…"   4 seconds ago    Up 2 seconds   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   jovial_yonath

Netstat 的结果如下所示:

$ sudo netstat -tulnp


Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State    PID/Program name
tcp        0      0 0.0.0.0:443   0.0.0.0:*       LISTEN   22676/docker-proxy
tcp        0      0 0.0.0.0:80    0.0.0.0:*       LISTEN   22698/docker-proxy

当然,您可以浏览或 curl到设备,以确保它能正常工作。

如果你不添加“0.0.0.0”,它将绑定在两个 IP 版本上,并且 PORTS将读取 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp,这可能不是安全,控制台垃圾邮件或可预见性的原因所需要的。

尝试删除已创建网络的 可连接标志

Doesn't work

docker network create --attachable --driver overlay --subnet=10.0.3.0/24 --gateway=10.0.3.1 dev

It works, but listeness IPv4 ports still not seeing when you check with Sudo netstat-tulnp4

docker network create --attachable --driver overlay --subnet=10.0.3.0/24 --gateway=10.0.3.1 dev