Asigne la interfaz física al acoplador exclusivamente

12

Me gustaría ejecutar una prueba de red de alto rendimiento en un contenedor acoplable, y no quiero la sobrecarga del puente (para que las tuberías no funcionen AFAIK). Me gustaría asignar (además del dispositivo docker veth normal) una interfaz de red física de 40 GbE desde el host a un contenedor docker como en el modo lxc "phys". Esto debería hacer que la interfaz física se vuelva invisible para el host.

NeilenMarais
fuente

Respuestas:

4

pipework puede mover una interfaz de red física del espacio de nombres de red predeterminado al contenedor:

    $ sudo pipework --direct-phys eth1 $CONTAINERID 192.168.1.2/24

Para más información ver aquí .

Christoph Zauner
fuente
1
Acepté esta respuesta porque parece sencillo, pero no lo he probado a mí mismo (he utilizado la respuesta larga que escribí antes de canalizaciones creció esta funcionalidad)
NeilenMarais
7

En mi búsqueda, encontré soluciones antiguas que implicaban pasar parámetros lxc-config a docker, pero las versiones más nuevas de docker ya no usan las herramientas lxc, por lo que eso no puede funcionar.

Siguiendo la sugerencia aquí: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ se encontró una solución. No busqué modificar la secuencia de comandos de la tubería como se mencionó anteriormente, sino que utilicé los comandos necesarios directamente. Consulte también la siguiente publicación del blog: http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/ .

Los siguientes comandos de herramienta de espacio de nombres de red de bajo nivel (es decir, no específicos de Docker) se pueden utilizar para transferir una interfaz desde el host a un contenedor de Docker:

CONTAINER=slave-play # Name of the docker container
HOST_DEV=ethHOST     # Name of the ethernet device on the host
GUEST_DEV=test10gb   # Target name for the same device in the container
ADDRESS_AND_NET=10.101.0.5/24

# Next three lines hooks up the docker container's network namespace 
# such that the ip netns commands below will work
mkdir -p /var/run/netns
PID=$(docker inspect -f '{{.State.Pid}}' $CONTAINER)
ln -s /proc/$PID/ns/net /var/run/netns/$PID

# Move the ethernet device into the container. Leave out 
# the 'name $GUEST_DEV' bit to use an automatically assigned name in 
# the container
ip link set $HOST_DEV netns $PID name $GUEST_DEV

# Enter the container network namespace ('ip netns exec $PID...') 
# and configure the network device in the container
ip netns exec $PID ip addr add $ADDRESS_AND_NET dev $GUEST_DEV

# and bring it up.
ip netns exec $PID ip link set $GUEST_DEV up

# Delete netns link to prevent stale namespaces when the docker
# container is stopped
rm /var/run/netns/$PID

Una advertencia menor en el nombre de la interfaz si su host tiene muchos dispositivos ethX (el mío tenía eth0 -> eth5). Por ejemplo, digamos que mueve eth3 al contenedor como eth1 en el espacio de nombres del contenedor. Cuando detenga el contenedor, el núcleo intentará mover el dispositivo eth1 del contenedor nuevamente al host, pero observe que ya existe un dispositivo eth1. Luego cambiará el nombre de la interfaz a algo arbitrario; Me llevó un tiempo encontrarlo de nuevo. Por esta razón, edité /etc/udev/rules.d/70-persistent-net.rules (creo que este nombre de archivo es común a las distribuciones de Linux más populares; estoy usando Debian) para dar a la interfaz en cuestión un nombre único e inconfundible. y utilícelo tanto en el contenedor como en el host.

Como no estamos usando Docker para hacer esta configuración, las herramientas estándar de ciclo de vida de Docker (por ejemplo, Docker Run --restart = on-failure: 10 ...) no se pueden usar. La máquina host en cuestión ejecuta Debian Wheezy, así que escribí el siguiente script de inicio:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          slave-play
# Required-Start:    $local_fs $network $named $time $syslog $docker
# Required-Stop:     $local_fs $network $named $time $syslog $docker
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       some slavishness
### END INIT INFO

CONTAINER=slave-play
SCRIPT="docker start -i $CONTAINER"
RUNAS=root

LOGFILE=/var/log/$CONTAINER.log
LOGFILE=/var/log/$CONTAINER.log

HOST_DEV=test10gb
GUEST_DEV=test10gb
ADDRESS_AND_NET=10.101.0.5/24


start() {
  if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); then
echo 'Service already running' >&2
return 1
  fi
  echo 'Starting service…' >&2
  local CMD="$SCRIPT &> \"$LOGFILE\" &"
  su -c "$CMD" $RUNAS 
  sleep 0.5 # Nasty hack so that docker container is already running before we do the rest
  mkdir -p /var/run/netns
  PID=$(docker inspect -f '{{.State.Pid}}' $CONTAINER)
  ln -s /proc/$PID/ns/net /var/run/netns/$PID
  ip link set $HOST_DEV netns $PID name $GUEST_DEV
  ip netns exec $PID ip addr add $ADDRESS_AND_NET dev $GUEST_DEV
  ip netns exec $PID ip link set $GUEST_DEV up
  rm /var/run/netns/$PID
  echo 'Service started' >&2
}

stop() {
  echo "Stopping docker container $CONTAINER" >&2
  docker stop $CONTAINER
  echo "docker container $CONTAINER stopped" >&2
}


case "$1" in
  start)
start
;;
  stop)
stop
;;
  restart)
stop
start
;;
  *)
echo "Usage: $0 {start|stop|restart}"
esac

Ligeramente hacky, pero funciona :)

NeilenMarais
fuente
¿Por qué comienzan los nombres de la interfaz de red eth? ¿Debian no hace nombres de dispositivos de red consistentes?
Michael Hampton
Para cualquier otra persona que se preguntara por qué /var/run/netns/$PIDse necesita el enlace simbólico : lo necesita para que los ip netns exec $PID ...comandos funcionen.
Donn Lee
2

Escribo un complemento de red de Docker para hacer esto.

https://github.com/yunify/docker-plugin-hostnic

docker pull qingcloud/docker-plugin-hostnic
docker run -v /run/docker/plugins:/run/docker/plugins -v /etc/docker/hostnic:/etc/docker/hostnic --network host --privileged qingcloud/docker-plugin-hostnic docker-plugin-hostnic
docker network create -d hostnic --subnet=192.168.1.0/24 --gateway 192.168.1.1 hostnic
docker run -it --ip 192.168.1.5 --mac-address 52:54:0e:e5:00:f7 --network hostnic ubuntu:14.04 bash
jolestar
fuente