Chỉ định giao diện vật lý cho docker độc quyền


12

Tôi muốn chạy thử nghiệm mạng hiệu suất cao trong thùng chứa docker và không muốn chi phí bắc cầu (vì vậy hệ thống đường ống sẽ không hoạt động AFAIK). Tôi muốn chỉ định (ngoài thiết bị docker veth bình thường) giao diện mạng 40GbE vật lý từ máy chủ sang bộ chứa docker như trong chế độ "vật lý" lxc. Điều này sẽ làm cho giao diện vật lý trở nên vô hình với máy chủ.

Câu trả lời:


4

pipework có thể di chuyển giao diện mạng vật lý từ mặc định sang không gian tên mạng container:

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

Để biết thêm thông tin xem tại đây .


1
Tôi đã chấp nhận câu trả lời này vì nó có vẻ đơn giản, nhưng tôi đã không tự mình thử nó (Tôi đã sử dụng câu trả lời dài mà tôi đã viết trước khi các bài tập phát triển chức năng này)
NeilenMarais

7

Trong tìm kiếm của mình, tôi đã tìm thấy các giải pháp cũ liên quan đến việc chuyển các tham số lxc-config cho docker, nhưng các phiên bản mới hơn của docker không sử dụng các công cụ lxc nữa, do đó không thể hoạt động.

Theo đề xuất ở đây: https://groups.google.com/d/msg/docker-user/pL8wlmiuAEU/QfcoFcKI3kgJ một giải pháp đã được tìm thấy. Tôi đã không xem xét sửa đổi tập lệnh pipework như đã đề cập ở trên, thay vào đó sử dụng các lệnh được yêu cầu trực tiếp. Cũng xem bài đăng blog tiếp theo: http://jason.digitalinertia.net/exposeing-docker-containers-with-sr-agu/ .

Các lệnh công cụ không gian mạng cấp độ thấp (nghĩa là không phải docker) sau đây có thể được sử dụng để chuyển giao diện từ máy chủ sang bộ chứa 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

Một cảnh báo nhỏ về việc đặt tên giao diện nếu máy chủ của bạn có nhiều thiết bị ethX (của tôi có eth0 -> eth5). Ví dụ: bạn di chuyển eth3 vào vùng chứa dưới dạng eth1 trong không gian tên container. Khi bạn dừng container, kernel sẽ cố gắng di chuyển thiết bị eth1 của container về máy chủ, nhưng lưu ý rằng đã có thiết bị eth1. Sau đó nó sẽ đổi tên giao diện thành một cái gì đó tùy ý; phải mất một thời gian để tìm lại. Vì lý do này, tôi đã chỉnh sửa /etc/udev/rules.d/70-persistent-net.rules (Tôi nghĩ tên tệp này là phổ biến cho hầu hết các bản phân phối Linux phổ biến; Tôi đang sử dụng Debian) để đặt cho giao diện trong câu hỏi một tên duy nhất, không thể nhầm lẫn và sử dụng nó trong cả container và trên máy chủ.

Vì chúng tôi không sử dụng docker để thực hiện cấu hình này, nên không thể sử dụng các công cụ vòng đời của docker tiêu chuẩn (ví dụ: docker run --restart = on-fail: 10 ...). Máy chủ trong câu hỏi chạy Debian Wheezy, vì vậy tôi đã viết đoạn script init sau:

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

Hơi hack, nhưng nó hoạt động :)


Tại sao tên giao diện mạng của bạn bắt đầu bằng eth? Debian không làm tên thiết bị mạng nhất quán?
Michael Hampton

Đối với bất cứ ai khác đã tự hỏi tại sao symlink /var/run/netns/$PIDlà cần thiết: Bạn cần nó để các ip netns exec $PID ...lệnh hoạt động.
Donn Lee

2

Tôi viết một plugin mạng docker để làm điều này.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.