Assegna IP statico al contenitore Docker


205

Sto ora cercando di assegnare un IP statico 172.17.0.1 all'avvio di un contenitore Docker.

Uso la porta 2122 come porta ssh di questo contenitore in modo da lasciare che questo contenitore ascolti la porta 2122.

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

Questo comando eseguirà un contenitore Docker con un IP casuale come 172.17.0.5, ma devo assegnare un IP specifico al contenitore.

Il seguente script di shell è ciò a cui faccio riferimento la documentazione di Docker nelle impostazioni di rete avanzate.

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

Questo script di shell assegnerà un IP statico 172.17.0.1 e si collegherà alla fine del mondo. Ma ogni volta che provo a inviare ssh a questo contenitore dal mio locale, non ha funzionato. Qual è il problema che forse ho incontrato?


Temo che non ci sia una risposta semplice a questa domanda, vedi github.com/docker/docker/issues/6743 e github.com/docker/docker/issues/1179 e leggi github.com/jpetazzo/pipework
user2915097

@larrylo puoi confermare che hai avviato un sshd all'interno del contenitore?
Bryan,

5
Stai annullando tutto il routing che il demone docker fa per te. I contenitori non sono macchine virtuali.
user2105103

Sì, confermo di poter avviare sshd all'interno del contenitore
LarryLo

Risposte:


291

Facile con Docker versione 1.10.1, build 9e83765.

Innanzitutto è necessario creare la propria rete docker (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

di eseguire semplicemente l'immagine (prenderò Ubuntu come esempio)

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

quindi nella shell di Ubuntu

ip addr

Inoltre potresti usare

  • --hostname per specificare un nome host
  • --add-host per aggiungere più voci a / etc / hosts

Documenti (e perché è necessario creare una rete) all'indirizzo https://docs.docker.com/engine/reference/commandline/network_create/


1
Ottima risposta - Basta aggiungere alcune informazioni aggiuntive: blog.jessfraz.com/post/ips-for-all-the-things
Ole

@cantSleepNow per qualche motivo ho solo bisogno di usare il mio bridge predefinito creato br0 che viene creato nel file interfacce durante l'avvio del sistema (quindi NON viene creato utilizzando la docker network create), potresti suggerirmi come posso ottenere lo stesso effetto di - -ip parametro (ottieni l'indirizzo IP fisso per un contenitore) senza creare il mio bridge usando la finestra mobile?
Mohammed Noureldin,

@MohammedNoureldin Non capisco perfettamente - suona anche come una nuova domanda, penso che dovresti chiederlo come tale.
cantSleepNow,

@cantSleepNow Voglio dire che devo correggere l'indirizzo IP del contenitore anche se NON sto usando un bridge personalizzato (quindi il parametro --ip non può essere usato), suggerisci un modo per ottenerlo?
Mohammed Noureldin,

@MohammedNoureldin non sono sicuro. Come ho detto, pubblica la tua domanda come domanda e non come commento - forse c'è qualcuno che conosce la risposta.
cantSleepNow,

89

Per docker-composete puoi usare quanto seguedocker-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

dall'host puoi testare usando:

docker-compose up -d
curl 172.20.128.2

Modern docker-composenon cambia l'indirizzo IP così frequentemente.

Per trovare ips di tutti i contenitori nel tuo docker-composein una sola riga usa:

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

Se vuoi automatizzare, puoi usare qualcosa come questo esempio


2
Sembra che questo funzionerà solo in docker-compose v2, v3 ha rotto la compatibilità.
Andrzej Rehmann,

4
Quando si utilizza docker-compose v3 + removeip_range
Andrzej Rehmann

Non ho l'ip_range però. non è quello coperto dalla sottorete? Comunque grazie! Ciò risolto il mio "Devo cercare di nuovo l'ip del mio contenitore mongo" - problema
Ben

1
c'è un modo per specificare l'indirizzo IP nella composizione 3 di composizione?
ealeon

2
La soluzione funziona bene per me senza ip_range. Sto usando la versione: "3.4".
Mikhail Morfikov,

24

Non è una risposta diretta ma potrebbe aiutare.

Eseguo la maggior parte dei miei servizi dockerizzati legati ai propri IP statici usando l'approccio successivo:

  1. Creo alias ip per tutti i servizi sull'host docker
  2. Quindi eseguo ogni servizio di reindirizzamento delle porte da questo IP al contenitore in modo che ogni servizio abbia un proprio IP statico che potrebbe essere utilizzato da utenti esterni e altri contenitori.

Campione:

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

Grazie ~ lo so. Proprio come fanno github.com/brandon-rhodes/fopnp/tree/m/playground . Lo proverò.
LarryLo

1
Questa è un'ottima soluzione, vorrei solo allegare questo link affinché i nuovi utenti possano conoscere l'aliasing cyberciti.biz/faq/…
Mohammed Noureldin,

Grazie per la bella soluzione.
RavinderSingh13,

4

Questo funziona per me.

Crea una rete con docker network create --subnet=172.17.0.0/16 selnet

Esegui immagine docker docker run --net selnet --ip 172.18.0.2 hub

All'inizio ho capito

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

Soluzione: aumentato il 2 ° quadruplo dell'IP [.18. anziché .17.]


3
C'è una simile risposta 2 anni più vecchio / identico altrove in questa pagina: stackoverflow.com/a/35359185/694469
KajMagnus

2

Mi sono imbattuto in questo problema durante il tentativo di attraccare Avahi che deve essere consapevole del suo IP pubblico per funzionare correttamente. L'assegnazione dell'IP statico al contenitore è complicata a causa della mancanza di supporto per l'assegnazione dell'IP statico in Docker.

Questo articolo descrive la tecnica su come assegnare un IP statico al contenitore su Debian :

  1. Il servizio Docker dovrebbe essere avviato con DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Presumo che il br0bridge sia già configurato.

  2. Il contenitore dovrebbe essere avviato con --cap-add=NET_ADMIN --net=bridge

  3. Il contenitore interno pre-up ip addr flush dev eth0in /etc/network/interfacespuò essere utilizzato per chiudere l'indirizzo IP assegnato da Docker come nell'esempio seguente:


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. Lo script di ingresso del contenitore dovrebbe iniziare con /etc/init.d/networking start. Inoltre, lo script di ingresso deve modificare o popolare il /etc/hostsfile per rimuovere i riferimenti all'IP assegnato da Docker.

2

È possibile impostare l'IP durante l'esecuzione.

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

Vedi il mio esempio su https://github.com/RvdGijp/mariadb-10.1-galera


sfortunatamente questo aggiunge un altro indirizzo IP, se un indirizzo IP è stato assegnato nel processo in precedenza, questo si traduce in due indirizzi IP
davey

1

Puoi accedere al servizio di altri container con il loro nome ( ping apacheotterrà l'ip o curl http://apacheaccederà al servizio http) E questa può essere un'alternativa a un ip statico.


3
Nella versione docker di 1.8 funziona direttamente. Nella versione più recente, è necessario collegare fistosamente questi contenitori.
Guisong He

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.