将物理接口专门分配给docker

我想在docker集装箱中运行一个高性能的networkingtesting,并且不希望桥接的开销(所以pipeworks将不起作用)。 我想分配一个物理的40GbEnetworking接口(除了普通的docker veth设备之外),就像在lxc“phys”模式下一样,从主机到Docker容器。 这应该导致物理接口对主机不可见。

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

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

欲了解更多信息,请看这里

在我的search中,我遇到了一些旧的解决scheme,它们将lxc-configparameter passing给docker,但是较新版本的docker不再使用lxc工具,因此无法工作。

按照此处的build议: https : //groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJfind了一个解决scheme。 我没有考虑如上所述修改pipe道脚本,而是直接使用所需的命令。 另见后续博文: http : //jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/ 。

以下低级别(即不是特定于docker的)networking名称空间工具命令可用于将接口从主机传输到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设备。 然后它会将接口重命名为任意的; 花了我一会儿才find它。 由于这个原因,我编辑了/etc/udev/rules.d/70-persistent-net.rules(我认为这个文件名对于大多数stream行的Linux发行版来说是很常见的;我使用的是Debian)来给这个接口提供一个独一无二的名字,并在容器和主机上使用。

由于我们没有使用docker来执行此configuration,所以不能使用标准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 

有点哈克,但它的作品:)

我写了一个dockernetworking插件来做到这一点。

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