有了Openvswitch和Docker,终于可以做《TCP/IP详解》的实验了!
所有做过网络编程的程序员,想必都会看《TCP/IP详解》卷一:协议
后来出了第二版,但是由于第一版才是Rechard Stevens的原版,本人还是多次看了第一版。
对这一版印象最深的就是下面这个拓扑图
书上的很多实验,都是基于这个图做的,看了实验结果,很多理论才有真实的感觉。
看这本书的时候,不尽感慨Rechard Stevens的天赋英才,他能够利用工作中当时少于的实验环境,做了大量的实验,写出了普惠程序员的这本书。
可是除了看书中的实验结果,如何能够模拟这么一个环境,也动手测试一下呢?
可是对于大部分的同学来讲,是几乎不可能的事情,除非能够真的管理实验室或者机房。
后来有了Docker和Openvswitch,发现这个拓扑图在一个虚拟机里面就能够模拟完成。
接下来我们就看这个过程。
一、创建一个Ubuntu的VirtualBox虚拟机
里面有两张网卡,一个是NAT,用于访问公网,一个是Host-only,用于ssh进去配置。
二、安装Docker
apt-get remove docker docker-engine docker.io
apt-get update
apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg > gpg
apt-key add gpg
apt-key fingerprint 0EBFCD88
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
apt-cache madison docker-ce
apt-get install docker-ce=17.03.2~ce-0~ubuntu-xenial
三、安装Openvswitch
apt-get install openvswitch-common openvswitch-dbg openvswitch-switch python-openvswitch openvswitch-ipsec openvswitch-pki openvswitch-vtep
安装网桥
apt-get install bridge-utils
apt-get install arping
四、创建br-ex,用于gateway连接外网
在虚拟机里面找到NAT的那张网卡
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:77:d9:16 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global enp0s3
valid_lft forever preferred_lft forever
创建br-ex,将NAT网卡连接到br-ex,然后将IP地址放在br-ex上
brctl addbr br-ex
brctl addif br-ex enp0s3
ifconfig enp0s3 0
ifconfig br-ex 10.0.2.15/24
ip route add default via 10.0.2.2 dev br-ex
五、准备一个Ubuntu容器镜像
准备一个Dockerfile
FROM hub.c.163.com/public/ubuntu:14.04
RUN
apt-get -y update && apt-get install -y iproute2 iputils-arping
net-tools arping tcpdump curl telnet iputils-tracepath traceroute
ENTRYPOINT /usr/sbin/sshd -D
编译这个Dockerfile
docker build -f Dockerfile -t hub.c.163.com/liuchao110119163/ubuntu:1 .
六、创建图中所有的节点,每个一个容器
docker run --privileged=true --net none --name aix -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name solaris -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name gemini -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name gateway -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name netb -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name sun -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name svr4 -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name bsdi -d hub.c.163.com/liuchao110119163/ubuntu:1
docker run --privileged=true --net none --name slip -d hub.c.163.com/liuchao110119163/ubuntu:1
七、创建两个网桥,代表两个二层网络
ovs-vsctl add-br net1
ovs-vsctl add-br net2
八、将所有的节点连接到两个网络
在这里我们使用pipework
./pipework net1 aix 140.252.1.92/24
./pipework net1 solaris 140.252.1.32/24
./pipework net1 gemini 140.252.1.11/24
./pipework net1 gateway 140.252.1.4/24
./pipework net1 netb 140.252.1.183/24
./pipework net2 bsdi 140.252.13.35/27
./pipework net2 sun 140.252.13.33/27
./pipework net2 svr4 140.252.13.34/27
九、添加从slip到bsdi的p2p网络
创建一个peer的两个网卡
ip link add name slipside mtu 1500 type veth peer name bsdiside mtu 1500
把其中一个塞到slip的网络namespace里面
root@k8smaster:~# docker inspect '--format={{ .State.Pid }}' slip
14521
ln -s /proc/14521/ns/net /var/run/netns/14521
ip link set slipside netns 14521
把另一个塞到bsdi的网络的namespace里面
root@k8smaster:~# docker inspect '--format={{ .State.Pid }}' bsdi
14478
ln -s /proc/14478/ns/net /var/run/netns/14478
ip link set bsdiside netns 14478
给slip这面的网卡添加IP地址
docker exec -it slip ip addr add 140.252.13.65/27 dev slipside
docker exec -it slip ip link set slipside up
给bsdi这面的网卡添加IP地址
docker exec -it bsdi ip addr add 140.252.13.66/27 dev bsdiside
docker exec -it bsdi ip link set bsdiside up
如果我们仔细分析,p2p网络和下面的二层网络不是同一个网络。
p2p网络的cidr是140.252.13.64/27,而下面的二层网络的cidr是140.252.13.32/27
所以对于slip来讲,对外访问的默认网关是13.66
docker exec -it slip ip route add default via 140.252.13.66 dev slipside
而对于bsdi来讲,对外访问的默认网关13.33
docker exec -it bsdi ip route add default via 140.252.13.33 dev eth1
对于sun来讲,要想访问p2p网络,需要添加下面的路由表
docker exec -it sun ip route add 140.252.13.64/27 via 140.252.13.35 dev eth1
对于svr4来讲,对外访问的默认网关是13.33
docker exec -it svr4 ip route add default via 140.252.13.33 dev eth1
对于svr4来讲,要访问p2p网关,需要添加下面的路由表
docker exec -it svr4 ip route add 140.252.13.64/27 via 140.252.13.35 dev eth1
这个时候,从slip是可以ping的通下面的所有的节点的。
十、添加从sun到netb的点对点网络
创建一个peer的网卡对
ip link add name sunside mtu 1500 type veth peer name netbside mtu 1500
一面塞到sun的网络namespace里面
root@k8smaster:~# docker inspect '--format={{ .State.Pid }}' sun
14384
ln -s /proc/14384/ns/net /var/run/netns/14384
ip link set sunside netns 14384
另一面塞到netb的网络的namespace里面
root@k8smaster:~# docker inspect '--format={{ .State.Pid }}' netb
14336
ln -s /proc/14336/ns/net /var/run/netns/14336
ip link set netbside netns 14336
给sun里面的网卡添加地址
docker exec -it sun ip addr add 140.252.1.29/24 dev sunside
docker exec -it sun ip link set sunside up
在sun里面,对外访问的默认路由是1.4
docker exec -it sun ip route add default via 140.252.1.4 dev sunside
在netb里面,对外访问的默认路由是1.4
docker exec -it netb ip route add default via 140.252.1.4 dev eth1
在netb里面,p2p这面可以没有IP地址,但是需要配置路由规则,访问到下面的二层网络
docker exec -it netb ip link set netbside up
docker exec -it netb ip route add 140.252.1.29/32 dev netbside
docker exec -it netb ip route add 140.252.13.32/27 via 140.252.1.29 dev netbside
docker exec -it netb ip route add 140.252.13.64/27 via 140.252.1.29 dev netbside
十一、对于netb,配置arp proxy
对于netb来讲,不是一个普通的路由器,因为netb两边是同一个二层网络,所以需要配置arp proxy,将同一个二层网络隔离称为两个。
配置proxy_arp为1
docker exec -it netb bash -c "echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp"
docker exec -it netb bash -c "echo 1 > /proc/sys/net/ipv4/conf/netbside/proxy_arp"
通过一个脚本proxy-arp脚本设置arp响应
设置proxy-arp.conf
eth1 140.252.1.29
netbside 140.252.1.92
netbside 140.252.1.32
netbside 140.252.1.11
netbside 140.252.1.4
将配置文件添加到docker里面
docker cp proxy-arp.conf netb:/etc/proxy-arp.conf
docker cp proxy-arp netb:/root/proxy-arp
在docker里面执行脚本proxy-arp
docker exec -it netb bash
chmod +x proxy-arp
./proxy-arp start
十二、配置上面的二层网络里面所有机器的路由
在aix里面,默认外网访问路由是1.4
docker exec -it aix ip route add default via 140.252.1.4 dev eth1
在aix里面,可以通过下面的路由访问下面的二层网络
docker exec -it aix ip route add 140.252.13.32/27 via 140.252.1.29 dev eth1
docker exec -it aix ip route add 140.252.13.64/27 via 140.252.1.29 dev eth1
同理配置solaris
docker exec -it solaris ip route add default via 140.252.1.4 dev eth1
docker exec -it solaris ip route add 140.252.13.32/27 via 140.252.1.29 dev eth1
docker exec -it solaris ip route add 140.252.13.64/27 via 140.252.1.29 dev eth1
同理配置gemini
docker exec -it gemini ip route add default via 140.252.1.4 dev eth1
docker exec -it gemini ip route add 140.252.13.32/27 via 140.252.1.29 dev eth1
docker exec -it gemini ip route add 140.252.13.64/27 via 140.252.1.29 dev eth1
十三、在gateway里面创建一个网卡连接到br-ex
连接到br-ex用于连接外网
./pipework br-ex gateway 10.0.2.88/24@10.0.2.2
通过配置路由可以连接到下面的二层网络
docker exec -it gateway ip route add 140.252.13.32/27 via 140.252.1.29 dev eth1
docker exec -it gateway ip route add 140.252.13.64/27 via 140.252.1.29 dev eth1
到此为止,上下的二层网络都能相互访问了,并且可以访问外网。
脚本在这里https://github.com/popsuper1982/tcpipillustrated
欢迎关注个人微信公众号
有了Openvswitch和Docker,终于可以做《TCP/IP详解》的实验了!的更多相关文章
- docker 网络概述及网络模式详解
docker 网络概述及网络模式详解 1.网络概述 2.网络模式详解 1.网络概述: Docker 网络实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0) ...
- Docker 基础技术之 Linux cgroups 详解
PS:欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 推荐大家到公众号阅读,那里阅读体验更好,也沉淀了很多篇干货. 前面两篇 ...
- Sentry 监控 - 私有 Docker Compose 部署与故障排除详解
内容整理自官方开发文档 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Map ...
- linux上Docker安装gogs私服亲测(详解)
一.前言 有网友问我为什么要使用私服,可能大部分人都不是太懂,网上那么多存储仓库而且好用方便,但是你想过没有如果企业中的项目,放在人家的仓库上这个安全性不是太好,所以说一般企业都会有自己的私服.本章教 ...
- DOCKER学习_012:Dockerfile配置指令详解
1 Dockerfile结构 基础镜像信息 镜像操作指令 容器启动时执行指令 2 FROM 指定基础镜像,用于继承其他镜像使用的 FROM ubuntu:14.06 FROM centos FROM ...
- 【新技术】CentOS系统下docker的安装配置及使用详解
1 docker简介 Docker 提供了一个可以运行你的应用程序的封套(envelope),或者说容器.它原本是dotCloud 启动的一个业余项目,并在前些时候开源了.它吸引了大量的关注和讨 ...
- [转载]Docker的安装配置及使用详解
简介 官网:http://www.docker.com/,点击get started进入下载,目前三个系统的docker容器都有,Windows版需要win10系统,我的是win7系统一开始用的 ...
- Docker的安装配置及使用详解
基本概念 Docker 包括三个基本概念 镜像(Image) 容器(Container) 仓库(Repository) 先理解了这三个概念,就理解了 Docker 的整个生命周期. 1.docker安 ...
- Docker中的镜像分层技术详解
早在集装箱没有出现的时候,码头上还有许多搬运的工人在搬运货物,在集装箱出现以后,码头上看到更多的不是工人,而且集装箱的搬运模式更加单一,更加高效,还有其他的好处,比如:货物多打包在集装箱里面,可以防止 ...
随机推荐
- ASP.NET Core Razor页面禁用防伪令牌验证
在这篇短文中,我将向您介绍如何ASP.NET Core Razor页面中禁用防伪令牌验证. Razor页面是ASP.NET Core 2.0中增加的一个页面控制器框架,用于构建动态的.数据驱动的网站: ...
- 2017-07-01(ifconfig ifdown ifup netstat )
ifconfig 可以查看IP地址与子网掩码 ifdown(禁用网卡) ifdown 网络设备名 ifdown eth0 ifup (启动网卡) ifup 网络设备名 ifup eth0 net ...
- _3_form_标签
什么是input标签? 处理输入信息 input有哪些类型? 选择: <input type="checkbox"> 多选框,选择爱好等 <input type= ...
- java web response提供文件下载功能
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- awk 指定{}内x的替换
替换{}中的x为; 原字符串 oxo{axbxc}oxo{dxexf}oxo 结果 oxo{a;b;c}oxo{d;e;f}oxo awk '{for(i=1;i<=NF;i++){ ...
- python-day2数据类型
内容介绍 数据类型 字符编码 文件处理 1.什么是数据? x=10 , 10是我们要存储的数据. 2.为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3.数据类 ...
- Android开发模板代码(二)——为ImageView设置图片,退出后能保存ImageView的状态
接着之前的那个从图库选择图片,设置到ImageView中去,但是,我发现了一个问题,就是再次进入的时候ImageView是恢复到了默认状态,搜索了资料许久之后,终于是发现了解决方法,使用SharePr ...
- 6 个 Linux 运维典型问题
作为一名合格的 Linux 运维工程师,一定要有一套清晰.明确的解决故障思路,当问题出现时,才能迅速定位.解决问题,这里给出一个处理问题的一般思路: 重视报错提示信息:每个错误的出现,都是给出错误提示 ...
- WEB消息推送-框架篇
WEB消息推送-comet4j 一.comet简介: comet :基于 HTTP长连接的“服务器推”技术,是一种新的 Web 应用架构.基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程 ...
- php操作mongodb的常用函数
连接mongodb: $mongoObj = new Mongo("127.0.0.1" , array( 'connect'=>true, 'persist'=>tr ...