Asignar IP estática al contenedor Docker

205

Ahora estoy tratando de asignar una IP estática 172.17.0.1 cuando se inicia un contenedor Docker.

Utilizo el puerto 2122 como el puerto ssh de este contenedor, de modo que dejo que este contenedor escuche el puerto 2122.

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

Este comando ejecutará un contenedor Docker con una IP aleatoria como 172.17.0.5, pero necesito asignar una IP específica al contenedor.

El siguiente script de shell es lo que hago referencia a la documentación de Docker en la configuración avanzada de red.

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

Este script de shell asignará una IP estática 172.17.0.1 y se vinculará al mundo bien. Pero cada vez que trato de enviar a este contenedor desde mi local, no funcionó. ¿Cuál es el problema que posiblemente conocí?

LarryLo
fuente
Me temo que no hay una respuesta simple a esa pregunta, vea github.com/docker/docker/issues/6743 y github.com/docker/docker/issues/1179 , y lea github.com/jpetazzo/pipework
user2915097
@larrylo ¿puedes confirmar que comenzaste un sshd dentro del contenedor?
Bryan
55
Estás deshaciendo todas las rutas que el Docker Daemon hace por ti. Los contenedores no son máquinas virtuales.
user2105103
Sí, confirmo que puedo comenzar sshd dentro del contenedor
LarryLo

Respuestas:

291

Fácil con Docker versión 1.10.1, compilación 9e83765.

Primero debe crear su propia red de acopladores (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

que simplemente ejecutar la imagen (tomaré ubuntu como ejemplo)

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

luego en ubuntu shell

ip addr

Además podrías usar

  • --hostname para especificar un nombre de host
  • --add-host para agregar más entradas a / etc / hosts

Documentos (y por qué necesita crear una red) en https://docs.docker.com/engine/reference/commandline/network_create/

cantSleepNow
fuente
1
Gran respuesta: solo agrego información adicional: blog.jessfraz.com/post/ips-for-all-the-things
Ole
@cantSleepNow, por alguna razón, solo necesito usar mi propio bridge br0 creado por defecto que se crea en el archivo de interfaces durante el arranque del sistema (por lo que NO se crea usando docker network create), ¿podría sugerirme cómo puedo obtener el mismo efecto de - -ip parámetro (obtener una dirección IP fija para un contenedor) sin crear mi puente usando docker?
Mohammed Noureldin el
@MohammedNoureldin No entiendo completamente, también suena como una nueva pregunta, creo que deberías hacerla como tal.
cantSleepNow
@cantSleepNow Quiero decir que necesito corregir la dirección IP del contenedor aunque NO estoy usando un puente personalizado (por lo tanto, no se puede usar el parámetroip), ¿sugiere alguna forma de obtener eso?
Mohammed Noureldin el
@MohammedNoureldin No estoy seguro. Como dije, publique su pregunta como pregunta y no como comentario, tal vez haya alguien que sepa la respuesta.
cantSleepNow
89

Para docker-composeque pueda usar siguientedocker-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

desde el host puedes probar usando:

docker-compose up -d
curl 172.20.128.2

Modern docker-composeno cambia la dirección IP con tanta frecuencia.

Para encontrar ips de todos los contenedores en su docker-composeen una sola línea use:

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 desea automatizar, puede usar algo como este ejemplo general

zainengineer
fuente
2
Parece que esto solo funcionará en docker-compose v2, v3 rompió la compatibilidad.
Andrzej Rehmann
44
Al usar docker-compose v3 + removeip_range
Andrzej Rehmann
Sin embargo, no obtengo el ip_range. ¿No está eso cubierto por la subred? De todos modos, gracias! Eso solucionó mi "Tengo que buscar la ip de mi contenedor mongo de nuevo" - problema
Ben
1
¿Hay alguna manera de especificar la dirección IP en compose versión 3?
ealeon
2
La solución funciona bien para mí sin ip_range. Estoy usando la versión: '3.4'.
Mikhail Morfikov
24

No es una respuesta directa pero podría ayudar.

Ejecuto la mayoría de mis servicios dockerizados vinculados a ips estáticos propios usando el siguiente enfoque:

  1. Creo alias de ip para todos los servicios en el host docker
  2. Luego ejecuto cada servicio redirigiendo puertos desde esta ip al contenedor para que cada servicio tenga una ip estática que puedan usar los usuarios externos y otros contenedores.

Muestra:

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
fuente
Gracias ~ lo sé. Al igual que github.com/brandon-rhodes/fopnp/tree/m/playground do. Voy a intentarlo.
LarryLo
1
Esta es una muy buena solución, simplemente adjuntaría este enlace para que los nuevos usuarios aprendan sobre alias cyberciti.biz/faq/…
Mohammed Noureldin
Gracias por una buena solución.
RavinderSingh13
4

Esto funciona para mi.

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

Ejecutar imagen del acoplador docker run --net selnet --ip 172.18.0.2 hub

Al principio, tengo

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

Solución: Aumento del 2º cuádruple de la IP [.18. en lugar de .17.]

Nils Zenker
fuente
3
Hay una respuesta similar / idéntica 2 años más antigua en otra parte de esta página: stackoverflow.com/a/35359185/694469
KajMagnus
2

Me topé con este problema durante el intento de dockerise Avahi que necesita ser consciente de su IP pública para funcionar correctamente. Asignar IP estática al contenedor es complicado debido a la falta de soporte para la asignación de IP estática en Docker.

Este artículo describe la técnica de cómo asignar IP estática al contenedor en Debian :

  1. Se debe comenzar con el servicio Docker DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Supongo que el br0puente ya está configurado.

  2. El contenedor debe comenzar con --cap-add=NET_ADMIN --net=bridge

  3. Recipiente interior pre-up ip addr flush dev eth0en /etc/network/interfacespuede ser utilizado para desestimar dirección IP asignada por acoplable como en ejemplo siguiente:


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. El script de entrada del contenedor debe comenzar por /etc/init.d/networking start. Además, el script de entrada debe editar o completar el /etc/hostsarchivo para eliminar las referencias a la IP asignada por Docker.
Solo trabajo
fuente
2

Puede configurar la IP mientras la ejecuta.

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

Vea mi ejemplo en https://github.com/RvdGijp/mariadb-10.1-galera

Qué grosero
fuente
desafortunadamente, esto agrega una dirección IP más, si se asignó una dirección IP en el proceso anteriormente, esto tiene como resultado tener dos direcciones IP
davey
1

Puede acceder al servicio de otros contenedores por su nombre ( ping apacheobtendrá la ip o curl http://apacheaccedería al servicio http) Y esta puede ser una alternativa a una ip estática.

Guisong He
fuente
3
En la versión docker de 1.8, esto funciona directamente. En la versión más reciente, debe vincular estos contenedores.
Guisong He