tipos redes interfaz entre dockers crear contenedor asignar linux networking docker

linux - redes - ping entre dockers



¿Cómo puedo configurar una dirección IP estática en un contenedor Docker? (11)

Descubrí que --net = host podría no ser siempre la mejor opción, ya que podría permitir a los usuarios cerrar el host desde el contenedor. En cualquier caso, resulta que la razón por la que no podía hacerlo desde dentro era porque la configuración de la red estaba diseñada para restringirse a las sesiones comenzadas con el argumento --privileged = true.

Estoy perfectamente satisfecho con el rango de IP que Docker me proporciona de forma predeterminada (176.17.xx), así que no necesito crear un nuevo puente, solo quiero dar a mis contenedores una dirección estática dentro de ese rango para que pueda señale los navegadores del cliente directamente. Intenté usar

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

desde un Dockerfile, y llenó correctamente el archivo de interfaces, pero la interfaz en sí misma no cambió. De hecho, ejecutar ifup eth0 dentro del contenedor obtiene este error:

RTNETLINK responde: operación no permitida

Error al mostrar eth0


En realidad, a pesar de mi fracaso inicial, la respuesta de @ MarkO''Connor fue correcta. Creé una nueva interfaz (docker0) en mi archivo host / etc / network / interfaces, ejecuté sudo ifup docker0 en el host, y luego ejecuté

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

que recogió la IP estática y la asignó a docker0 en el contenedor.

¡Gracias!


Entendí que no está buscando una red de contenedores de múltiples hosts en esta etapa, pero creo que es probable que la necesite pronto. Weave le permitiría definir primero redes de contenedores múltiples en un host, y luego mover potencialmente algunos contenedores a otro host sin perder la IP estática que le haya asignado.


Esto funcionó para mí:

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

Explicado:

  • --cap-add=NET_ADMIN tiene derechos para administrar la red (es decir, para el comando /sbin/ip )

  • myimages/image1 para el contenedor

  • /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0 ; bash" Dentro del contenedor ejecute ip addr add 172.17.0.8 dev eth0 para agregar una nueva dirección IP 172.17.0.8 a este contenedor (precaución: no utilice una dirección IP gratis ahora y en el futuro ). Luego ejecuta bash, solo para que el contenedor no se detenga automáticamente.

Bonificación :

Mi escena objetivo: configurar una aplicación distribuida con contenedores que desempeñan diferentes roles en dist-app. Un "contenedor de conductor" puede ejecutar comandos de acoplador por sí mismo (adentro) para iniciar y detener contenedores según sea necesario. Cada contenedor está configurado para saber dónde conectarse para acceder a un rol / contenedor particular en la dist-app (por lo que el conjunto de ip para cada rol debe ser conocido por cada socio).

Para hacer esto:

  1. "contenedor conductor"

imagen creada con este 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

comando de creación de imagen:

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

contenedor ejecutar comando:

docker run -v /var/run/docker.sock:/var/run/docker.sock --name=conductor1 -d -it myimages/conductor bash

  1. Ejecutar contenedores con diferentes roles.

Primero (no es absolutamente necesario) agregar entradas a /etc/hosts para localizar socios por ip o nombre (opción --add-host )

Segundo (obviamente se requiere) asignar una ip al contenedor en ejecución (use /sbin/ip en él)

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"


Estoy usando el método escrito here de la documentación oficial de Docker y he confirmado que funciona:

# At one shell, start a container and # leave its shell idle and running $ sudo docker run -i -t --rm --net=none base /bin/bash root@63f36fc01b5f:/# # 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

Usando este enfoque, ejecuto mis contenedores siempre con net = none y establezco las direcciones IP con un script externo.


Las tuberías también son geniales, pero si puede usar un nombre de host que no sea ip, entonces puede probar este script

#!/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

Solo necesita ejecutar este comando cada vez que inicie sus laboratorios de docker Puede encontrar mis scripts con funciones adicionales aquí dockerip


Los contenedores Docker de forma predeterminada no tienen suficientes privilegios para manipular la pila de red. Puede intentar agregar --cap-add = NET_ADMIN al comando de ejecución para permitir esta capacidad específica. O puede probar --privileged = true (otorga todos los derechos) para la prueba.

Otra opción es usar pipework del host.


Para completar: hay otro método sugerido en los foros de Docker. (Editar: y mencionado de paso por la respuesta de Андрей Сердюк).

Agregue la dirección IP estática en el sistema host , luego publique los puertos en esa IP, por ejemplo, docker run -p 192.0.2.1:80:80 -d mywebserver .

Por supuesto, esa sintaxis no funcionará para IPv6 y la documentación no menciona que ...

Me suena mal: el comodín habitual se une (*: 80) en el host teóricamente en conflicto con el contenedor. En la práctica, el puerto Docker tiene prioridad y no entra en conflicto, debido a cómo se implementa con iptables. Pero su IP de contenedor público seguirá respondiendo en todos los puertos que no estén en conflicto, por ejemplo, ssh.



Ya he respondido esto aquí https://.com/a/35359185/4094678 pero ahora veo que esta pregunta es más antigua que la anterior, así que también copiaré la respuesta:

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

Primero necesita 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 el shell ubuntu

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/