专门为Docker分配物理接口


12

我想在Docker容器中运行高性能网络测试,并且不希望桥接的开销(因此管道工程无法在AFAIK中使用)。我想像在lxc“ phys”模式下一样(除了普通的docker veth设备)分配一个从主机到docker容器的物理40GbE网络接口。这将导致物理接口对主机不可见。

Answers:


4

pipework 可以将物理网络接口从默认位置移动到容器网络名称空间:

    $ sudo pipework --direct-phys eth1 $CONTAINERID 192.168.1.2/24

有关更多信息,请参见此处


1
我接受了这个答案,因为它看起来很简单,但是我自己还没有尝试过(我使用了在管道系统开发此功能之前写的长答案)
NeilenMarais

7

在我的搜索中,我遇到了一些旧的解决方案,这些解决方案涉及将lxc-config参数传递给docker,但是较新版本的docker不再使用lxc工具,因此无法使用。

遵循以下建议:https : //groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ找到了解决方案。我没有考虑如上所述修改管道工作脚本,而是直接使用必需的命令。另请参阅后续博客文章:http : //jason.digitalinertia.net/exposed-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,因此我编写了以下初始化脚本:

#!/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

有点hacky,但是可以用:)


为什么您的网络接口名称以eth?开头?Debian不会使用一致的网络设备名称吗?
迈克尔·汉普顿

对于想知道为什么/var/run/netns/$PID需要符号链接的其他人:您需要它才能使ip netns exec $PID ...命令起作用。
唐·李

2

我写了一个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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.