ポート8000で小さなWebアプリを実行しているIPv6ネイティブコンテナがあります。
Dockerホストでは、グローバルIPを使用してWebサービスにアクセスできますが、別のホストから接続すると「接続が拒否されました」というメッセージが表示されます。ただし、コンテナは他のホストからpingを実行できます。
コンテナ内のサービスは機能します
# 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アドレスはping可能です。
{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
サブネットがあり、1つの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から使用したものはすべて、リンクプレフィックスのみが付属し、ルーティングプレフィックスは付属していません。しかし、Hetznerのネットワーク外のマシンからmtr
を試したところ、出力は2a01:4f8:10a:2cc5::/64
が実際にはルーティングされたプレフィックスであるように見えます。
eth0
のルーティングされたプレフィックスから単一のアドレスを割り当てるのは少し珍しいことです。しかし、それを/128
として割り当てたので、それはまだ有効な構成です。また、サーバーにルーテッドプレフィックスのみがあり、リンクプレフィックスがない場合は、その方法で/128
を割り当てるのが賢明な構成です。
構成に問題が見つからなかったため、代わりに自分のマシンから問題を再現しようとしましたが、見つかりませんでした。
$ curl "http://[2a01:4f8:10a:2cc5:0:242:ac11:2]:8000"
I'm b6032b33bc12
それは、問題がそのcurl
コマンドを実行したマシン(またはそれが接続されているネットワーク)にある可能性が高いという結論につながります。
そのマシンについては何も言わなかったので、具体的に何が問題なのかは言えません。試すことができるのは、次の2つのコマンドの出力を比較することです。
traceroute 2a01:4f8:10a:2cc5:0:242:ac11:2
traceroute -p 8000 2a01:4f8:10a:2cc5:0:242:ac11:2
ここでは、Ubuntu16.04でtraceroute
パッケージを使用しています。他のtraceroute
バージョンでは、異なる引数が必要になる場合があります。