【发布时间】:2014-11-23 10:10:07
【问题描述】:
我有一段时间使用 OpenStack 来管理我的应用程序。现在我想将它们作为每个应用程序的容器转移到 docker,因为 docker 更轻量级和高效。
问题是几乎所有与网络相关的事情在运行时都出错了。
在我的设计中,每个应用程序容器都应该有一个静态 IP 地址,我可以使用 hosts 文件来定位容器网络。
这是我的实现。 (bash 文件名是 docker_addnet.sh)
# Useages
# docker_addnet.sh container_name IP
# interface name: veth_(containername)
# gateway 172.17.42.1
if [ $# != 2 ]; then
echo -e "ERROR! Wrong args"
exit 1
fi
container_netmask=16
container_gw=172.17.42.1
container_name=$1
bridge_if=veth_`echo ${container_name} | cut -c 1-10`
container_ip=$2/${container_netmask}
container_id=`docker ps | grep $1 | awk '{print \$1}'`
pid=`docker inspect -f '{{.State.Pid}}' ${container_name}`
echo "Contaner: " $container_name "pid: " $pid
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid
brctl delif docker0 $bridge_if
ip link add A type veth peer name B
ip link set A name $bridge_if
brctl addif docker0 $bridge_if
ip link set $bridge_if up
ip link set B netns $pid
ip netns exec $pid ip link set dev B name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $container_ip dev eth0
ip netns exec $pid ip route add default via $container_gw
该脚本用于设置容器的静态ip地址,然后运行容器,必须附加--net=none手动设置网络
您现在可以通过
启动容器sudo docker run --rm -it --name repl --dns=8.8.8.8 --net=none clojure bash
并通过
设置网络sudo zsh docker_addnet.sh repl 172.17.15.1
在容器bash中,你可以通过ip addr看到IP地址,输出类似于
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
67: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 2e:7b:7e:5a:b5:d6 brd ff:ff:ff:ff:ff:ff
inet 172.17.15.1/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::2c7b:7eff:fe5a:b5d6/64 scope link
valid_lft forever preferred_lft forever
到目前为止一切顺利。
让我们尝试使用clojure repl获取容器主机ip地址。首先是repl:
lein repl
接下来评估下面的代码
(. java.net.InetAddress getLocalHost)
clojure 代码等于
System.out.println(Inet4Address.getLocalHost());
你得到的是一个例外
UnknownHostException 5a8efbf89c79:名称或服务未知 java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:-2)
其他奇怪的事情是 RMI 服务器无法通过RemoteServer.getClientHost(); 获取客户端 IP 地址。
那么可能导致此问题的原因是什么?我记得java有时会得到错误的网络配置,但我不知道原因。
【问题讨论】:
标签: docker