Attribuer une adresse IP statique au conteneur Docker

205

J'essaie maintenant d'attribuer une IP statique 172.17.0.1 lors du démarrage d'un conteneur Docker.

J'utilise le port 2122 comme port ssh de ce conteneur afin de laisser ce conteneur écouter le port 2122.

sudo docker run -i -t -p 2122:2122 ubuntu

Cette commande exécutera un conteneur Docker avec une IP aléatoire comme 172.17.0.5, mais je dois attribuer une IP spécifique au conteneur.

Le script shell suivant est ce que je référence à la documentation Docker dans les paramètres réseau avancés.

pid=$(sudo docker inspect -f '{{.State.Pid}}' <container_name> 2>/dev/null)
sudo rm -rf /var/run/netns/*
sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
sudo ip link add A type veth peer name B
sudo brctl addif docker0 A
sudo ip link set A up
sudo ip link set B netns $pid
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link delete eth0
sudo ip netns exec $pid ip link set dev B name eth0
sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link set eth0 up
sudo ip netns exec $pid ip addr add 172.17.0.1/16 dev eth0
sudo ip netns exec $pid ip route add default via 172.17.42.1

Ce script shell attribuera une IP statique 172.17.0.1 et un lien vers l'amende mondiale. Mais chaque fois que j'essaie de ssh vers ce conteneur à partir de mon local, cela n'a pas fonctionné. Quel est le problème que j'ai rencontré?

LarryLo
la source
Je crains qu'il n'y ait pas de réponse simple à cette question, voir github.com/docker/docker/issues/6743 et github.com/docker/docker/issues/1179 et lisez github.com/jpetazzo/pipework
user2915097
@larrylo pouvez-vous confirmer que vous avez démarré un sshd à l'intérieur du conteneur?
Bryan
5
Vous annulez tout le routage que le démon docker fait pour vous. Les conteneurs ne sont pas des machines virtuelles.
user2105103
Oui, je confirme que je peux démarrer sshd à l'intérieur du conteneur
LarryLo

Réponses:

291

Facile avec Docker version 1.10.1, build 9e83765.

Vous devez d'abord créer votre propre réseau docker (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

que d'exécuter simplement l'image (je prendrai ubuntu comme exemple)

docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash

puis dans la coque ubuntu

ip addr

De plus, vous pouvez utiliser

  • --hostname pour spécifier un nom d'hôte
  • --add-host pour ajouter plus d'entrées à / etc / hosts

Documents (et pourquoi vous devez créer un réseau) sur https://docs.docker.com/engine/reference/commandline/network_create/

cantSleepNow
la source
1
Excellente réponse - Il suffit d'ajouter quelques informations supplémentaires: blog.jessfraz.com/post/ips-for-all-the-things
Ole
@cantSleepNow pour une raison quelconque, j'ai juste besoin d'utiliser mon propre pont br0 créé par défaut qui est créé dans le fichier d'interface lors du démarrage du système (donc il n'est PAS créé à l'aide de la création de réseau docker), pourriez-vous me suggérer comment puis-je obtenir le même effet de - -ip paramètre (obtenir une adresse IP fixe pour un conteneur) sans créer mon pont à l'aide de docker?
Mohammed Noureldin du
@MohammedNoureldin Je ne comprends pas bien - cela ressemble aussi à une nouvelle question, je pense que vous devriez la poser comme telle.
cantSleepNow
@cantSleepNow Je veux dire que je dois corriger l'adresse IP du conteneur bien que je n'utilise PAS de pont personnalisé (donc le paramètre --ip ne peut pas être utilisé), proposez-vous un moyen pour l'obtenir?
Mohammed Noureldin du
@MohammedNoureldin Je ne suis pas sûr. Comme je l'ai dit, postez votre question sous forme de question et non de commentaire - il y a peut-être quelqu'un qui connaît la réponse.
cantSleepNow
89

Car docker-composevous pouvez utiliser ce qui suitdocker-compose.yml

version: '2'
services:
  nginx:
    image: nginx
    container_name: nginx-container
    networks:
      static-network:
        ipv4_address: 172.20.128.2
networks:
  static-network:
    ipam:
      config:
        - subnet: 172.20.0.0/16
          #docker-compose v3+ do not use ip_range
          ip_range: 172.28.5.0/24

de l'hôte, vous pouvez tester en utilisant:

docker-compose up -d
curl 172.20.128.2

Moderne docker-composene change pas souvent d'adresse IP.

Pour trouver les ips de tous les conteneurs dans votre docker-composeen une seule ligne, utilisez:

for s in `docker-compose ps -q`; do echo ip of `docker inspect -f "{{.Name}}" $s` is `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $s`; done

Si vous souhaitez automatiser, vous pouvez utiliser quelque chose comme cet exemple gist

zainengineer
la source
2
Il semble que cela ne fonctionne que dans Docker-compose v2, v3 cassé la compatibilité.
Andrzej Rehmann
4
Lors de l'utilisation de docker-compose v3 + removeip_range
Andrzej Rehmann
Je ne reçois pas l'ip_range cependant. n'est-ce pas couvert par le sous-réseau? Quoi qu'il en soit, merci! Cela a corrigé mon "Je dois rechercher à nouveau l'IP de mon conteneur mongo" - problème
Ben
1
Existe-t-il un moyen de spécifier l'adresse IP dans la version 3 de Composer?
ealeon
2
La solution fonctionne bien pour moi sans ip_range. J'utilise la version: '3.4'.
Mikhail Morfikov
24

Pas une réponse directe mais cela pourrait aider.

J'exécute la plupart de mes services dockerized liés à leurs propres IPS statiques en utilisant l'approche suivante:

  1. Je crée des alias IP pour tous les services sur l'hôte docker
  2. Ensuite, j'exécute chaque service redirigeant les ports de cette adresse IP vers le conteneur afin que chaque service ait sa propre adresse IP statique qui pourrait être utilisée par des utilisateurs externes et d'autres conteneurs.

Échantillon:

docker run --name dns --restart=always -d -p 172.16.177.20:53:53/udp dns
docker run --name registry --restart=always -d -p 172.16.177.12:80:5000 registry
docker run --name cache --restart=always -d -p 172.16.177.13:80:3142 -v /data/cache:/var/cache/apt-cacher-ng cache
docker run --name mirror --restart=always -d -p 172.16.177.19:80:80 -v /data/mirror:/usr/share/nginx/html:ro mirror
...
ISanych
la source
Merci ~ je le sais. Tout comme github.com/brandon-rhodes/fopnp/tree/m/playground do. Je vais essayer.
LarryLo
1
Ceci est une très bonne solution, je voudrais simplement attacher ce lien pour que les nouveaux utilisateurs apprennent à aliaser cyberciti.biz/faq/…
Mohammed Noureldin
Merci pour la belle solution.
RavinderSingh13
4

Cela fonctionne pour moi.

Créez un réseau avec docker network create --subnet=172.17.0.0/16 selnet

Exécuter l'image docker docker run --net selnet --ip 172.18.0.2 hub

Au début, j'ai

docker: Error response from daemon: Invalid address 172.17.0.2: It does not belong to any of this network's subnets.
ERRO[0000] error waiting for container: context canceled

Solution: augmentation du 2e quadruple de l'IP [.18. au lieu de .17.]

Nils Zenker
la source
3
Il y a une réponse similaire / identique de 2 ans plus
tôt
2

Je suis tombé sur ce problème lors de la tentative de dockerise Avahi qui doit être conscient de son adresse IP publique pour fonctionner correctement. L'attribution d'une adresse IP statique au conteneur est délicate en raison du manque de prise en charge de l'attribution d'adresses IP statiques dans Docker.

Cet article décrit la technique pour attribuer une IP statique au conteneur sur Debian :

  1. Le service Docker doit être démarré avec DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Je suppose que le br0pont est déjà configuré.

  2. Le conteneur doit être démarré avec --cap-add=NET_ADMIN --net=bridge

  3. Le conteneur intérieur pre-up ip addr flush dev eth0dans /etc/network/interfacespeut être utilisé pour ignorer l'adresse IP attribuée par Docker comme dans l'exemple suivant:


auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    pre-up ip addr flush dev eth0
    address 192.168.0.249
    netmask 255.255.255.0
    gateway 192.168.0.1
  1. Le script d'entrée du conteneur doit commencer par /etc/init.d/networking start. Le script d'entrée doit également modifier ou remplir le /etc/hostsfichier afin de supprimer les références à l'adresse IP attribuée par Docker.
Onlyjob
la source
2

Vous pouvez définir l'IP tout en l'exécutant.

docker run --cap-add=NET_ADMIN -dit imagename /bin/sh -c "/sbin/ip addr add 172.17.0.12 dev eth0; bash"

Voir mon exemple sur https://github.com/RvdGijp/mariadb-10.1-galera

Si vulgaire
la source
malheureusement, cela ajoute une adresse IP de plus, si une adresse IP a été attribuée dans le processus avant, cela se traduit par avoir deux adresses IP
davey
1

Vous pouvez accéder au service d'autres conteneurs par leur nom ( ping apacheobtiendra l'IP ou curl http://apacheaccèderait au service http) Et cela peut être une alternative à une IP statique.

Guisong He
la source
3
Dans la version docker de 1.8, cela fonctionne directement. Dans la version la plus récente, vous devez lier ces conteneurs en premier.
Guisong He