Bei meiner Suche bin ich auf alte Lösungen gestoßen, bei denen lxc-config-Parameter an Docker übergeben wurden. Neuere Versionen von Docker verwenden die lxc-Tools jedoch nicht mehr, sodass dies nicht funktioniert.
Dem Vorschlag hier folgend: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ wurde eine Lösung gefunden. Ich habe nicht versucht, das Pipework-Skript wie oben erwähnt zu ändern, sondern die erforderlichen Befehle direkt zu verwenden. Siehe auch den folgenden Blog-Beitrag: http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/ .
Die folgenden Befehle des Netzwerk-Namespace-Tools auf niedriger Ebene (dh nicht Docker-spezifisch) können verwendet werden, um eine Schnittstelle vom Host in einen Docker-Container zu übertragen:
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
Eine kleine Einschränkung bei der Benennung der Benutzeroberfläche, wenn Ihr Host viele ethX-Geräte hat (meins hatte eth0 -> eth5). Angenommen, Sie verschieben eth3 als eth1 im Containernamensraum in den Container. Wenn Sie den Container stoppen, versucht der Kernel, das eth1-Gerät des Containers zurück auf den Host zu verschieben. Beachten Sie jedoch, dass bereits ein eth1-Gerät vorhanden ist. Anschließend wird die Schnittstelle in etwas Beliebiges umbenannt. Ich habe eine Weile gebraucht, um es wieder zu finden. Aus diesem Grund habe ich /etc/udev/rules.d/70-persistent-net.rules bearbeitet (ich denke, dieser Dateiname ist in den meisten gängigen Linux-Distributionen üblich; ich verwende Debian), um der fraglichen Schnittstelle einen eindeutigen, unverwechselbaren Namen zu geben und verwenden Sie dies sowohl im Container als auch auf dem Host.
Da wir für diese Konfiguration kein Docker verwenden, können die Standard-Docker-Lebenszyklus-Tools (z. B. Docker-Ausführung --restart = on-fail: 10 ...) nicht verwendet werden. Auf dem fraglichen Host-Computer wird Debian Wheezy ausgeführt, daher habe ich das folgende Init-Skript geschrieben:
#!/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
Etwas hackig, aber es funktioniert :)