Informations d'arrière-plan
J'ai un serveur avec deux interfaces réseau qui exécute Docker. Docker, comme certains outils de virtualisation, crée une interface de pont Linux appelée docker0
. Cette interface est configurée par défaut avec une IP de 172.17.42.1
et tous les conteneurs Docker communiquent avec cette interface comme passerelle et se voient attribuer des adresses IP dans la même /16
plage. Si je comprends bien, tout le trafic réseau vers / depuis les conteneurs passe par un NAT, donc sortant il semble provenir 172.17.42.1
et entrant il est envoyé 172.17.42.1
.
Ma configuration ressemble à ceci:
+------------+ /
| | |
+-------------+ Gateway 1 +-------
| | 10.1.1.1 | /
+------+-------+ +------------+ |
| eth0 | /
| 10.1.1.2 | |
| | |
| DOCKER HOST | |
| | | Internet
| docker0 | |
| (bridge) | |
| 172.17.42.1 | |
| | |
| eth1 | |
| 192.168.1.2 | \
+------+-------+ +------------+ |
| | | \
+-------------+ Gateway 2 +-------
| 192.168.1.1| |
+------------+
Le problème
Je veux acheminer tout le trafic depuis / vers n'importe quel conteneur Docker de la deuxième eth1
192.168.1.2
interface vers une passerelle par défaut de 192.168.1.1
, tout en ayant tout le trafic depuis / vers la machine hôte sortir de l' eth0
10.1.1.2
interface vers une passerelle par défaut de 10.1.1.1
. J'ai essayé une variété de choses jusqu'à présent en vain, mais la seule chose que je pense être la plus proche à corriger est d'utiliser iproute2 comme ceci:
# Create a new routing table just for docker
echo "1 docker" >> /etc/iproute2/rt_tables
# Add a rule stating any traffic from the docker0 bridge interface should use
# the newly added docker routing table
ip rule add from 172.17.42.1 table docker
# Add a route to the newly added docker routing table that dictates all traffic
# go out the 192.168.1.2 interface on eth1
ip route add default via 192.168.1.2 dev eth1 table docker
# Flush the route cache
ip route flush cache
# Restart the Docker daemon so it uses the correct network settings
# Note, I do this as I found Docker containers often won't be able
# to connect out if any changes to the network are made while it's
# running
/etc/init.d/docker restart
Lorsque j'apporte un conteneur, je ne peux plus en sortir après avoir fait cela. Je ne suis pas sûr que les interfaces de pont soient gérées de la même manière que les interfaces physiques pour ce type de routage, et je veux juste un contrôle d'intégrité ainsi que des conseils sur la façon dont je pourrais accomplir cette tâche apparemment simple.
Réponses:
Vous devrez peut-être aussi regarder plus en détail la configuration d'iptables. Docker masque tout le trafic provenant du sous-réseau de conteneur, par exemple 172.17.0.0/16, à 0.0.0.0. Si vous exécutez
iptables -L -n -t nat
, vous pouvez voir la chaîne POSTROUTING sous la table nat qui fait cela -Maintenant, vous pouvez supprimer cette règle et la remplacer par une règle qui masque tout le trafic provenant du sous-réseau des conteneurs vers l'IP de votre deuxième interface - 192.168.1.2, car c'est ce que vous désirez. La règle de suppression sera, en supposant que c'est la première règle sous la chaîne POSTROUTING -
Ensuite, vous ajoutez cette règle personnalisée -
la source
ip rule add from 172.17.0.0/16 table docker
ip route add default via 192.168.1.2 dev eth1 table docker
ip route flush cache
iptables -t nat -D POSTROUTING 1
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT --to-source 192.168.1.2
/etc/init.d/docker restart
. Ensuite, j'ai essayé d'exécuter un ping out et un traceroute à partir d'un conteneur, et je n'ai rien pu atteindre.Un ami et moi sommes tombés sur ce problème exact où nous voulions que Docker prenne en charge plusieurs demandes de service d'interfaces réseau. Nous travaillions spécifiquement avec le service AWS EC2 où nous attachions / configurions / montions également les interfaces supplémentaires. Dans ce projet , il y a plus que ce dont vous avez besoin, je vais donc essayer d'inclure uniquement ce dont vous avez besoin ici.
Tout d'abord, nous avons créé une table de routage distincte pour
eth1
:Ensuite, nous avons configuré la table mangle pour définir des marques de connexion provenant de
eth1
:Enfin, nous ajoutons cette règle pour que tous les
fwmark
s utilisent la nouvelle table que nous avons créée.La
iptables
commande ci-dessous rétablira la marque de connexion, puis autorisera la règle de routage à utiliser la table de routage appropriée.Je crois que c'est tout ce qui est nécessaire dans notre exemple plus complexe où (comme je l'ai dit) notre projet consistait à attacher / configurer / mettre en place l'
eth1
interface au moment du démarrage.Maintenant, cet exemple n'empêcherait pas les connexions de
eth0
répondre aux demandes,docker0
mais je pense que vous pouvez ajouter une règle de routage pour empêcher cela.la source
La mascarade n'est pas de 172.17.42.1 mais plutôt
Ce qui signifie que cette règle ne fonctionnera pas correctement.
Essayez plutôt
la source
ip rule add from 172.17.0.0/16 table docker
ip route add default via 192.168.1.2 dev eth1 table docker
ip route flush cache
/etc/init.d/docker restart
partir du conteneur, j'ai exécuté un traceroute et le premier saut était 10.1.1.1 alors qu'il aurait dû être 192.168.1.1