Yalnızca docker'a fiziksel arayüz atayın


12

Bir docker kapsayıcısında yüksek performanslı bir ağ testi yapmak istiyorum ve köprüleme yükünü istemiyorum (bu yüzden pipeworks AFAIK çalışmayacak). Ben lxc "phys" modunda olduğu gibi (normal docker veth cihazına ek olarak) ana bir docker konteyner fiziksel 40GbE ağ arayüzü atamak istiyorum. Bu, fiziksel arabirimin ana bilgisayar tarafından görünmez olmasına neden olmalıdır.

Yanıtlar:


4

pipework fiziksel ağ arabirimini varsayılandan kapsayıcı ağ ad alanına taşıyabilir:

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

Daha fazla bilgi için buraya bakın .


1
Bu cevabı kabul ediyorum, çünkü basit görünüyor, ama kendim denemedim (
pipeworks

7

Aramamda lxc-config parametrelerini docker'a geçiren eski çözümlerle karşılaştım, ancak docker'ın daha yeni sürümleri artık lxc araçlarını kullanmıyor, bu yüzden çalışamıyor.

Buradaki öneriden sonra: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ bir çözüm bulundu. Gerekli komutları doğrudan kullanarak, yukarıda belirtildiği gibi boru komut dosyası değiştirmeye bakmadım. Ayrıca sonraki blog yayınına bakın: http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/ .

Ana bilgisayardan bir docker kapsayıcısına bir arabirim aktarmak için aşağıdaki düşük düzeyli (yani docker'a özgü olmayan) ağ ad alanı aracı komutları kullanılabilir:

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

Ana makinenizde çok fazla ethX cihazı varsa, arayüz adında küçük bir uyarı (benimki eth0 -> eth5 vardı). Örneğin, eth3'ü konteynerin ad alanında eth1 olarak konteynerin içine taşıdığınızı varsayalım. Kapsayıcıyı durdurduğunuzda, çekirdek kabın eth1 aygıtını ana bilgisayara geri taşımayı dener, ancak zaten bir eth1 aygıtı olduğunu fark eder. Daha sonra arayüzü keyfi bir şekilde yeniden adlandırır; tekrar bulmam biraz zaman aldı. Bu nedenle /etc/udev/rules.d/70-persistent-net.rules (bu dosya adının en popüler Linux dağıtımları için ortak olduğunu düşünüyorum; Debian kullanıyorum) düzenledim, söz konusu arabirime benzersiz ve açık bir ad vermek için ve hem kapta hem de ana bilgisayarda kullanın.

Bu yapılandırmayı yapmak için docker'ı kullanmadığımızdan, standart docker yaşam döngüsü araçları (örn. Docker run --restart = on-error: 10 ...) kullanılamaz. Söz konusu ana makine Debian Wheezy çalıştırıyor, bu yüzden aşağıdaki init betiğini yazdım:

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

Biraz hacky, ama işe yarıyor :)


Ağ arayüzü adlarınız neden başlıyor eth? Debian tutarlı ağ cihazı adları yapmıyor mu?
Michael Hampton

Symlink'in neden /var/run/netns/$PIDgerekli olduğunu merak eden herkes için: ip netns exec $PID ...Komutların çalışması için buna ihtiyacınız var .
Donn Lee

2

Bunu yapmak için bir docker ağ eklentisi yazıyorum.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.