Docker コンテナで高パフォーマンス ネットワーク テストを実行したいのですが、ブリッジのオーバーヘッドは発生させたくないので (したがって、私の知る限りではパイプワークは機能しません)、(通常の Docker veth デバイスに加えて) ホストから Docker コンテナに、lxc "phys" モードのように物理 40GbE ネットワーク インターフェイスを割り当てたいと思います。これにより、物理インターフェイスがホストから見えなくなります。
答え1
pipework
物理ネットワーク インターフェイスをデフォルトからコンテナ ネットワーク名前空間に移動できます。
$ sudo pipework --direct-phys eth1 $CONTAINERID 192.168.1.2/24
詳細については、ここ。
答え2
検索中に、lxc-config パラメータを docker に渡す古いソリューションを見つけましたが、新しいバージョンの docker では lxc ツールが使用されなくなったため、これは機能しません。
ここでの提案に従ってください:https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ解決策が見つかりました。上記のように配管スクリプトを変更することは検討せず、代わりに必要なコマンドを直接使用しました。次のブログ投稿も参照してください。http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/ (英語)。
次の低レベル (つまり、Docker 固有ではない) ネットワーク名前空間ツール コマンドを使用して、ホストから 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
ホストに ethX デバイスが多数ある場合 (私のホストでは eth0 -> eth5)、インターフェイスの命名に関する小さな注意点があります。たとえば、コンテナの名前空間で eth3 を eth1 としてコンテナに移動するとします。コンテナを停止すると、カーネルはコンテナの eth1 デバイスをホストに戻そうとしますが、すでに eth1 デバイスが存在することに注意してください。次に、インターフェイスの名前を任意の名前に変更します。再び見つけるのにしばらく時間がかかりました。このため、/etc/udev/rules.d/70-persistent-net.rules (このファイル名は、ほとんどの一般的な Linux ディストリビューションで共通だと思います。私は Debian を使用しています) を編集して、問題のインターフェイスに一意で紛らわしい名前を付け、コンテナとホストの両方でその名前を使用しました。
この構成には docker を使用していないため、標準の docker ライフサイクル ツール (例: docker run --restart=on-failure:10 ...) は使用できません。問題のホスト マシンは Debian Wheezy を実行しているため、次の init スクリプトを作成しました。
#!/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
少しハッキーですが、動作します :)
答え3
これを実行するために、docker ネットワーク プラグインを作成します。
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