Dans ma recherche, je suis tombé sur d'anciennes solutions qui impliquaient de passer des paramètres lxc-config à docker, mais les nouvelles versions de docker n'utilisent plus les outils lxc, donc cela ne peut pas fonctionner.
En suivant la suggestion ici: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ une solution a été trouvée. Je n'ai pas cherché à modifier le script de tuyauterie comme mentionné ci-dessus, à la place en utilisant directement les commandes requises. Voir également le billet de blog suivant: http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/ .
Les commandes d'outil d'espace de noms de réseau de bas niveau (c'est-à-dire non spécifiques aux dockers) suivantes peuvent être utilisées pour transférer une interface de l'hôte vers un conteneur 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
Une mise en garde mineure sur le nom de l'interface si votre hôte a beaucoup de périphériques ethX (le mien avait eth0 -> eth5). Par exemple, disons que vous déplacez eth3 dans le conteneur en tant que eth1 dans l'espace de noms des conteneurs. Lorsque vous arrêtez le conteneur, le noyau essaiera de déplacer le périphérique eth1 du conteneur vers l'hôte, mais notez qu'il existe déjà un périphérique eth1. Il renommera alors l'interface en quelque chose d'arbitraire; m'a pris un certain temps pour le retrouver. Pour cette raison, j'ai édité /etc/udev/rules.d/70-persistent-net.rules (je pense que ce nom de fichier est commun à la plupart des distributions Linux populaires; j'utilise Debian) pour donner à l'interface en question un nom unique et unique. et utilisez-le à la fois dans le conteneur et sur l'hôte.
Étant donné que nous n'utilisons pas docker pour effectuer cette configuration, les outils de cycle de vie de docker standard (par exemple, docker run --restart = on-failure: 10 ...) ne peuvent pas être utilisés. La machine hôte en question exécute Debian Wheezy, j'ai donc écrit le script init suivant:
#!/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
Légèrement hacky, mais ça marche :)