Mein Ziel ist es, eine routingfähige öffentliche IPv6-Adresse für jeden meiner Docker-Container zu haben. Ich möchte über das IPv6-Protokoll eine Verbindung zu und aus meinen Containern herstellen können.
Ich verwende Linode und habe einen öffentlichen IPv6-Pool erhalten:
2600:3c01:e000:00e2:: / 64 routed to 2600:3c01::f03c:91ff:feae:d7d7
Diese "geroutete" Adresse wurde von dhcp automatisch konfiguriert:
# ip -6 addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2600:3c01::f03c:91ff:feae:d7d7/64 scope global mngtmpaddr dynamic
valid_lft 2591987sec preferred_lft 604787sec
inet6 fe80::f03c:91ff:feae:d7d7/64 scope link
valid_lft forever preferred_lft forever
Ich habe einen AAAA-Datensatz eingerichtet ipv6.daaku.org
, um die Arbeit zu vereinfachen:
# nslookup -q=AAAA ipv6.daaku.org
ipv6.daaku.org has AAAA address 2600:3c01:e000:e2::1
Zum Testen habe ich diese Adresse manuell zugewiesen:
# ip -6 addr add 2600:3c01:e000:00e2::1/64 dev eth0
# ip -6 addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2600:3c01:e000:e2::1/64 scope global
valid_lft forever preferred_lft forever
inet6 2600:3c01::f03c:91ff:feae:d7d7/64 scope global mngtmpaddr dynamic
valid_lft 2591984sec preferred_lft 604784sec
inet6 fe80::f03c:91ff:feae:d7d7/64 scope link
valid_lft forever preferred_lft forever
Ich kann dies jetzt von meinem IPv6-fähigen Heimnetzwerk aus anpingen:
# ping6 -c3 ipv6.daaku.org
PING6(56=40+8+8 bytes) 2601:9:400:12ab:1db7:a353:a7b4:c192 --> 2600:3c01:e000:e2::1
16 bytes from 2600:3c01:e000:e2::1, icmp_seq=0 hlim=54 time=16.855 ms
16 bytes from 2600:3c01:e000:e2::1, icmp_seq=1 hlim=54 time=19.506 ms
16 bytes from 2600:3c01:e000:e2::1, icmp_seq=2 hlim=54 time=17.467 ms
--- ipv6.daaku.org ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 16.855/17.943/19.506/1.133 ms
Ich habe die Adresse entfernt, weil ich sie nur im Container haben möchte, und bin zum ursprünglichen Zustand zurückgekehrt:
# ip -6 addr del 2600:3c01:e000:00e2::1/64 dev eth0
# ip -6 addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2600:3c01::f03c:91ff:feae:d7d7/64 scope global mngtmpaddr dynamic
valid_lft 2591987sec preferred_lft 604787sec
inet6 fe80::f03c:91ff:feae:d7d7/64 scope link
valid_lft forever preferred_lft forever
Ich habe einen Docker-Container ohne Netzwerk in einem anderen Terminal gestartet:
# docker run -it --rm --net=none debian bash
root@b96ea38f03b3:/#
Zur Vereinfachung der Verwendung steckt es in einer Variablen fest:
CONTAINER_PID=$(docker inspect -f '{{.State.Pid}}' b96ea38f03b3)
Richten Sie die Netze für diese PID ein:
# mkdir -p /run/netns
# ln -s /proc/$CONTAINER_PID/ns/net /run/netns/$CONTAINER_PID
Erstellt ein neues Gerät, weist ihm die IP zu:
# ip link add container0 link eth0 type macvlan
# ip link set container0 netns $CONTAINER_PID
# ip netns exec $CONTAINER_PID ip link set dev container0 name eth0
# ip netns exec $CONTAINER_PID ip link set eth0 up
# ip netns exec $CONTAINER_PID ip addr add 2600:3c01:e000:00e2::1/64 dev eth0
Zurück im anderen Terminal, wo ich den Container gestartet habe:
# ip -6 addr show eth0
22: eth0@gre0: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500
inet6 2600:3c01::a083:1eff:fea5:5ad2/64 scope global dynamic
valid_lft 2591979sec preferred_lft 604779sec
inet6 2600:3c01:e000:e2::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::a083:1eff:fea5:5ad2/64 scope link
valid_lft forever preferred_lft forever
# ip -6 route
2600:3c01::/64 dev eth0 proto kernel metric 256 expires 2591976sec
2600:3c01:e000:e2::/64 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
default via fe80::1 dev eth0 proto ra metric 1024 expires 67sec
Dies funktioniert nicht und ich kann weder eine Verbindung zum Container herstellen ( ping6 ipv6.google.com
als Test verwenden) noch den Container über das Internet von meinem Heimnetzwerk aus ( ping6 ipv6.daaku.org
als Test verwenden) anpingen.
Update: Ich habe es geschafft, ausgehendes IPv6 auf folgende Weise zum Laufen zu bringen :
ip -6 addr add 2600:3c01:e000:00e2::1111:1/112 dev docker0 &&
ip6tables -P FORWARD ACCEPT &&
sysctl -w net.ipv6.conf.all.forwarding=1 &&
sysctl -w net.ipv6.conf.all.proxy_ndp=1
CONTAINER_PID=$(docker inspect -f '{{.State.Pid}}' 4fd3b05a04bb)
mkdir -p /run/netns &&
ln -s /proc/$CONTAINER_PID/ns/net /run/netns/$CONTAINER_PID &&
ip netns exec $CONTAINER_PID ip -6 addr add 2600:3c01:e000:00e2::1111:20/112 dev eth0 &&
ip netns exec $CONTAINER_PID ip -6 route add default via 2600:3c01:e000:00e2::1111:1 dev eth0
IPv6-Routen auf dem Host:
# ip -6 r
2600:3c01::/64 dev eth0 proto kernel metric 256 expires 2582567sec
2600:3c01:e000:e2::1111:0/112 dev docker0 proto kernel metric 256
2600:3c01:e000:e2::/64 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
fe80::/64 dev docker0 proto kernel metric 256
fe80::/64 dev veth1775864 proto kernel metric 256
fe80::/64 dev veth102096c proto kernel metric 256
fe80::/64 dev vethdf3a55b proto kernel metric 256
IPv6-Routen im Container:
# ip -6 r
2600:3c01:e000:e2::1111:0/112 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
default via 2600:3c01:e000:e2::1111:1 dev eth0 metric 1024
Ich kann es immer noch nicht von meinem Heimcomputer aus anpingen.
quelle
Antworten:
Ich denke, Ihr Problem hängt mit dem Routing zusammen. Das Problem ist, dass Ihnen eine Wohnung zugewiesen
/64
wurde, Sie sich jedoch für ein Sub-Subnetz von a entschieden haben/112
. Dies ist für ausgehenden Datenverkehr in Ordnung, da Ihr Container-Host alle einzelnen Sub-Subnetze kennt. Wenn Ihr ISP jedoch die Rückgabepakete verarbeitet, weiß er nicht, dass Sie die Unterabschnitte abgetrennt haben2600:3c01:e000:e2::1111:0/112
und dass diese über weitergeleitet werden sollten2600:3c01:e000:00e2::1
. Sie erwarten nur, dass das Ganze2600:3c01:e000:00e2::/64
dort sitzt, direkt verbunden und über Unicast erreichbar ist.Das Problem ist, dass es keinen Mechanismus gibt , der Ihrem ISP mitteilt, dass Sie sich entschieden haben, mit dem Sub-Subnetz zu beginnen (eigentlich ist das eine Lüge, es gibt eine Reihe von Möglichkeiten - aber alle erfordern die Zusammenarbeit Ihres ISP). Ihre einfachste Wette ist wahrscheinlich zu stoppen Routing des Verkehrs auf die Behälter, und starten Sie überbrücken es.
Ich kann dir nicht genau sagen, wie das geht. Ich habe es versucht, und mehrere Leute haben freundlich darauf hingewiesen, dass ich falsch lag. Hoffentlich kann jemand das klären. Das Problem bleibt jedoch, dass Sie Ihre Container mit Ihrer Next-Hop-Route und umgekehrt verbinden müssen, anstatt sie weiterzuleiten.
quelle
docker0
der Welt und umgekehrt passiert , und ich schlage vor, dass dieser Hop überbrückt (und nicht geroutet) werden sollte. Es mag der richtige Weg sein, dies zu tun, indem maneth0
diedocker0
Brücke erweitert - wie gesagt, ich bin kein Experte für Containerisierung -, aber ich bin mir ziemlich klar darüber, was das OP tun muss, selbst wenn ich kann Ich weiß nicht genau, wie er es machen soll.In Docker 1.0 gibt es zwei Optionen zum Aktivieren der IPv6-Konnektivität für Docker-Container. Ich musste den lxc-Treiber anstelle von libcontainer verwenden, damit beide Methoden funktionieren. Möglicherweise können Sie RADVD verwenden. Ich habe es nicht versucht.
1) Lassen Sie den Provider die / 64 an Ihren Docker-Host weiterleiten . Dies ist die einfachste Option. Aktivieren Sie die IPv6-Weiterleitung und weisen Sie Docker0 / 64 zu. Sie müssen dieses Netzwerk nicht in kleinere Netzwerke aufteilen (z. B. / 112), es sei denn, Sie haben mehrere Docker-Bridges oder mehrere Docker-Hosts.
Diese Methode wird in Andreas Neuhaus 'Blogbeitrag "IPv6 in Docker Containers" ausführlich behandelt. Siehe http://zargony.com/2013/10/13/ipv6-in-docker-containers .
Beachten Sie, dass nur sehr wenige IPv6-fähige IaaS-Anbieter a / 64 an eine VM weiterleiten. Die zweite Methode überwindet diese Einschränkung auf halbkludige Weise.
2) Verwenden Sie eine Teilmenge von / 64 von der LAN-Schnittstelle auf der Docker-Bridge. - Für diese Methode ist kein / 64 erforderlich, das an Ihren Docker-Host weitergeleitet wird. Ein kleineres Netzwerk im / 64 (z. B. / 112) im LAN ist Docker0 zugewiesen. NDP ist so konfiguriert, dass NDP von der Docker-Bridge zu Ihrer LAN-Schnittstelle (wahrscheinlich eth0) übertragen wird.
Ich habe eine detaillierte Beschreibung dieser Methode unter http://jeffloughridge.wordpress.com/2014/07/22/ipv6-in-docker-containers-on-digitalocean/ geschrieben .
Ich habe keine Docker-Versionen größer als 1.0 verwendet. Es ist möglich, dass sich die Dinge in neueren Versionen geändert haben.
quelle
Per RFC befinden sich alle Adressen in einem Subnetz innerhalb von / 64. Zuweisungen in diesem Bereich verwenden eine oder mehrere IPv6-Adressen.
Sie denken, IPv6 ist wie IPv4, aber größere Adressen. Ich bin hier, um Ihnen zu sagen, wenn Sie Ihre Systeme so entwerfen, Ihre Einrichtungskosten erhöhen, Wartung Sicherheit ist!
quelle
/64
?