我正在尝试使用 Python 进行网络开发,我能找到的最好的资源之一是这里 - Brandon Rhodes
现在我采用了上面提供的 vagrant 文件和其中包含的默认虚拟盒镜像的方法。这里的一切似乎都运行良好。
因此从本质上讲,我能够启动并运行具有以下架构的 ubuntu 框(取自上面的链接)
从我的 Ubuntu 机器上,我能够完美地 ssh 进入 h1、h2、h3 和 h4 盒,并从那里进入给定基础设施中的任何其他盒。
但是,我对容器的概念(在本例中为 Docker 及其配置)非常陌生,并且才刚刚开始探索它。所以请容忍我的无知。因此,我并不完全理解上述情况下容器的整个网络配置究竟是如何完成的。
我能够从上面的 github 链接中再次从 launch.sh 脚本和 Docker 文件中得到一些理解,但不完全。
#!/bin/bash
#
# Start up the network playground on a boot2docker instance, assuming
# that "build.sh" has already been run in this directory to build the
# Docker images..
set -e -x
cd $(dirname "$0")
# If Docker has just been installed, we might need to join its group.
if ! echo "$(groups)" | grep -q docker
then
sudo adduser vagrant docker
exec newgrp docker < ./launch.sh
fi
# Make sure network tools are ready to run.
if [ ! -x /sbin/brctl ]
then
sudo apt-get -y install bridge-utils
fi
sudo mkdir -p /var/run/netns
sudo modprobe ip_nat_ftp nf_conntrack_ftp
# Tool to start a container.
start_container () {
hostname=$1
image=$2
port=$3
container=${hostname%%.*}
pid=$(docker inspect -f '{{.State.Pid}}' $container 2>/dev/null || true)
if [ "$pid" = "" ]
then
if [ -n "$port" ]
then netopts="--publish=$port:22"
else netopts="--net=none"
fi
docker run --name=$container --hostname=$hostname \
--dns=10.1.1.1 --dns-search=example.com "$netopts" \
--volume=$(readlink -f ..):/fopnp -d $image
elif [ "$pid" = "0" ]
then
docker start $container >/dev/null
else
return
fi
pid=$(docker inspect -f '{{.State.Pid}}' $container)
sudo rm -f /var/run/netns/$container
sudo ln -s /proc/$pid/ns/net /var/run/netns/$container
echo Container started: $container
}
# These commands are each a no-op if the command has already run.
start_bridge () { # args: BRIDGE_NAME
sudo brctl addbr $1 &>/dev/null || return
sudo ip link set $1 up
echo Created bridge: $1
}
give_interface_to_container () { # args: OLD_NAME CONTAINER NEW_NAME
sudo ip link set $1 netns $2
sudo ip netns exec $2 ip link set dev $1 name $3
sudo ip netns exec $2 ip link set $3 up
}
create_interface () {
#
# Given an interface name "www-eth0", create both an interface with
# that name and also a peer that is connected to it. Place the peer
# in the container "www" and give it the name "eth0" there.
#
interface=$1
container=${interface%%-*}
short_name=${interface##*-}
sudo ip link add $interface type veth peer name P &>/dev/null || return
give_interface_to_container P $container $short_name
echo Created interface: $interface
}
create_point_to_point () {
#
# Given arguments "backbone eth0 isp eth1", create a pair of peer
# interfaces and put one inside the container "backbone" and name it
# "eth0" and the other inside of "isp" with the name "eth1".
#
sudo ip netns exec $1 ip link set $2 up &>/dev/null && return
sudo ip link add P type veth peer name Q
give_interface_to_container P $1 $2
give_interface_to_container Q $3 $4
echo Created link between: $1 $3
}
bridge_add_interface () {
bridge=$1
interface=$2
sudo brctl addif $bridge $interface &>/dev/null || return
sudo ip link set dev $interface up
echo Bridged interface: $interface
}
# Build the playground.
start_container h1 fopnp/base 2201
start_container h2 fopnp/base 2202
start_container h3 fopnp/base 2203
start_container h4 fopnp/base 2204
start_container modemA fopnp/base
start_container modemB fopnp/base
start_container isp fopnp/base
start_container backbone fopnp/dns
start_container example.com fopnp/base
start_container ftp.example.com fopnp/ftp
start_container mail.example.com fopnp/mail
start_container www.example.com fopnp/www
# For each LAN, create an ethernet bridge and corresponding interfaces.
create_interface h1-eth1
create_interface h2-eth1
create_interface h3-eth1
create_interface h4-eth1
create_interface modemA-eth1
create_interface modemB-eth1
start_bridge homeA
bridge_add_interface homeA modemA-eth1
bridge_add_interface homeA h1-eth1
bridge_add_interface homeA h2-eth1
bridge_add_interface homeA h3-eth1
start_bridge homeB
bridge_add_interface homeB modemB-eth1
bridge_add_interface homeB h4-eth1
create_interface example-eth1
create_interface ftp-eth0
create_interface mail-eth0
create_interface www-eth0
start_bridge exampleCOM
bridge_add_interface exampleCOM example-eth1
bridge_add_interface exampleCOM ftp-eth0
bridge_add_interface exampleCOM mail-eth0
bridge_add_interface exampleCOM www-eth0
# The other network connections are simple point-to-point links.
create_point_to_point backbone eth0 isp eth0
create_point_to_point backbone eth1 example eth0
create_point_to_point isp eth1 modemA eth0
create_point_to_point isp eth2 modemB eth0
# Configure manual IP addresses and routes on the point-to-points.
# First, down in the direction of the broadband modems.
sudo ip netns exec backbone ip addr add 10.1.1.1/32 dev eth0
sudo ip netns exec backbone ip route add 10.25.1.1/32 dev eth0
sudo ip netns exec backbone ip route add 10.25.0.0/16 via 10.25.1.1
sudo ip netns exec isp ip addr add 10.25.1.1/32 dev eth0
sudo ip netns exec isp ip addr add 10.25.1.1/32 dev eth1
sudo ip netns exec isp ip addr add 10.25.1.1/32 dev eth2
sudo ip netns exec isp ip route add 10.1.1.1/32 dev eth0
sudo ip netns exec isp ip route add 10.25.1.65/32 dev eth1
sudo ip netns exec isp ip route add 10.25.1.66/32 dev eth2
sudo ip netns exec isp ip route add default via 10.1.1.1
# Second, down in the direction of the example.com machine room.
sudo ip netns exec backbone ip addr add 10.1.1.1/32 dev eth1
sudo ip netns exec backbone ip route add 10.130.1.1/32 dev eth1
sudo ip netns exec backbone ip route add 10.130.1.0/24 via 10.130.1.1
sudo ip netns exec example ip addr add 10.130.1.1/32 dev eth0
sudo ip netns exec example ip route add 10.1.1.1/32 dev eth0
sudo ip netns exec example ip route add default via 10.1.1.1
# Configure the LAN behind each broadband modem.
sudo ip netns exec modemA ip addr add 10.25.1.65/16 dev eth0
sudo ip netns exec modemB ip addr add 10.25.1.66/16 dev eth0
for modem in modemA modemB
do
sudo ip netns exec $modem ip addr add 192.168.1.1/24 dev eth1
sudo ip netns exec $modem ip route add default via 10.25.1.1
sudo ip netns exec $modem iptables --table nat \
--append POSTROUTING --out-interface eth0 -j MASQUERADE
done
for host in h1 h2 h3 h4
do
n=${host#?}
sudo ip netns exec $host ip route del default
sudo ip netns exec $host ip addr add 192.168.1.1$n/24 dev eth1
sudo ip netns exec $host ip route add default via 192.168.1.1
done
# Configure the 10.130.1.* network that the example.com machines share.
sudo ip netns exec example ip addr add 10.130.1.1/24 dev eth1
sudo ip netns exec ftp ip addr add 10.130.1.2/24 dev eth0
sudo ip netns exec mail ip addr add 10.130.1.3/24 dev eth0
sudo ip netns exec www ip addr add 10.130.1.4/24 dev eth0
for name in ftp mail www
do sudo ip netns exec $name ip route add default via 10.130.1.1
done
以下是我想要做的事情:
我希望我的 Ubuntu 基础机器成为同一基础架构的一部分(与 h1/h2/h3/h4 机箱之一处于同一级别),这样我就可以通过 SSH 直接访问基础架构上的所有其他机箱,也可以直接访问它们上运行的服务。例如,到目前为止,我可以从 h1/h2/h3/h4 机箱中的任何一个内部访问(例如 ping)www.example.com,但不能直接从基础 Ubuntu 机箱访问。我希望能够直接从基础 Ubuntu 机箱执行此操作,而不必先 ssh 进入 h1-h4 机箱之一然后再执行此操作。
请指教。
答案1
我认为这与 h1-h4 的 ip 子网范围有关,您可以直接 ssh 到它们,因为我假设您的 ip 也在同一范围内 (192.168.1.x)。
你可以尝试改变你知识产权到 10.130.1.x 并尝试 ssh 到其他服务器,但这样做你将无法直接 ssh 到 h1-h4,你必须通过互联网服务提供商和调制解调器或者调制解调器
答案2
有两个步骤可以使这四台主机能够h1
从h4
主主机访问:
当容器在中启动时
launch.sh
,它会被分配一个端口,通过该端口它将向主主机提供 SSH 服务,例如:start_container h1 fopnp/base 2201
该
ssh-config
文件需要包含一个别名,告诉 SSH 在访问主机名时改为连接到该端口上的本地主机:Host h1 Hostname 127.0.0.1 Port 2201
因此,为了使所有主机都以与h1
和相同的方式可用h4
,请在它们的行中为它们提供唯一的端口号start_container
,然后在 SSH 文件中为它们创建主机别名。祝你好运!