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 :)