У меня есть собственный контейнер 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
версии могут нуждаться в разных аргументах.