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 :)