Nei*_*ais 13 networking docker
我想在 docker 容器中运行高性能网络测试,并且不想要桥接的开销(因此管道无法工作 AFAIK)。我想(除了普通的 docker veth 设备之外)从主机到 docker 容器分配一个物理 40GbE 网络接口,就像在 lxc“phys”模式下一样。这应该会导致物理接口对主机不可见。
在我的搜索中,我遇到了旧的解决方案,这些解决方案涉及将 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
Run Code Online (Sandbox Code Playgroud)
如果您的主机有很多 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
Run Code Online (Sandbox Code Playgroud)
有点hacky,但它有效:)
小智 4
pipework可以将物理网络接口从默认网络命名空间移至容器网络命名空间:
$ sudo pipework --direct-phys eth1 $CONTAINERID 192.168.1.2/24
Run Code Online (Sandbox Code Playgroud)
欲了解更多信息,请参见此处。
| 归档时间: |
|
| 查看次数: |
15806 次 |
| 最近记录: |