Donner une connectivité IPv6 à ses conteneurs Docker en utilisant un bloc d'IPv6 de son opérateur

Il peut paraître étonnant qu’un service moderne comme Docker n’offre pas d’IPv6 dans les conteneurs par défaut, en particulier lorsqu’on se trouve dans un réseau avec de l’IPv6.

En fait, pour la même raison que nous avons vu dans l’article introductif, étant donné que les conteneurs se trouvent dans un réseau virtuel, ils ne peuvent pas être joignables par la box/le routeur distribuant le sous-réseau IPv6.

On observe d’ailleurs le même phénomène avec l’IPv4 : chaque conteneur dispose d’une IPv4 dans un sous-réseau distinct de celui dans lequel se trouve notre machine hôte.

Illustration d´un réseau domestique IPv4 classique

Pour que les conteneurs aient accès à Internet dans ces conditions, en IPv4 du NAT est mis en œuvre :

42sh$ iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 3 packets, 228 bytes)
 pkts bytes target     prot opt in     out     source               destination
14713  978K MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0

Comme on ne fait généralement pas de NAT sur les IPv6, rien de similaire n’est fait par Docker dans ce sens.

Docker comme routeur IPv6

Sans IPv6 dans un conteneur, il est impossible pour les conteneurs de s’adresser à d’autres services écoutant exclusivement en IPv6 sur Internet.

Afin que les programmes conteneurisés puissent se connecter à d’autres services en IPv6, il convient d’activer l’option Enable IPv6 et de définir le préfixe à utiliser au travers de l’option IPv6 Prefix.

Attention, ce n’est pas tout de définir ces options, il faut aussi que la box route correctement les paquets à destinations des conteneurs vers votre machine.

C’est pour cela que nous avons besoin de tirer parti des autres blocs d’IPv6 fournis par notre opérateur. En indiquant à la box l’adresse de notre machine hébergeant nos conteneurs, elle y routera tous les paquets à destination des conteneurs sans poser de question.

Tout ne peut donc pas se faire exclusivement sur la machine, le réseau doit aussi être configuré. Commençons d’ailleurs par cela.

Paramétrer la délégation de préfixe IPv6 sur la Freebox

La box va nous demander l’adresse (IPv6) vers laquelle elle devra router les paquets. On indique généralement une IP de lien local.

On commence donc par regarder quelle est notre IPv6 locale sur le lien sortant vers la box.

⚠️ Attention toutes les interfaces ont une adresse locale, elles commencent toutes par fe80:, elles ne sont valables que sur la carte réseau considérée. Si vous récupérez la mauvaise adresse, il ne se passera rien (cela ne cassera pas votre réseau pour autant).

Dans mon cas, c’est l’interface eth0 qui est connectée à la box :

42sh$ ip address show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether fd:54:01:98:cd:ba brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.42/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0
       valid_lft 35141sec preferred_lft 35141sec
    inet6 2a01:...:2420:24ac:f101:c280:50c2/64 scope global noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::5a43:3580:173c:395e/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Mon IP locale est donc fe80::5a43:3580:173c:395e.

C’est cette IP que je vais indiquer dans la configuration de la box.

Sur les Freebox, la fenêtre de paramétrage des préfixes supplémentaires se trouve dans « Paramètres de la Freebox », « Configuration IPv6 », sous l’onglet « Général ». C’est le cadre « Délégation de préfixe » qui va nous intéresser.

Cela ressemble à ça :

Fenêtre de paramétrage de la délégation de préfixe IPv6 de la Freebox

Laissez toujours le 1ᵉʳ champ vide, sans quoi la box ne vous proposera plus d’IPv6 sur le réseau principal.

Indiquez dans le 1ᵉʳ champ vide suivant (le deuxième a priori donc !) l’adresse locale récupérée plus tôt.

C’est tout ! Le plus dur est passé. Voyons maintenant la configuration de Docker.

Paramétrer Docker pour l’IPv6

Nous n’allons pas utiliser la plage à laquelle notre machine est connectée. Nous allons utiliser toute une plage /64, celle pour laquelle on a donné l’IP locale de notre machine à la box.

Notre délégation de préfixe correctement paramétrée sur la Freebox

Selon la capture d’écran précédente, notre fichier de configuration /etc/docker/daemon.json devrait ressembler à :

{
  "ipv6": true,
  "fixed-cidr-v6": "2a01:1234:abcd:2421::/64"
}

On relance Docker et on peut tester :

42sh$ docker run -it alpine
/ # ip address show eth0
58: eth0@if59: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:09 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.9/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2a01:1234:abcd:2421:0:242:ac11:9/64 scope global flags 02
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:9/64 scope link
       valid_lft forever preferred_lft forever

Si vous avez une IPv6 en plus de l’IPv4 habituelle, c’est que Docker est correctement configuré. Pour savoir si la configuration côté box a réussi, lançons un ping dans le conteneur :

/ # ping ping6.online.net
PING ping6.online.net (2001:bc8:1::40): 56 data bytes
64 bytes from 2001:bc8:1::40: seq=0 ttl=52 time=11.008 ms
64 bytes from 2001:bc8:1::40: seq=1 ttl=52 time=8.822 ms
^C
--- ping6.online.net ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 8.822/9.915/11.008 ms

Si le ping répond, c’est tout bon : vos conteneurs auront désormais accès à et seront accessibles en IPv6.

Autres cas d’usage

Ce billet fait partie d’une série de billets sur l’usage des plages d’IPv6 supplémentaires :