กำหนดส่วนต่อประสานทางกายภาพให้กับนักเทียบท่าโดยเฉพาะ


12

ฉันต้องการเรียกใช้การทดสอบเครือข่ายประสิทธิภาพสูงในคอนเทนเนอร์ของนักเทียบท่าและไม่ต้องการโอเวอร์เฮดของการเชื่อมต่อ (เพื่อให้ปิเปตไม่ทำงานใน AFAIK) ฉันต้องการมอบหมาย (นอกเหนือจากอุปกรณ์ veth docker ปกติ) อินเตอร์เฟสเครือข่ายทางกายภาพ 40GbE จากโฮสต์ไปยังคอนเทนเนอร์ docker เช่นเดียวกับในโหมด lxc "phys" สิ่งนี้ควรทำให้อินเตอร์เฟสแบบฟิสิคัลเป็นโฮสต์ที่มองไม่เห็น

คำตอบ:


4

pipework สามารถย้ายอินเตอร์เฟสเครือข่ายแบบฟิสิคัลจากค่าดีฟอลต์ไปยังเนมสเปซเครือข่ายคอนเทนเนอร์:

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

สำหรับข้อมูลเพิ่มเติมดูที่นี่


1
ฉันยอมรับคำตอบนี้เพราะดูเหมือนจะง่าย แต่ฉันไม่ได้ลองด้วยตัวเอง (ฉันใช้คำตอบยาว ๆ ที่ฉันเขียนก่อนที่ pipeworks จะเพิ่มฟังก์ชันการทำงานนี้)
NeilenMarais

7

ในการค้นหาของฉันฉันเจอวิธีแก้ไขปัญหาเก่าที่ invovled ผ่านพารามิเตอร์ lxc-config ไปที่นักเทียบท่า แต่นักเทียบท่ารุ่นใหม่ไม่ได้ใช้เครื่องมือ lxc อีกต่อไปดังนั้นจึงไม่สามารถทำงานได้

ทำตามคำแนะนำที่นี่: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJพบวิธีแก้ปัญหา ฉันไม่ได้มองไปที่การแก้ไขสคริปต์ pipework ดังกล่าวข้างต้นแทนที่จะใช้คำสั่งที่จำเป็นโดยตรง ยังเห็นโพสต์บล็อกต่อไปนี้: http://jason.digitalinertia.net/exposing-docker-containers-with-sr-iov/

คำสั่งเครื่องมือเนมสเปซเครือข่ายเนมสเปซระดับต่ำ (เช่นไม่ใช่เฉพาะนักเทียบท่า) ต่อไปนี้สามารถใช้เพื่อถ่ายโอนอินเตอร์เฟสจากโฮสต์ไปยังคอนเทนเนอร์นักเทียบท่า:

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 ในเนมสเปซของ container เมื่อคุณหยุดคอนเทนเนอร์เคอร์เนลจะพยายามย้ายอุปกรณ์ eth1 ของคอนเทนเนอร์กลับไปยังโฮสต์ แต่สังเกตว่ามีอุปกรณ์ eth1 อยู่แล้ว จากนั้นจะเปลี่ยนชื่ออินเทอร์เฟซเป็นบางอย่างตามอำเภอใจ ใช้เวลาสักครู่เพื่อค้นหาอีกครั้ง ด้วยเหตุนี้ฉันจึงแก้ไข /etc/udev/rules.d/70-persistent-net.rules (ฉันคิดว่าชื่อไฟล์นี้เป็นเรื่องธรรมดาสำหรับ Linux distros ที่ได้รับความนิยมมากที่สุดฉันใช้ Debian) เพื่อให้อินเทอร์เฟซเป็นชื่อที่ไม่ซ้ำใคร และใช้มันทั้งในคอนเทนเนอร์และบนโฮสต์

เนื่องจากเราไม่ได้ใช้นักเทียบท่าเพื่อกำหนดค่าเครื่องมือวงจรชีวิตนักเทียบท่ามาตรฐาน (เช่นนักวิ่งที่เรียกใช้ --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

แฮ็คเล็กน้อย แต่ได้ผล :)


ทำไมชื่ออินเตอร์เฟซเครือข่ายของคุณเริ่มต้นด้วยeth? Debian ทำชื่ออุปกรณ์เครือข่ายไม่ตรงกันหรือไม่?
Michael Hampton

สำหรับคนอื่นที่สงสัยว่าเหตุใดจึง/var/run/netns/$PIDต้องใช้symlink : คุณต้องการip netns exec $PID ...คำสั่งในการทำงาน
Donn Lee

2

ฉันเขียนปลั๊กอินเครือข่ายนักเทียบท่าเพื่อทำสิ่งนี้

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.