Depuis Docker 1.10 (et libnetwork update), nous pouvons attribuer manuellement une adresse IP à un conteneur situé dans un réseau défini par l'utilisateur, et c'est cool!
Je souhaite attribuer une adresse IP à un conteneur sur mon réseau local (comme nous pouvons le faire avec des machines virtuelles en mode "pont"). Mon réseau local est 192.168.1.0/24, tous mes ordinateurs ont une adresse IP. Et je veux que mes conteneurs aient des IP dans cette plage, afin de pouvoir les atteindre de n’importe où sur mon LAN (sans NAT/PAT/etc ...).
Je lis évidemment le blog post de Jessie Frazelle et beaucoup d'autres post ici et partout comme:
et tellement plus, mais rien n'est sorti; mes conteneurs ont toujours des adresses IP "à l'intérieur" de mon hôte Docker et ne sont pas accessibles pour les autres ordinateurs de mon réseau local.
En lisant le billet de blog de Jessie Frazelle, je me suis dit (puisqu'elle utilise l'IP publique) que nous pouvons faire ce que je veux faire.
Edit: En effet, si je fais quelque chose comme:
network create --subnet 192.168.1.0/24 --gateway 192.168.1.1 homenet
docker run --rm -it --net homenet --ip 192.168.1.100 nginx
La nouvelle interface sur le docker Host (br- [a-z0-9] +) prend l'adresse IP '--gateway', qui est celle de mon routeur. Et la même adresse IP sur deux ordinateurs du réseau ... BOOM
Merci d'avance.
EDIT: Cette solution est maintenant inutile. Depuis la version 1.12, Docker fournit deux pilotes de réseau: macvlan et ipvlan. Ils permettent d'attribuer une adresse IP statique à partir du réseau local. Voir le réponse ci-dessous .
Après avoir recherché personnes ayant le même problème , nous sommes passés à une solution de contournement:
Nous voulons avoir des conteneurs avec ip dans le réseau 192.168.1.0/24 (comme des ordinateurs) sans NAT/PAT/traduction/transfert de port/etc ...
En faisant ceci:
network create --subnet 192.168.1.0/24 --gateway 192.168.1.1 homenet
nous pouvons donner aux conteneurs l'adresse IP que nous voulons, mais le pont créé par docker (br-[a-z0-9]+
) aura l'IP 192.168.1.1, qui est notre routeur.
Utilisez le paramètre DefaultGatewayIPv4
:
docker network create --subnet 192.168.1.0/24 --aux-address "DefaultGatewayIPv4=192.168.1.1" homenet
Par défaut, Docker donnera à l’interface de pont (br-[a-z0-9]+
) la première adresse IP déjà prise par une autre machine. La solution consiste à utiliser le paramètre --gateway
pour indiquer au menu fixe d'affecter une adresse IP arbitraire (disponible):
docker network create --subnet 192.168.1.0/24 --aux-address "DefaultGatewayIPv4=192.168.1.1" --gateway=192.168.1.200 homenet
Nous pouvons spécifier le nom du pont en ajoutant -o com.docker.network.bridge.name=br-home-net
à la commande précédente.
Nous avons maintenant un pont (br-[a-z0-9]+
) créé par Docker. Nous devons faire le lien avec une interface physique (dans mon cas, je dois utiliser une carte réseau, donc j'utilise eth1 pour cela):
brctl addif br-home-net eth1
Nous pouvons maintenant supprimer l'adresse IP du pont, puisque nous n'en avons pas besoin:
ip a del 192.168.1.200/24 dev br-home-net
L'IP 192.168.1.200
peut être utilisé comme pont sur plusieurs hôtes de menu fixe, car nous ne l'utilisons pas et nous le supprimons.
Docker prend désormais en charge les pilotes de réseau Macvlan et IPvlan. La documentation de Docker pour les deux pilotes réseau peut être trouvée ici .
Avec les deux pilotes, vous pouvez implémenter le scénario souhaité (configurer un conteneur pour qu'il se comporte comme une machine virtuelle en mode pont):
Macvlan: permet à une seule interface réseau physique (appareil principal) d'avoir un nombre arbitraire d'appareils esclaves, chacun avec ses propres adresses MAC.
Requiert le noyau Linux v3.9–3.19 ou 4.0+.
IPvlan: vous permet de créer un nombre arbitraire de périphériques esclaves pour votre périphérique maître, qui partagent tous la même adresse MAC.
Requiert le noyau Linux v4.2 + (la prise en charge des noyaux précédents existe, mais elle est boguée).
Voir le kernel.org HOWTO IPVLAN Driver pour plus d'informations.
La connectivité du conteneur est obtenue en plaçant l'un des périphériques esclaves dans l'espace de noms réseau du conteneur à configurer. Les périphériques maîtres restent sur le système d'exploitation hôte (espace de noms par défaut).
En règle générale, vous devez utiliser le pilote IPvlan si l'hôte Linux connecté au commutateur/routeur externe a une stratégie configurée qui n'autorise qu'un seul MAC par port. C'est souvent le cas dans les environnements VMWare ESXi!
Une autre chose importante à retenir (Macvlan et IPvlan): Le trafic vers et depuis le périphérique maître ne peut pas être envoyé vers et depuis des périphériques esclaves. Si vous devez activer la communication maître à esclave, voir la section "Communication avec l'hôte (default-ns)} _" du document "IPVLAN - Le début" publié par l'un des auteurs d'IPvlan (Mahesh Bandewar).
Utilisez le pilote officiel de Docker:
À partir de Docker v1.12.0-rc2 , le nouveau pilote MACVLAN est désormais disponible dans une version officielle de Docker:
- Le pilote MacVlan n’est plus expérimental # 23524
Ces nouveaux pilotes ont été bien documentés par le ou les auteurs, avec des exemples d'utilisation }.
À la fin de la journée, il devrait fournir des fonctionnalités similaires, être plus facile à configurer et avec moins de bugs/autres défauts.
Voir les conteneurs sur l'hôte Docker:
Seul inconvénient avec le nouveau pilote officiel macvlan est que la machine hôte de docker ne peut pas voir/communiquer avec ses propres conteneurs. Ce qui pourrait être souhaitable ou non, selon votre situation spécifique.
Ce problème peut être résolu si vous avez plus de 1 NIC sur votre ordinateur hôte docker. Et les deux cartes réseau sont connectées à votre réseau local. Ensuite, vous pouvez soit A) dédier l’un des deux codes de votre hôte docker à un docker exclusivement. Et utilisez le dernier nic pour que l'hôte puisse accéder au réseau local.
Ou B) en ajoutant des itinéraires spécifiques aux seuls conteneurs auxquels vous devez accéder via la 2ème carte réseau. Par exemple:
Sudo route add -Host $container_ip gw $lan_router_ip $if_device_nic2
La méthode A) est utile si vous souhaitez accéder à tous vos conteneurs à partir de l'hôte de menu fixe et si vous avez plusieurs liens câblés.
La méthode Wheras B) est utile si vous n’avez besoin que de l’accès à quelques conteneurs spécifiques à partir de l'hôte de menu fixe. Ou si votre deuxième NIC est une carte wifi et serait beaucoup plus lente pour gérer tout votre trafic LAN. Par exemple sur un ordinateur portable.
Installation:
Si vous ne pouvez pas voir la version préliminaire -rc2
candidate sur Ubuntu 16.04, ajoutez ou modifiez temporairement cette ligne dans votre fichier /etc/apt/sources.list pour indiquer:
deb https://apt.dockerproject.org/repo ubuntu-xenial testing
au lieu de main
(qui est des versions stables).
Je n'ai plus recommandé cette solution. Donc, ça a été enlevé. C'était using bridge driver and brctrl .
Il y a un meilleur pilote officiel maintenant. Voir autre réponse sur cette page: https://stackoverflow.com/a/36470828/287510
Voici un exemple d'utilisation de macvlan. Il démarre un serveur Web à l’adresse http://10.0.2.1/ .
Ces commandes et le fichier Docker Compose fonctionnent sur QNAP et la station de conteneur de QNAP. Notez que l'interface réseau de QNAP est qvs0
.
Le blog " Utilisation des réseaux Docker macvlan "[1][2] par Lars Kellogg-Stedman explique la signification des commandes.
docker network create -d macvlan -o parent=qvs0 --subnet 10.0.0.0/8 --gateway 10.0.0.1 --ip-range 10.0.2.0/24 --aux-address "Host=10.0.2.254" macvlan0
ip link del macvlan0-shim link qvs0 type macvlan mode bridge
ip link add macvlan0-shim link qvs0 type macvlan mode bridge
ip addr add 10.0.2.254/32 dev macvlan0-shim
ip link set macvlan0-shim up
ip route add 10.0.2.0/24 dev macvlan0-shim
docker run --network="macvlan0" --ip=10.0.2.1 -p 80:80 nginx
Utilisez la version 2 car la version 3 ne prend pas en charge les autres configurations réseau, telles que gateway
, ip_range
et aux_address
.
version: "2.3"
services:
HTTPd:
image: nginx:latest
ports:
- "80:80/tcp"
- "80:80/udp"
networks:
macvlan0:
ipv4_address: "10.0.2.1"
networks:
macvlan0:
driver: macvlan
driver_opts:
parent: qvs0
ipam:
config:
- subnet: "10.0.0.0/8"
gateway: "10.0.0.1"
ip_range: "10.0.2.0/24"
aux_address: "Host=10.0.2.254"