Weisen Sie dem Docker-Container eine statische IP zu


205

Ich versuche jetzt, eine statische IP 172.17.0.1 zuzuweisen, wenn ein Docker-Container gestartet wird.

Ich verwende Port 2122 als SSH-Port dieses Containers, damit dieser Container Port 2122 abhört.

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

Dieser Befehl führt einen Docker-Container mit einer zufälligen IP wie 172.17.0.5 aus, aber ich muss dem Container eine bestimmte IP zuweisen.

Das folgende Shell-Skript ist das, worauf ich in den erweiterten Netzwerkeinstellungen in der Docker-Dokumentation verweise.

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

Dieses Shell-Skript weist eine statische IP 172.17.0.1 zu und verlinkt auf die Weltstrafe. Aber wann immer ich versuche, von meinem lokalen zu diesem Container zu ssh, hat es nicht funktioniert. Was ist das Problem, das ich möglicherweise getroffen habe?


Ich fürchte, es gibt keine einfache Antwort auf diese Frage, siehe github.com/docker/docker/issues/6743 und github.com/docker/docker/issues/1179 und lesen Sie github.com/jpetazzo/pipework
user2915097

@larrylo kannst du bestätigen, dass du ein sshd im container gestartet hast?
Bryan

5
Sie machen das gesamte Routing rückgängig, das der Docker-Daemon für Sie erledigt. Container sind keine VMs.
user2105103

Ja, ich bestätige, dass ich sshd im Container starten kann
LarryLo

Antworten:


291

Einfach mit Docker Version 1.10.1, Build 9e83765.

Zuerst müssen Sie Ihr eigenes Docker-Netzwerk erstellen (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

als einfach das Bild ausführen (ich nehme Ubuntu als Beispiel)

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

dann in Ubuntu Shell

ip addr

Zusätzlich könnten Sie verwenden

  • --hostname um einen Hostnamen anzugeben
  • --add-host um weitere Einträge zu / etc / hosts hinzuzufügen

Dokumente (und warum Sie ein Netzwerk erstellen müssen) unter https://docs.docker.com/engine/reference/commandline/network_create/


1
Tolle Antwort - Fügen Sie
Ole

@cantSleepNow Aus irgendeinem Grund muss ich nur meine standardmäßig erstellte Bridge br0 verwenden, die während des Systemstarts in der Schnittstellendatei erstellt wird (also NICHT mit Docker Network Create erstellt wird). Können Sie mir vorschlagen, wie ich den gleichen Effekt erzielen kann wie - -ip Parameter (feste IP-Adresse für einen Container erhalten) ohne meine Bridge mit Docker zu erstellen?
Mohammed Noureldin

@MohammedNoureldin Ich verstehe nicht ganz - klingt auch nach einer neuen Frage, ich denke, Sie sollten es als solche stellen.
cantSleepNow

@cantSleepNow Ich meine, ich muss die IP-Adresse des Containers korrigieren, obwohl ich KEINE benutzerdefinierte Bridge verwende (daher kann der Parameter --ip nicht verwendet werden). Schlagen Sie eine Möglichkeit vor, dies zu ermitteln?
Mohammed Noureldin

@ MohammedNoureldin Ich bin nicht sicher. Wie gesagt, poste deine Frage als Frage und nicht als Kommentar - vielleicht gibt es jemanden, der die Antwort kennt.
cantSleepNow

89

Für docker-composeSie können folgende verwendendocker-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

Vom Host aus können Sie Folgendes testen:

docker-compose up -d
curl 172.20.128.2

Modern docker-composeändert die IP-Adresse nicht so häufig.

Um ips aller Container in Ihrem docker-composein einer einzigen Zeile zu finden, verwenden Sie:

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

Wenn Sie automatisieren möchten, können Sie so etwas wie dieses Beispiel verwenden


2
Sieht so aus, als würde dies nur in Docker-Compose v2 funktionieren, v3 hat die Kompatibilität unterbrochen.
Andrzej Rehmann

4
Bei Verwendung von Docker-Compose v3 + entfernenip_range
Andrzej Rehmann

Ich bekomme den ip_range allerdings nicht. Wird das nicht vom Subnetz abgedeckt? Trotzdem danke! Das hat mein Problem "Ich muss die IP meines Mongo-Containers noch einmal nachschlagen" behoben
Ben

1
Gibt es eine Möglichkeit, die IP-Adresse in Compose Version 3 anzugeben?
ealeon

2
Die Lösung funktioniert gut für mich ohne ip_range. Ich benutze Version: '3.4'.
Mikhail Morfikov

24

Keine direkte Antwort, aber es könnte helfen.

Ich führe die meisten meiner Docker-Dienste, die an eigene statische IPs gebunden sind, mit dem folgenden Ansatz aus:

  1. Ich erstelle IP-Aliase für alle Dienste auf dem Docker-Host
  2. Dann führe ich jeden Dienst aus, der Ports von dieser IP in den Container umleitet, sodass jeder Dienst eine eigene statische IP hat, die von externen Benutzern und anderen Containern verwendet werden kann.

Stichprobe:

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
...

Danke ~ Ich weiß das. Genau wie bei github.com/brandon-rhodes/fopnp/tree/m/playground . Ich werde es versuchen.
LarryLo

1
Dies ist eine sehr gute Lösung. Ich würde diesen Link nur anhängen, damit die neuen Benutzer mehr über das Aliasing von cyberciti.biz/faq/…
Mohammed Noureldin

Vielen Dank für die schöne Lösung.
RavinderSingh13

4

Das funktioniert bei mir.

Erstellen Sie ein Netzwerk mit docker network create --subnet=172.17.0.0/16 selnet

Führen Sie das Docker-Image aus docker run --net selnet --ip 172.18.0.2 hub

Zuerst habe ich bekommen

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

Lösung: Das 2. Vierfache der IP wurde erhöht [.18. statt .17.]


3
Es gibt eine 2 Jahre ältere ähnliche / identische Antwort an anderer Stelle auf dieser Seite: stackoverflow.com/a/35359185/694469
KajMagnus

2

Ich bin auf dieses Problem gestoßen, als ich versucht habe, Avahi anzudocken , das sich seiner öffentlichen IP bewusst sein muss, um ordnungsgemäß zu funktionieren. Das Zuweisen einer statischen IP-Adresse zum Container ist schwierig, da die statische IP-Zuweisung in Docker nicht unterstützt wird.

Dieser Artikel beschreibt die Technik, wie dem Container unter Debian eine statische IP zugewiesen wird :

  1. Der Docker-Dienst sollte mit gestartet werden DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Ich gehe davon aus, dass die br0Brücke bereits konfiguriert ist.

  2. Container sollte mit gestartet werden --cap-add=NET_ADMIN --net=bridge

  3. Der interne Container pre-up ip addr flush dev eth0in /etc/network/interfaceskann verwendet werden, um die von Docker zugewiesene IP-Adresse wie im folgenden Beispiel zu verwerfen:


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. Das Eingabeskript des Containers sollte mit beginnen /etc/init.d/networking start. Außerdem muss das Eingabeskript die /etc/hostsDatei bearbeiten oder füllen , um Verweise auf die vom Docker zugewiesene IP zu entfernen.


1

Sie können über ihren Namen auf den Dienst anderer Container zugreifen ( ping apacheerhalten die IP oder curl http://apachewürden auf den http-Dienst zugreifen). Dies kann eine Alternative zu einer statischen IP sein.


3
In der Docker-Version 1.8 funktioniert dies direkt. In der neueren Version müssen Sie diese Container mit der Faust verknüpfen.
Guisong He

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.