도커 컨테이너에서 고성능 네트워크 테스트를 실행하고 싶고 브리징 오버헤드를 원하지 않습니다(파이프워크가 AFAIK에서 작동하지 않음). lxc "phys" 모드에서처럼 호스트에서 도커 컨테이너로 물리적 40GbE 네트워크 인터페이스를 일반 docker veth 장치에 추가로 할당하고 싶습니다. 이로 인해 물리적 인터페이스가 호스트에 보이지 않게 됩니다.
답변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-pertant-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
약간 해킹되었지만 작동합니다 :)
답변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