Tetapkan antarmuka fisik ke docker secara eksklusif

Saya ingin menjalankan tes jaringan berkinerja tinggi dalam wadah buruh pelabuhan, dan tidak ingin overhead bridging (jadi pipeworks tidak akan berfungsi AFAIK). Saya ingin menetapkan (selain perangkat docker Veth normal) antarmuka jaringan 40GbE fisik dari host ke wadah docker seperti dalam mode "phys" lxc. Ini harus menyebabkan antarmuka fisik menjadi tidak terlihat oleh host.

Dalam pencarian saya, saya menemukan solusi lama yang invovled melewati parameter LXC-config ke docker, tetapi versi docker yang lebih baru tidak menggunakan alat lxc lagi, sehingga tidak dapat berfungsi.

Mengikuti saran di sini: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ sebuah solusi ditemukan.Saya tidak melihat ke dalam memodifikasi skrip pipework seperti yang disebutkan di atas, Alih-alih menggunakan perintah yang diperlukan secara langsung. Juga lihat posting blog berikutnya: http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/.

Perintah alat namespace jaringan tingkat rendah (yaitu tidak spesifik docker) berikut dapat digunakan untuk mentransfer antarmuka dari host ke wadah docker:

CONTAINER=slave-play # Name of the docker containerHOST_DEV=ethHOST     # Name of the ethernet device on the hostGUEST_DEV=test10gb   # Target name for the same device in the containerADDRESS_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 workmkdir -p /var/run/netnsPID=$(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 containerip 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 containerip 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 stoppedrm /var/run/netns/$PID

>Peringatan kecil pada penamaan antarmuka jika host Anda memiliki banyak perangkat ethX (milik saya memiliki eth0 - eth5). Misalnya Anda memindahkan eth3 ke dalam wadah sebagai eth1 di namespace wadah. Saat Anda menghentikan penampung, kernel akan mencoba memindahkan perangkat eth1 penampung kembali ke host, tetapi perhatikan bahwa sudah ada perangkat eth1. Ini kemudian akan mengubah nama antarmuka menjadi sesuatu yang sewenang-wenang; butuh beberapa saat untuk menemukannya lagi. Untuk alasan ini saya mengedit /etc/udev/rules.d / 70-gigih-bersih.aturan (saya pikir nama file ini umum untuk distro Linux paling populer; saya menggunakan Debian) untuk memberikan antarmuka yang dimaksud Nama yang unik dan tidak salah lagi, dan menggunakannya di wadah dan di host.

Karena kita tidak menggunakan docker untuk melakukan konfigurasi ini, alat siklus hidup docker standar (misalnya docker run --restart=on-failure:10 ...) tidak dapat digunakan. Mesin host yang dimaksud menjalankan Debian Wheezy, jadi saya menulis skrip init berikut:

#!/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 INFOCONTAINER=slave-playSCRIPT="docker start -i $CONTAINER"RUNAS=rootLOGFILE=/var/log/$CONTAINER.logLOGFILE=/var/log/$CONTAINER.logHOST_DEV=test10gbGUEST_DEV=test10gbADDRESS_AND_NET=10.101.0.5/24start() {  if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); thenecho 'Service already running' >&2return 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)stopstart;;  *)echo "Usage: $0 {start|stop|restart}"esac

Sedikit hacky, tetapi berhasil :)

pipework dapat memindahkan Antarmuka jaringan fisik dari default ke namespace jaringan kontainer:

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

Untuk informasi lebih lanjut lihat di sini.

Saya menulis plugin jaringan docker untuk melakukan ini.

https://github.com/yunify/docker-plugin-hostnic

docker pull qingcloud/docker-plugin-hostnicdocker run -v /run/docker/plugins:/run/docker/plugins -v /etc/docker/hostnic:/etc/docker/hostnic --network host --privileged qingcloud/docker-plugin-hostnic docker-plugin-hostnicdocker network create -d hostnic --subnet=192.168.1.0/24 --gateway 192.168.1.1 hostnicdocker run -it --ip 192.168.1.5 --mac-address 52:54:0e:e5:00:f7 --network hostnic ubuntu:14.04 bash