it-swarm.com.de

Wie kann ich eine statische IP-Adresse in einem Docker-Container festlegen?

Ich bin vollkommen zufrieden mit dem IP-Bereich, den der Docker mir standardmäßig gibt. 176.17.x.x, damit ich keine neue Brücke erstellen muss, möchte ich meinen Containern nur eine statische Adresse geben innerhalb dieses Bereichs, damit ich Client-Browser direkt darauf verweisen kann. Ich habe versucht mit

RUN echo "auto eth0" >> /etc/network/interfaces
RUN echo "iface eth0 inet static" >> /etc/network/interfaces
RUN echo "address 176.17.0.250" >> /etc/network/interfaces
RUN echo "netmask 255.255.0.0" >> /etc/network/interfaces
RUN ifdown eth0
RUN ifup eth0

von einem Dockerfile, und es füllte die Interface-Datei richtig, aber das Interface selbst hat sich nicht geändert. Wenn Sie ifup eth0 im Container ausführen, wird der folgende Fehler ausgegeben:

RTNETLINK antwortet: Operation nicht erlaubt Fehler beim Aufrufen von eth0

41
dlanced

Ich habe dies hier bereits beantwortet https://stackoverflow.com/a/35359185/4094678 aber ich sehe jetzt, dass diese Frage tatsächlich älter ist als die oben genannte, also kopiere ich die Antwort auch :

Einfach mit Docker Version 1.10.1, Build 9e83765.

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

docker network create --subnet=172.18.0.0/16 mynet123

als einfach das Bild laufen lassen (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/

29
cantSleepNow

Ich verwende die Methode hier aus der offiziellen Docker-Dokumentation und habe bestätigt, dass sie funktioniert:

# At one Shell, start a container and
# leave its Shell idle and running

$ Sudo docker run -i -t --rm --net=none base /bin/bash
[email protected]:/#

# At another Shell, learn the container process ID
# and create its namespace entry in /var/run/netns/
# for the "ip netns" command we will be using below

$ Sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ Sudo mkdir -p /var/run/netns
$ Sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

# Check the bridge's IP address and netmask

$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...

# Create a pair of "peer" interfaces A and B,
# bind the A end to the bridge, and bring it up

$ Sudo ip link add A type veth peer name B
$ Sudo brctl addif docker0 A
$ Sudo ip link set A up

# Place B inside the container's network namespace,
# rename to eth0, and activate it with a free IP

$ Sudo ip link set B netns $pid
$ Sudo ip netns exec $pid ip link set dev B name eth0
$ Sudo ip netns exec $pid ip link set eth0 up
$ Sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ Sudo ip netns exec $pid ip route add default via 172.17.42.1

Mit diesem Ansatz starte ich meine Container immer mit net = none und setze IP-Adressen mit einem externen Skript.

13
unlink

Trotz meines anfänglichen Scheiterns war @ MarkO'Connors Antwort tatsächlich richtig. Ich habe eine neue Schnittstelle (docker0) in meiner Datei Host/etc/network/interfaces erstellt, Sudo ifup docker0 auf dem Host ausgeführt und dann ausgeführt

docker run --net=Host -i -t ... 

dieser hat die statische IP abgeholt und im Container an docker0 vergeben.

Vielen Dank!

6
dlanced

Docker-Container verfügen standardmäßig nicht über die erforderlichen Berechtigungen, um den Netzwerkstapel zu bearbeiten. Sie können versuchen, --cap-add=NET_ADMIN auf den Befehl run, um diese spezielle Funktion zuzulassen. Oder Sie können versuchen --privileged=true (gewährt alle Rechte) zum Testen.

Eine andere Option ist die Verwendung von Pipeline vom Host.

4
user2105103

Das hat bei mir funktioniert:

docker run --cap-add=NET_ADMIN -d -it myimages/image1  /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0;  bash"

Erklärt:

  • --cap-add=NET_ADMIN Haben Rechte zum Verwalten des Netzes (d. H. Für den Befehl /sbin/ip)

  • myimages/image1 Bild für den Container

  • /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0 ; bash" Führen Sie im Container ip addr add 172.17.0.8 dev eth0 Aus, um diesem Container eine neue IP-Adresse 172.17.0.8 hinzuzufügen (Achtung: Verwenden Sie jetzt eine kostenlose IP-Adresse . und in der Zukunft ). Führen Sie dann bash aus, damit der Container nicht automatisch angehalten wird.

Bonus:

Meine Zielszene: Eine verteilte App mit Containern einrichten, die in der dist-App unterschiedliche Rollen spielen. Ein "Dirigentencontainer" kann Docker-Befehle (von innen) ausführen, um Container nach Bedarf zu starten und zu stoppen. Jeder Container ist so konfiguriert, dass er weiß, wo eine Verbindung hergestellt werden muss, um auf eine bestimmte Rolle/einen bestimmten Container in der dist-App zuzugreifen (daher muss jedem Partner der Satz von IPs für jede Rolle bekannt sein).

Um dies zu tun:

  1. "Dirigentenbehälter"

bild erstellt mit diesem Dockerfile

FROM pin3da/docker-zeromq-node
MAINTAINER Foobar

# install docker software  
RUN apt-get -yqq update && apt-get -yqq install docker.io 

# export /var/run/docker.sock  so we can connect it in the Host
VOLUME /var/run/docker.sock

befehl zum Erstellen von Images:

docker build --tag=myimages/conductor --file=Dockerfile .

container run befehl:

docker run -v /var/run/docker.sock:/var/run/docker.sock --name=conductor1 -d -it myimages/conductor  bash
  1. Führen Sie Container mit unterschiedlichen Rollen aus.

Fügen Sie zuerst (nicht unbedingt erforderlich) Einträge zu /etc/hosts Hinzu, um Partner nach IP oder Name zu suchen (Option --add-Host)

Zweitens (offensichtlich erforderlich) weisen Sie dem laufenden Container eine IP zu (verwenden Sie /sbin/ip Darin)

docker run --cap-add=NET_ADMIN --add-Host worker1:172.17.0.8 --add-Host worker2:172.17.0.9 --name=worker1 -h worker1.example.com -d -it myimages/image1  /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0;  bash"
3
cibercitizen1

& mit Pipeline (192.168.1.1 unter der default gateway IP-Adresse):

pipework br0 container-name 192.168.1.10/[email protected]

Bearbeiten: nicht mit --net=none Beginnen: Dies schließt Container-Ports.

Siehe weitere Anmerkungen

3
Stuart Cardall

pipework auch toll, aber wenn Sie einen anderen Hostnamen als ip verwenden können, können Sie dieses Skript ausprobieren

#!/bin/bash
# This function will list all ip of running containers
function listip {
    for vm in `docker ps|tail -n +2|awk '{print $NF}'`; 
        do
            ip=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $vm`;
            echo "$ip  $vm";
        done    
}

# This function will copy hosts file to all running container /etc/hosts
function updateip {
        for vm in `docker ps|tail -n +2|awk '{print $NF}'`;
                do
                        echo "copy hosts file to  $vm";
                        docker exec -i $vm sh -c 'cat > /etc/hosts' < /tmp/hosts
                done
}

listip > /tmp/hosts
updateip

Sie müssen diesen Befehl nur jedes Mal ausführen, wenn Sie Ihre Docker Labs starten. Sie finden meine Skripte mit zusätzlichen Funktionen hier dockerip

2
Phan Dolphy

Ich habe verstanden, dass Sie sich derzeit nicht mit der Multi-Host-Vernetzung von Containern befassen, aber ich glaube, dass Sie sie wahrscheinlich bald brauchen werden. Weave ermöglicht es Ihnen, zunächst mehrere Containernetzwerke auf einem Host zu definieren und dann möglicherweise einige Container auf einen anderen Host zu verschieben, ohne die statische IP-Adresse zu verlieren, die Sie ihm zugewiesen haben.

2
errordeveloper

Ich habe entdeckt, dass --net=Host ist möglicherweise nicht immer die beste Option, da Benutzer den Host möglicherweise vom Container aus herunterfahren können! Auf jeden Fall stellte sich heraus, dass der Grund, warum ich es von innen nicht richtig machen konnte, darin bestand, dass die Netzwerkkonfiguration auf Sitzungen beschränkt war, die mit dem --privileged=true Streit.

1
dlanced

Der Vollständigkeit halber: In den Docker-Foren wird eine andere Methode vorgeschlagen. (Redigieren Sie: und erwähnt beiläufig durch die Antwort von Андрей Сердюк).

Fügen Sie die statische IP-Adresse auf dem Host System hinzu und veröffentlichen Sie dann Ports auf dieser IP, z. docker run -p 192.0.2.1:80:80 -d mywebserver.

Natürlich funktioniert diese Syntax nicht für IPv6 und die Dokumentation erwähnt das nicht ...

Für mich klingt das falsch: Die üblichen Wildcards (*: 80) auf dem Host stehen theoretisch im Konflikt mit dem Container. In der Praxis hat der Docker-Port Vorrang und es treten keine Konflikte auf, da er mithilfe von iptables implementiert wird. Ihre öffentliche Container-IP antwortet jedoch weiterhin auf alle nicht - in Konflikt stehenden Ports, z. ssh.

1
sourcejedi

Sie können SkyDns mit dem Diensterkennungstool einrichten - https://github.com/crosbymichael/skydock

Oder: Erstellen Sie einfach eine Netzwerkschnittstelle und veröffentlichen Sie Docker-Container-Ports wie hier https://Gist.github.com/andreyserdjuk/bd92b5beba2719054dfe