Назад | Перейти на главную страницу

Нет подключения IPv6 к контейнеру Docker за пределами хоста

У меня есть собственный контейнер IPv6, на котором запущено небольшое веб-приложение на порту 8000.

На хосте Docker я могу получить доступ к веб-сервису, используя глобальный IP-адрес, но получаю отказ в соединении при подключении с другого хоста. Однако контейнер может быть отправлен с другого хоста.

Сервис в контейнере работает

# curl "http://[2a01:4f8:10a:2cc5:0:242:ac11:2]:8000"
I'm b6032b33bc12

Однако при запуске с другого хоста:

{2.1.5p273} curl "http://[2a01:4f8:10a:2cc5:0:242:ac11:2]:8000"
curl: (7) Failed to connect to 2a01:4f8:10a:2cc5:0:242:ac11:2 port 8000: Connection refused

Тем не менее, адрес ipv6 доступен для проверки связи:

{2.1.5p273} ping6 2a01:4f8:10a:2cc5:0:242:ac11:2
PING 2a01:4f8:10a:2cc5:0:242:ac11:2(2a01:4f8:10a:2cc5:0:242:ac11:2) 56 data bytes
64 bytes from 2a01:4f8:10a:2cc5:0:242:ac11:2: icmp_seq=1 ttl=60 time=0.385 ms
64 bytes from 2a01:4f8:10a:2cc5:0:242:ac11:2: icmp_seq=2 ttl=60 time=0.452 ms

Что я пропустил?

Еще несколько подробностей о моем окружении:

# docker -
Docker version 17.03.1-ce, build c6d412e

Демон использует следующие аргументы для включения ipv6:

--experimental=true --ipv6 --fixed-cidr-v6=2a01:4f8:10a:2cc5::2/64

У хоста есть маршрутизированный ipv6 /64 подсети, которой назначен один IP-адрес eth0, а оставшаяся подсеть на docker0.

# ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:c8:f8:5c:7b
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::1/64 Scope:Link
      inet6 addr: fe80::42:c8ff:fef8:5c7b/64 Scope:Link
      inet6 addr: 2a01:4f8:10a:2cc5::1/64 Scope:Global
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:129 errors:0 dropped:0 overruns:0 frame:0
      TX packets:121 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0
      RX bytes:9536 (9.3 KiB)  TX bytes:11130 (10.8 KiB)

eth0      Link encap:Ethernet  HWaddr 90:1b:0e:c4:3d:a1
      inet addr:88.99.148.135  Bcast:88.99.148.191  Mask:255.255.255.192
      inet6 addr: fe80::921b:eff:fec4:3da1/64 Scope:Link
      inet6 addr: 2a01:4f8:10a:2cc5::2/128 Scope:Global
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:107917 errors:0 dropped:0 overruns:0 frame:0
      TX packets:25223 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000
      RX bytes:143498170 (136.8 MiB)  TX bytes:2953043 (2.8 MiB)
      Interrupt:16 Memory:f7000000-f7020000

Контейнер имеет глобальный ipv6

docker exec b6032b33bc12 ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
      inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
      inet6 addr: 2a01:4f8:10a:2cc5:0:242:ac11:2/64 Scope:Global

Маршрутизация для ipv6 существует и, похоже, работает:

# ip -6 route
2a01:4f8:10a:2cc5::2 dev eth0  proto kernel  metric 256
2a01:4f8:10a:2cc5::/64 dev docker0  proto kernel  metric 256
2a01:4f8:10a:2cc5::/64 dev docker0  metric 1024
fe80::/64 dev eth0  proto kernel  metric 256
fe80::/64 dev docker0  proto kernel  metric 256
fe80::/64 dev veth0fbfa39  proto kernel  metric 256
default via fe80::1 dev eth0  metric 1024

Хост имеет исходящее соединение:

# ping6 google.com
PING google.com(fra16s20-in-x0e.1e100.net) 56 data bytes
64 bytes from fra16s20-in-x0e.1e100.net: icmp_seq=1 ttl=56 time=5.08 ms

Как и контейнер

# docker exec b6032b33bc12 ping6 google.com
PING google.com(fra16s20-in-x0e.1e100.net) 56 data bytes
64 bytes from fra16s20-in-x0e.1e100.net: icmp_seq=1 ttl=55 time=5.00 ms
64 bytes from fra16s20-in-x0e.1e100.net: icmp_seq=2 ttl=55 time=5.00 ms

Я подозреваю, что есть проблема с iptables:

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-ISOLATION  all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate     RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
Chain DOCKER (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.17.0.2           tcp dpt:8000
Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

И эквивалент ipv6:

# ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Просматривая всю вашу конфигурацию, я не вижу в ней ничего плохого.

Все, что я использовал от Hetzner, идет только с префиксом ссылки и без префикса маршрутизации. Но я попробовал mtr с машины вне сети Hetzner, и результат выглядит как 2a01:4f8:10a:2cc5::/64 действительно маршрутизируемый префикс.

Назначение одного адреса из вашего маршрутизируемого префикса на вашем eth0 немного необычно. Но поскольку вы назначили его как /128 это все еще действующая конфигурация. И если на вашем сервере есть только маршрутизируемый префикс и нет префикса ссылки, то присвоение /128 в этом смысле разумная конфигурация.

Поскольку я не смог найти никаких проблем в вашей конфигурации, я вместо этого попытался воспроизвести проблему со своей машины, но не смог.

$ curl "http://[2a01:4f8:10a:2cc5:0:242:ac11:2]:8000"
I'm b6032b33bc12

Это приводит меня к выводу, что проблема, скорее всего, кроется в машине, на которой вы запустили этот curl команда (или в сети, к которой она подключена).

Поскольку вы ничего не рассказали нам об этой машине, я не могу более конкретно сказать, в чем проблема. Вы можете попробовать сравнить вывод этих двух команд:

traceroute 2a01:4f8:10a:2cc5:0:242:ac11:2
traceroute -p 8000 2a01:4f8:10a:2cc5:0:242:ac11:2

Здесь я использую traceroute пакет в Ubuntu 16.04. Другой traceroute версии могут нуждаться в разных аргументах.