Linux科技

网络虚拟化技术三

2019-04-02  本文已影响0人  Miracle001

虚拟复杂网络2(不同的物理节点上)

启动两个不同的物理节点,在其上面启动虚拟机实例,不同物理服务器上的不同虚拟机通信

物理服务器A/B--两个
通过s1转发的数据到s2,不是通过e1接口发以太网帧到e2接口的,而是把e1/e2配置为GRE类型,基于GRE通用路由封装方式
2个接口之间 -- GRE隧道,GRE通用路由封装 跨越网络  
把s1的数据通过GRE通道发到s2上面
如下图

GRE: Generic Routing Encapsulation,通用路由封装: 是一种隧道技术;

vm1 vm3通信
同一个网络内--众多物理节点--可以物理桥--桥接 
不同网络内(如:不同的机房)--桥接模式不再适用--使用GRE方式

以太网帧只能在本地进行传输,但是可以借助GRE技术
把以太网帧用GRE技术封装起来
GRE工作在ip层,因此可以与另一个物理主机的ip地址建立一个虚拟的点对点的隧道
把这样的以太网帧传到另一个节点上,解封后并扔给交换机s2,类似将两个交换机直接连接起来一样
能跨越的距离取决于GRE路由协议本身所能够传输的距离

node1/2 不在同一个网络,也可以在以太网层完成本地网络通信--不深究
此处是node1和node2两个不同的节点,处于同一网络内
1
准备新的宿主机2台  node1、node2
架构图--如上图1

下面的配置和"虚拟复杂网络1"的配置相同,并且需要准备2台宿主机
centos 7.5 1804 
epel源
2g4核
允许虚拟化Intel VT-x/EPT
此处网络设置: 
  先设置为 nat+仅主机,连接外网装程序包,如下图2
    node1
      nat--192.168.25.11
      仅主机--192.168.50.11
    node2
      nat--192.168.25.12
      仅主机--192.168.50.12
    node3(最后才用,先配好)
      nat--192.168.25.13
      仅主机--192.168.50.13
  再设置为 vmnet2+仅主机,如下图3
    node1/node2/node3
      vmnet2--eth0--设置为dhcp获取的地址
      仅主机--eth1--设置为dhcp获取的地址
2 3
网络: nat+仅主机  node1/node2/node3都操作,以node1为例
[root@node1 ~]# yum clean all
[root@node1 ~]# yum repolist
[root@node1 ~]# yum info bridge-utils  qemu-kvm tcpdump dnsmasq tigervnc
    用到的只有qemu-kvm
[root@node1 ~]# yum info openvswitch*
显示有3个包: openvswitch,openvswitch-controller,openvswitch-test
    用到的只有openvswitch
[root@node1 ~]# yum -y install bridge-utils  qemu-kvm tcpdump dnsmasq tigervnc
[root@node1 ~]# yum -y install openvswitch
[root@node1 ~]# rpm -ql openvswitch
[root@node1 ~]# yum update iproute -y  为了dnsmasq的配置
关机,换网络


网络: vmnet2+仅主机  node1/node2都操作,以node1为例,此处没有node3
虚拟机的界面登录
[root@node1 ~]# cdnet
[root@node1 network-scripts]# vim ifcfg-eth1  仅主机
删除IPADDR、PREFIX、GATEWAY,修改BOOTPROTO为dhcp,其他不变
[root@node1 network-scripts]# vim ifcfg-eth0  vmnet2模式
删除IPADDR、PREFIX、GATEWAY、DNS1、DNS2,修改BOOTPROTO为dhcp,其他不变
[root@node1 network-scripts]# systemctl restart network
[root@node1 network-scripts]# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.75.133  netmask 255.255.255.0  broadcast 192.168.75.255
...  ...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.50.135  netmask 255.255.255.0  broadcast 192.168.50.255
[root@node2 ~]# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.75.132  netmask 255.255.255.0  broadcast 192.168.75.255
...  ...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.50.134  netmask 255.255.255.0  broadcast 192.168.50.255


在xshell上面连接服务器  
[c:\~]$ ssh root@192.168.50.135  需要等一会,然后提示输入密码 node1登录
[c:\~]$ ssh root@192.168.50.134  node2登录

接下来--node1/node2都操作,以node1为例
[root@node1 ~]# systemctl start openvswitch
[root@node1 ~]# systemctl status openvswitch
[root@node1 ~]# vim /etc/sysctl.conf 
net.ipv4.ip_forward = 1
[root@node1 ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@node1 ~]# modprobe kvm
[root@node1 ~]# lsmod |grep kvm
kvm_intel             174841  0 
kvm                   578518  1 kvm_intel
irqbypass              13503  1 kvm
[root@node1 ~]# ovs-vsctl add-br br-in
注意node2上添加相同的br-in,两个是在不同主机上,不冲突
[root@node2 ~]# ovs-vsctl add-br br-in  
[root@node1 ~]# ovs-vsctl show
bf86462d-f265-4a16-8519-670b957e1f1b
    Bridge br-in
        Port br-in
            Interface br-in
                type: internal
    ovs_version: "2.0.0"
[root@node1 ~]# ln -sv /usr/libexec/qemu-kvm /usr/bin/  命令加入到PATH路径里面
[root@node1 ~]# mkdir -pv /vm/images
[root@node1 ~]# cd /vm/images
[root@node1 images]# rz  上传镜像cirros-0.3.6-i386-disk.img
[root@node1 images]# cp cirros-0.3.6-i386-disk.img vm1.img
[root@node1 images]# cp cirros-0.3.6-i386-disk.img vm2.img
注意node2上,复制镜像名称为vm3/vm4,便于区分
[root@node2 images]# cp cirros-0.3.6-i386-disk.img vm3.img
[root@node2 images]# cp cirros-0.3.6-i386-disk.img vm4.img

node1/node2都操作,以node1为例
编辑kvm虚拟机启动脚本
[root@node1 images]# vim /etc/if-up
#!/bin/bash
#
bridge='br-in'

if [ -n "$1" ];then
        ip link set $1 up
        sleep 1
#       brctl addif $bridge $1
        ovs-vsctl add-port $bridge $1
        [ $? -eq 0 ] && exit 0 || exit 1
else
#       echo "Error: no interface specified."
        echo "Error: no port specified."
        exit 2
fi
[root@node1 images]# chmod +x /etc/if-up
[root@node1 images]# bash -n /etc/if-up
编辑kvm虚拟机down脚本
[root@node1 images]# vim /etc/if-down
#!/bin/bash
#
bridge='br-in'

if [ -n "$1" ];then
        ip link set $1 down
        sleep 1
#       brctl addif $bridge $1
        ovs-vsctl del-port $bridge $1
        [ $? -eq 0 ] && exit 0 || exit 1
else
#       echo "Error: no interface specified."
        echo "Error: no port specified."
        exit 2
fi
[root@node1 images]# chmod +x /etc/if-down
[root@node1 images]# bash -n /etc/if-down


启动虚拟机实例时,让实例自动获取地址,配置dnsmasq
在node1上配置dnsmasq
# 先配置一个名称空间r0
[root@node1 ~]# ip netns add r0
[root@node1 ~]# ip netns list
r0
# 再创建一对网络接口,一半在br-in 一半在r0(路由器)
[root@node1 ~]# ip link add sif0 type veth peer name rif0
  sif0--不需要地址--关联到交换机br-in(s1)上
  rif0--需要有地址--放到网络名称空间r0上
[root@node1 ~]# ip link set sif0 up
[root@node1 ~]# ip link set rif0 up
  此处直接激活sif0
  rif0可以暂不激活,即使激活也没用,需要先添加到r0上,再激活
# sif0关联到br-in上
[root@node1 ~]# ovs-vsctl add-port br-in sif0
[root@node1 ~]# ovs-vsctl show 
bf86462d-f265-4a16-8519-670b957e1f1b
    Bridge br-in
        Port "sif0"
            Interface "sif0"
        Port br-in
            Interface br-in
                type: internal
    ovs_version: "2.0.0"
# rif0关联到r0上,并激活
[root@node1 ~]# ip link set rif0 netns r0
[root@node1 ~]# ip netns exec r0 ip link set rif0 up
[root@node1 ~]# ip netns exec r0 ifconfig
# node1-r0上配置dns
[root@node1 ~]# ip netns exec r0 ip addr add 10.0.4.254/24 dev rif0
[root@node1 ~]# ip netns exec r0 ifconfig  添加地址成功
  或者执行: ip netns exec r0 ip addr list
rif0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.4.254  netmask 255.255.255.0  broadcast 0.0.0.0
...  ...
    如果是添加地址错误,可以删除再添加
    ip netns exec r0 ip addr flush dev rif0
    ip netns exec r0 ip addr list
# 添加dnsmasq的地址池并启动服务
[root@node1 ~]# ip netns exec r0 dnsmasq -F 10.0.4.201,10.0.4.220,86400 -i rif0
[root@node1 ~]# ip netns exec r0 ps aux|grep dnsmasq  进程显示dnsmasq启动
nobody     7282  0.0  0.0  53856  1108 ?        S    11:23   0:00 dnsmasq -F 10.0.4.201,10.0.4.220,86400 -i rif0
root       7294  0.0  0.0 112704   972 pts/1    S+   11:24   0:00 grep --color=auto dnsmasq
[root@node1 ~]# ip netns exec r0 ss -unl|grep 67  67号端口监听--可以提供dns服务
UNCONN     0      0            *:67                       *:*                  

node1启动虚拟机实例vm1
[root@node1 ~]# qemu-kvm -name "vm1" -m 128 -smp 2 -drive file=/vm/images/vm1.img,if=virtio,media=disk -net nic,model=virtio,macaddr=52:54:00:00:00:01 -net tap,ifname=fgq1,script=/etc/if-up,downscript=/etc/if-down --nographic
输入默认账号和密码
$ sudo su -
# ifconfig  显示ip地址自动获取,dnsmasq配置成功
eth0      Link encap:Ethernet  HWaddr 52:54:00:00:00:01  
          inet addr:10.0.4.216  Bcast:10.0.4.255  Mask:255.255.255.0
node2启动虚拟机实例vm3
[root@node2 ~]# qemu-kvm -name "vm3" -m 128 -smp 2 -drive file=/vm/images/vm3.img,if=virtio,media=disk -net nic,model=virtio,macaddr=52:54:00:00:00:03 -net tap,ifname=fgq3,script=/etc/if-up,downscript=/etc/if-down --nographic
输入默认账号和密码
$ sudo su -
# ifconfig  此处的ip地址不会自动获取
eth0      Link encap:Ethernet  HWaddr 52:54:00:00:00:03  
          inet6 addr: fe80::5054:ff:fe00:3/64 Scope:Link
此时的node1、node2无法通信

[root@node2 ~]# ovs-vsctl show
81b68126-b653-4695-8372-2c82bf9479d0
    Bridge br-in
        Port br-in
            Interface br-in
                type: internal
        Port "fgq3"
            Interface "fgq3"
    ovs_version: "2.0.0"
此处只是把vm3上的网卡fgq3添加到交换机br-in(桥-s2)上,node1和node2是不会通信的

现在把接口e1和e2激活,并配置地址,变成GRE通道来使node1和node2通信
此处就不用激活了,因为e1对应node1的eth0,e2对应node2的eth0
二者都是vmnet2模式,都使用dhcp获得地址了
注意: 
一定不能把接口e1/e2添加到桥s1/s2上,因为e1/e2是为了实现隧道功能,必须作为独立接口使用
s1/s2桥只能借助于e1/e2接口来完成隧道协议封装

[root@node1 ~]# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.75.133  netmask 255.255.255.0  broadcast 192.168.75.255
[root@node2 ~]# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.75.132  netmask 255.255.255.0  broadcast 192.168.75.255
# node1的eth0与node2的eth0可以互相ping通
[root@node1 ~]# ping 192.168.75.132
PING 192.168.75.132 (192.168.75.132) 56(84) bytes of data.
64 bytes from 192.168.75.132: icmp_seq=1 ttl=64 time=0.778 ms
[root@node2 ~]# ping 192.168.75.133
PING 192.168.75.133 (192.168.75.133) 56(84) bytes of data.
64 bytes from 192.168.75.133: icmp_seq=1 ttl=64 time=0.422 ms


e1/e2--不在同一个网络(网段)中,也可以通信,中间加一个路由,确保e1可以与e2互相ping通即可
现在想让 vm1与vm3 像在类似一个局域网内通信,让接口e1/e2承载其隧道协议的封装
两边的交换机s1/s2上各自添加一个端口,设置port的值为GRE或者接口类型为gre类型
# 在node1的虚拟交换机s1(br-in)上添加一个端口gre0
[root@node1 ~]# ovs-vsctl add-port br-in gre0
[root@node1 ~]# ovs-vsctl show
bf86462d-f265-4a16-8519-670b957e1f1b
    Bridge br-in
        Port "sif0"
            Interface "sif0"
        Port "gre0"
            Interface "gre0"
        Port br-in
            Interface br-in
                type: internal
        Port "fgq1"
            Interface "fgq1"
    ovs_version: "2.0.0"
[root@node1 ~]# ovs-vsctl list port
# 设置interface的属性
[root@node1 ~]# ovs-vsctl list interface gre0
_uuid               : 29bb0772-1c2d-4d6e-9b27-bf26c559f754
admin_state         : []
bfd                 : {}
bfd_status          : {}
cfm_fault           : []
cfm_fault_status    : []
cfm_health          : []
cfm_mpid            : []
cfm_remote_mpids    : []
cfm_remote_opstate  : []
duplex              : []
external_ids        : {}
ifindex             : []
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current        : []
link_resets         : []
link_speed          : []
link_state          : []
mac                 : []
mac_in_use          : []
mtu                 : []
name                : "gre0"
ofport              : -1
ofport_request      : []
options             : {}
other_config        : {}
statistics          : {}
status              : {}
type                : ""
  type为空,默认为eth类型
# 现在设置type为GRE,设置option--对端虚拟节点是另外一个节点的值
  本机是192.168.75.133--对端是192.168.75.132
[root@node1 ~]# ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.75.132
[root@node1 ~]# ovs-vsctl list interface gre0
_uuid               : 29bb0772-1c2d-4d6e-9b27-bf26c559f754
admin_state         : up
bfd                 : {}
bfd_status          : {}
cfm_fault           : []
cfm_fault_status    : []
cfm_health          : []
cfm_mpid            : []
cfm_remote_mpids    : []
cfm_remote_opstate  : []
duplex              : []
external_ids        : {}
ifindex             : 0
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current        : []
link_resets         : 0
link_speed          : []
link_state          : up
mac                 : []
mac_in_use          : "12:71:6e:71:57:d8"
mtu                 : []
name                : "gre0"
ofport              : 4
ofport_request      : []
options             : {remote_ip="192.168.75.132"}
other_config        : {}
statistics          : {collisions=0, rx_bytes=0, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=0, tx_bytes=0, tx_dropped=0, tx_errors=0, tx_packets=0}
status              : {tunnel_egress_iface="eth0", tunnel_egress_iface_carrier=up}
type                : gre
statistics显示数据,status 开启隧道,表明隧道功能已经开启

同理在node2上操作添加端口gre0
# 在node2的虚拟交换机s2(br-in)上添加一个端口gre0
[root@node2 ~]# ovs-vsctl add-port br-in gre0 -- set interface gre0 type=gre options:remote_ip=192.168.75.133
    ovs-vsctl  后面加 -- 可以添加多个要执行的命令
    options:remote_ip=192.168.75.133  注意此处是对端node1-eth0地址
[root@node2 ~]# ovs-vsctl show
81b68126-b653-4695-8372-2c82bf9479d0
    Bridge br-in
        Port "fgq3"
            Interface "fgq3"
        Port br-in
            Interface br-in
                type: internal
        Port "gre0"
            Interface "gre0"
                type: gre
                options: {remote_ip="192.168.75.133"}
    ovs_version: "2.0.0"
[root@node2 ~]# ovs-vsctl list interface gre0  列出这张表的信息

现把node2上面的vm3kill掉,然后再次启动,看是否可以成功获取node1上的r0-dhcp服务分配的ip地址
[root@node2 ~]# ps aux|grep qemu-kvm
root       7726  0.4 11.3 940948 210916 pts/2   Sl+  14:13   0:13 qemu-kvm -name vm3 -m 128 -smp 2 -drive file=/vm/images/vm3.img,if=virtio,media=disk -net nic,model=virtio,macaddr=52:54:00:00:00:03 -net tap,ifname=fgq3,script=/etc/if-up,downscript=/etc/if-down --nographic
root       8672  0.0  0.0 112708   972 pts/3    S+   15:06   0:00 grep --color=auto qemu-kvm
[root@node2 ~]# kill 7726
[root@node2 ~]# qemu-kvm -name "vm3" -m 128 -smp 2 -drive file=/vm/images/vm3.img,if=virtio,media=disk -net nic,model=virtio,macaddr=52:54:00:00:00:03 -net tap,ifname=fgq3,script=/etc/if-up,downscript=/etc/if-down --nographic
输入账号和密码
$ sudo su -
# ifconfig  
eth0      Link encap:Ethernet  HWaddr 52:54:00:00:00:03  
          inet addr:10.0.4.218  Bcast:10.0.4.255  Mask:255.255.255.0
    可以看到vm3可以获取dhcp分配的地址,表明 vm1与vm3 二者现在处于同一个局域网中
node1-vm1与node2-vm3可以互相ping通
vm1
# ping 10.0.4.218
PING 10.0.4.218 (10.0.4.218): 56 data bytes
64 bytes from 10.0.4.218: seq=0 ttl=64 time=2.752 ms
vm3
# ping 10.0.4.216
PING 10.0.4.216 (10.0.4.216): 56 data bytes
64 bytes from 10.0.4.216: seq=0 ttl=64 time=6.084 ms

# 抓包查看,表明--没有物理桥,借助GRE隧道可以通信
[root@node1 ~]# tcpdump -i eth0 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:17:28.754549 IP 192.168.75.133 > 192.168.75.132: GREv0, length 102: IP 10.0.4.216 > 10.0.4.218: ICMP echo request, id 27905, seq 17, length 64
15:17:28.755952 IP 192.168.75.132 > 192.168.75.133: GREv0, length 102: IP 10.0.4.218 > 10.0.4.216: ICMP echo reply, id 27905, seq 17, length 64
现在再启动node1-vm2/node2-vm4两个虚拟机
node1--vm1 vm2
node2--vm3 vm4
vm1与vm3 能通信
vm2与vm4 能通信
并且都在同一网段中的  vm1与vm2--不能通信 vm3与vm4--不能通信
想要达到上面的效果,需要设置:
vm1与vm3--在同一vlan中,vm2与vm4--在另外一个vlan中

node1上启动vm2,自动获取地址
[root@node1 ~]# qemu-kvm -name "vm2" -m 128 -smp 2 -drive file=/vm/images/vm2.img,if=virtio,media=disk -net nic,model=virtio,macaddr=52:54:00:00:00:02 -net tap,ifname=fgq2,script=/etc/if-up,downscript=/etc/if-down --nographic
输入账号和密码
$ sudo su -
# ifconfig 
eth0      Link encap:Ethernet  HWaddr 52:54:00:00:00:02  
          inet addr:10.0.4.217  Bcast:10.0.4.255  Mask:255.255.255.0
node2上启动vm4,自动获取地址,并且可以ping通vm1/vm2/vm3
[root@node2 ~]# qemu-kvm -name "vm4" -m 128 -smp 2 -drive file=/vm/images/vm4.img,if=virtio,media=disk -net nic,model=virtio,macaddr=52:54:00:00:00:04 -net tap,ifname=fgq4,script=/etc/if-up,downscript=/etc/if-down --nographic
输入账号和密码
$ sudo su -
# ifconfig 
eth0      Link encap:Ethernet  HWaddr 52:54:00:00:00:04  
          inet addr:10.0.4.219  Bcast:10.0.4.255  Mask:255.255.255.0
# ping 10.0.4.216  vm4-ping-vm1
PING 10.0.4.216 (10.0.4.216): 56 data bytes
64 bytes from 10.0.4.216: seq=0 ttl=64 time=4.915 ms
# ping 10.0.4.217  vm4-ping-vm2
PING 10.0.4.217 (10.0.4.217): 56 data bytes
64 bytes from 10.0.4.217: seq=0 ttl=64 time=5.120 ms
# ping 10.0.4.218  vm4-ping-vm3
PING 10.0.4.218 (10.0.4.218): 56 data bytes
64 bytes from 10.0.4.218: seq=0 ttl=64 time=3.432 ms


vm1 vm2 不能通信
vm3 vm4 不能通信
vm1 vm3  在同一vlan中
vm2 vm4  在另一vlan中
# 设置fgq1的vlan-id为10,fgq2的vlan-id为20
[root@node1 ~]# ovs-vsctl show
bf86462d-f265-4a16-8519-670b957e1f1b
    Bridge br-in
        Port "sif0"
            Interface "sif0"
        Port "gre0"
            Interface "gre0"
                type: gre
                options: {remote_ip="192.168.75.132"}
        Port "fgq2"
            Interface "fgq2"
        Port br-in
            Interface br-in
                type: internal
        Port "fgq1"
            Interface "fgq1"
    ovs_version: "2.0.0"
[root@node1 ~]# ovs-vsctl set port fgq1 tag=10 -- set port fgq2 tag=20
[root@node1 ~]# ovs-vsctl list port fgq1
[root@node1 ~]# ovs-vsctl list port fgq2

在node2的vm4上去ping-vm1/vm2
# ping 10.0.4.216  不通
PING 10.0.4.216 (10.0.4.216): 56 data bytes
# ping 10.0.4.217  不通
PING 10.0.4.216 (10.0.4.216): 56 data bytes

# 设置fgq3的vlan-id为10,fgq4的vlan-id为20
[root@node2 ~]# ovs-vsctl show
81b68126-b653-4695-8372-2c82bf9479d0
    Bridge br-in
        Port "fgq4"
            Interface "fgq4"
        Port "fgq3"
            Interface "fgq3"
        Port br-in
            Interface br-in
                type: internal
        Port "gre0"
            Interface "gre0"
                type: gre
                options: {remote_ip="192.168.75.133"}
    ovs_version: "2.0.0"
[root@node2 ~]# ovs-vsctl set port fgq3 tag=10 -- set port fgq4 tag=20
[root@node2 ~]# ovs-vsctl list port fgq3
[root@node2 ~]# ovs-vsctl list port fgq4

在node2的vm4上
去ping-vm1/vm3,是ping不通的,因为vlan-id不一样
去ping-vm2,可以ping通的,因为vlan-id相同
# ping 10.0.4.216  不通
PING 10.0.4.216 (10.0.4.216): 56 data bytes
# ping 10.0.4.218  不通
PING 10.0.4.216 (10.0.4.216): 56 data bytes
# ping 10.0.4.217  通
PING 10.0.4.217 (10.0.4.217): 56 data bytes
64 bytes from 10.0.4.217: seq=0 ttl=64 time=4.312 ms

---------------------------------------------------------------------------
---------------------------------------------------------------------------

接下来把GRE通道删除,更改为vxlan
vxlan 支持vlan且数量很大,支持隧道功能--类似GRE功能
删除GRE之前,先删除fgq1/2/3/4上面的tag,以便可以互相ping通
[root@node1 ~]# ovs-vsctl remove port fgq1 tag 10
[root@node1 ~]# ovs-vsctl remove port fgq2 tag 20
[root@node1 ~]# ovs-vsctl list port fgq1
[root@node1 ~]# ovs-vsctl list port fgq2
[root@node2 ~]# ovs-vsctl remove port fgq3 tag 10
[root@node2 ~]# ovs-vsctl remove port fgq4 tag 20
[root@node2 ~]# ovs-vsctl list port fgq3
[root@node2 ~]# ovs-vsctl list port fgq4
vm1/2/3/4可以互相ping通

移除GRE
[root@node1 ~]# ovs-vsctl del-port br-in gre0
[root@node1 ~]# ovs-vsctl show  没有gre0了
[root@node1 ~]# ovs-vsctl show
bf86462d-f265-4a16-8519-670b957e1f1b
    Bridge br-in
        Port "sif0"
            Interface "sif0"
        Port "fgq2"
            Interface "fgq2"
        Port br-in
            Interface br-in
                type: internal
        Port "fgq1"
            Interface "fgq1"
    ovs_version: "2.0.0"
[root@node2 ~]# ovs-vsctl del-port br-in gre0
[root@node2 ~]# ovs-vsctl show  没有gre0了
[root@node2 ~]# ovs-vsctl show
81b68126-b653-4695-8372-2c82bf9479d0
    Bridge br-in
        Port "fgq4"
            Interface "fgq4"
        Port "fgq3"
            Interface "fgq3"
        Port br-in
            Interface br-in
                type: internal
    ovs_version: "2.0.0"
此时vm4去ping-vm1/vm2是ping不通的,只能ping通同属于一个网络内的vm3

node1的br-in(虚拟交换机s1)上添加vxlan-vx0
[root@node1 ~]# ovs-vsctl add-port br-in vx0 -- set interface vx0 type=vxlan options:remote_ip=192.168.75.132
[root@node1 ~]# ovs-vsctl list port vx0
[root@node1 ~]# ovs-vsctl list interface vx0
_uuid               : 903cbf86-1eee-4298-b251-a2566afa83b1
admin_state         : up
bfd                 : {}
bfd_status          : {}
cfm_fault           : []
cfm_fault_status    : []
cfm_health          : []
cfm_mpid            : []
cfm_remote_mpids    : []
cfm_remote_opstate  : []
duplex              : []
external_ids        : {}
ifindex             : 0
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current        : []
link_resets         : 0
link_speed          : []
link_state          : up
mac                 : []
mac_in_use          : "ee:dc:4a:fb:46:bc"
mtu                 : []
name                : "vx0"
ofport              : 6
ofport_request      : []
options             : {remote_ip="192.168.75.132"}
other_config        : {}
statistics          : {collisions=0, rx_bytes=0, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=0, tx_bytes=0, tx_dropped=0, tx_errors=0, tx_packets=0}
status              : {tunnel_egress_iface="eth0", tunnel_egress_iface_carrier=up}
type                : vxlan

node2的br-in(虚拟交换机s2)上添加vxlan-vx0
[root@node2 ~]# ovs-vsctl add-port br-in vx0 -- set interface vx0 type=vxlan options:remote_ip=192.168.75.133
[root@node2 ~]# ovs-vsctl list interface vx0
_uuid               : 5e2d994d-df0a-487a-855e-cf7599763cae
admin_state         : up
bfd                 : {}
bfd_status          : {}
cfm_fault           : []
cfm_fault_status    : []
cfm_health          : []
cfm_mpid            : []
cfm_remote_mpids    : []
cfm_remote_opstate  : []
duplex              : []
external_ids        : {}
ifindex             : 0
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current        : []
link_resets         : 0
link_speed          : []
link_state          : up
mac                 : []
mac_in_use          : "0a:32:46:c8:08:f4"
mtu                 : []
name                : "vx0"
ofport              : 6
ofport_request      : []
options             : {remote_ip="192.168.75.133"}
other_config        : {}
statistics          : {collisions=0, rx_bytes=0, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=0, tx_bytes=0, tx_dropped=0, tx_errors=0, tx_packets=0}
status              : {tunnel_egress_iface="eth0", tunnel_egress_iface_carrier=up}
type                : vxlan

node1的vm1上去ping-vm2/vm3/vm4,可以互相ping通
# ping 10.0.4.217  OK
# ping 10.0.4.218  OK  一直ping着,等测试抓包
# ping 10.0.4.219  OK
抓包测试,有来有回
[root@node1 ~]# tcpdump -i eth0 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:42:57.697730 IP 192.168.75.133.51602 > 192.168.75.132.4789: VXLAN, flags [I] (0x08), vni 0
IP 10.0.4.216 > 10.0.4.218: ICMP echo request, id 29441, seq 31, length 64
17:42:57.699375 IP 192.168.75.132.34708 > 192.168.75.133.4789: VXLAN, flags [I] (0x08), vni 0
IP 10.0.4.218 > 10.0.4.216: ICMP echo reply, id 29441, seq 31, length 64

现在删除node1和node2上的vxlan,为下面的网络做准备
node1/node2 拆除vxlan
[root@node1 ~]# ovs-vsctl del-port br-in vx0
[root@node1 ~]# ovs-vsctl show
[root@node2 ~]# ovs-vsctl del-port br-in vx0
[root@node2 ~]# ovs-vsctl show
此时node1的vm1上去ping-vm2可以通,去ping-vm3/vm4,不能ping通
# ping 10.0.4.217  OK
# ping 10.0.4.218  no
# ping 10.0.4.219  no

虚拟复杂网络3(3个不同的物理节点)

1 2 3
假如 A与B建立的通信,不是直接建立,而是通过C间接建立关系
A可以与C连接,基于vxlan或GRE
vm1 可以通过e4接口访问互联网  如何操作
    C物理节点需要有一个ovs的虚拟交换机s3
    vm1的报文 通过s1 可以传到s3上面
    将物理网卡e4直接添加到桥s3上,桥接方式,vm1直接通过e4连接外网,不安全
    如上图1
或者构建一个netns
    创建一组接口,一半在netns上,一半在s3上
    再创建一组接口,一半在netns上,一半在本地local上
    如上图2
或者在上面的netns的基础上,再创建一个交换机s4,把e4放到s4上面
    在netns上面添加路由/net规则
    在netns上添加snat规则,为了外网的数据能够返回给vm1
要想外部访问内部的某个虚拟机如vm1,还需要在natns上加一个flowting-ip
对外部访问flowting-ip的请求统统映射到内部的某个vm
    外部访问flowting-ip的请求--是可以到达的,因为交换机s4、e4,都是在2层
过程: request-->e4-->flowting-ip-->dnat规则-->交换机隧道-->vm1
如上图3
node3的3个接口--GRE通信、管理节点通信、外部网络通信
node1不和node2建立GRE,要和node3建立GRE

node3
安装ovs包
虚拟交换机--物理桥s3
物理名称空间netns
把物理桥e4添加到物理名称空间netns上,并给其一个能和外部网络通信的地址,跨主机映射,访问内部vm

s3--ovs-vsctl格式的桥
s4--brctl格式的桥 物理桥

创建s3的桥br-in
创建netns,且上面有两个网卡,一个加到物理桥s4上,另外一个关联到内部的ovs桥-s3上去
ovs桥-s3要set port 与s1建立GRE通道


node3--C物理节点
2g4核
vmnet2--eth0--192.168.75.x--dhcp获取的地址
仅主机--eth1--192.168.50.x--xshell--dhcp获取的地址
前面已经配置好了vment2和仅主机,相关程序包已经安装完成
    不需要装qemu-kvm 不需要启动虚拟机
现在需要重新添加一块网卡eth2--连接外网--如上图所示
nat--192.168.25.x--eth2--此处直接把eth2放到桥br-ex(s4)上--详情看配置

node3节点网络配置
[root@node3 ~]# cdnet
[root@node3 network-scripts]# vim ifcfg-eth1  仅主机
删除IPADDR、PREFIX、GATEWAY,修改BOOTPROTO为dhcp,其他不变
[root@node3 network-scripts]# vim ifcfg-eth0  vmnet2模式
删除IPADDR、PREFIX、GATEWAY、DNS1、DNS2,修改BOOTPROTO为dhcp,其他不变
[root@node3 network-scripts]# vim ifcfg-eth2  自己写一个新文件
DEVICE="eth2"
BOOTPROTO="static"
ONBOOT="yes"
NM_CONTROLLED=no
BRIDGE=br-ex
[root@node3 network-scripts]# vim ifcfg-br-ex 
DEVICE="br-ex"
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.25.13
PREFIX=24
GATEWAY=192.168.25.2
DNS1=114.114.114.114
DNS2=8.8.8.8
NM_CONTROLLED=no
TYPE=Bridge
[root@node3 network-scripts]# systemctl restart network

[root@node3 network-scripts]# ifconfig 
br-ex: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.25.13  netmask 255.255.255.0  broadcast 192.168.25.255
        inet6 fe80::20c:29ff:fe14:5283  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:14:52:83  txqueuelen 1000  (Ethernet)
...  ...
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.75.134  netmask 255.255.255.0  broadcast 192.168.75.255
        inet6 fe80::2212:ad79:718c:c015  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:14:52:6f  txqueuelen 1000  (Ethernet)
...  ...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.50.130  netmask 255.255.255.0  broadcast 192.168.50.255
        inet6 fe80::f0ff:4c20:13aa:a2e3  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:14:52:79  txqueuelen 1000  (Ethernet)
...  ...
eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::20c:29ff:fe14:5283  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:14:52:83  txqueuelen 1000  (Ethernet)
...  ...

在xshell上面连接node3服务器  
[c:\~]$ ssh root@192.168.50.130  node3
[root@node3 ~]# systemctl start openvswitch
[root@node3 ~]# systemctl status openvswitch
[root@node3 ~]# vim /etc/sysctl.conf 
net.ipv4.ip_forward = 1
[root@node3 ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@node3 ~]# modprobe kvm
[root@node3 ~]# lsmod |grep kvm
kvm_intel             174841  0 
kvm                   578518  1 kvm_intel
irqbypass              13503  1 kvm

添加内部桥br-in(s3交换机)
[root@node3 ~]# ovs-vsctl add-br br-in
[root@node3 ~]# ovs-vsctl show
521a430d-850e-4cd1-89d7-cf6480afd198
    Bridge br-in
        Port br-in
            Interface br-in
                type: internal
    ovs_version: "2.0.0"
    此处没有br-ex,因为它不是ovs-vsctl创建的

让node1与node3以GRE方式通信,不用vxlan,效果是相同的
node1操作
# 创建ovs桥,设置GRE
[root@node1 ~]# ovs-vsctl add-port br-in gre0
[root@node1 ~]# ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.75.134
[root@node1 ~]# ping 192.168.75.134
PING 192.168.75.134 (192.168.75.134) 56(84) bytes of data.
64 bytes from 192.168.75.134: icmp_seq=1 ttl=64 time=0.625 ms

node3操作
# 创建ovs桥,设置GRE
[root@node3 ~]# ovs-vsctl add-port br-in gre0 -- set interface gre0 type=gre options:remote_ip=192.168.75.133

node3上创建网络名称空间netns,且创建两对网卡--连接两个交换机s3/s4,并且起到路由功能
# 创建网络名称空间 r1
[root@node3 ~]# ip netns add r1
[root@node3 ~]# ip netns list
r1
br-in  br-ex  连接这两个桥
[root@node3 ~]# ip link add sin0 type veth peer name rin0
[root@node3 ~]# ip link add sex0 type veth peer name rex0

关联到桥上并激活
[root@node3 ~]# ip link set sin0 up
[root@node3 ~]# ip link set sex0 up
# 把sin0放到桥s3上
[root@node3 ~]# ovs-vsctl add-port br-in sin0

关联到路由器上(名称空间上)的先不激活,等到加进路由器上再激活
[root@node3 ~]# ip link set rin0 netns r1
[root@node3 ~]# ip link set rex0 netns r1

把rex0放到名称空间netns(r1)上
[root@node3 ~]# ip netns exec r1 ifconfig -a  有rex0 rin0
# 配置地址
[root@node3 ~]# ip netns exec r1 ifconfig rin0 10.0.4.100/24 up
[root@node3 ~]# ip netns exec r1 ifconfig
rin0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.4.100  netmask 255.255.255.0  broadcast 10.0.4.255
[root@node3 ~]# ip netns exec r1 ping 10.0.4.216  可以ping通vm1
PING 10.0.4.216 (10.0.4.216) 56(84) bytes of data.
64 bytes from 10.0.4.216: icmp_seq=1 ttl=64 time=2.88 ms
此处要一直ping着,后面抓包用
表明: GRE隧道没问题,rin0(r1)-->sin0(s3桥)-->s1桥--vm1

node1上抓包查看
[root@node1 ~]# tcpdump -i eth0 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:02:44.824034 IP 192.168.75.134 > 192.168.75.133: GREv0, length 102: IP 10.0.4.100 > 10.0.4.216: ICMP echo request, id 4412, seq 1, length 64
18:02:44.825219 IP 192.168.75.133 > 192.168.75.134: GREv0, length 102: IP 10.0.4.216 > 10.0.4.100: ICMP echo reply, id 4412, seq 1, length 64


把另外一半 关联到s4桥br-ex上
把sex0接口添加到br-ex桥上--即:sex0关联到物理桥上
[root@node3 ~]# brctl addif br-ex sex0   sex0不需要配置地址
[root@node3 ~]# ip netns exec r1 ifconfig -a
# 给rex0配置nat地址
[root@node3 ~]# ip netns exec r1 ifconfig rex0 192.168.25.100/24 up
[root@node3 ~]# ip netns exec r1 ifconfig
rex0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.25.100  netmask 255.255.255.0  broadcast 192.168.25.255
# r1--ping 网关可以通
[root@node3 ~]# ip netns exec r1 ping 192.168.25.2
PING 192.168.25.2 (192.168.25.2) 56(84) bytes of data.
64 bytes from 192.168.25.2: icmp_seq=1 ttl=128 time=0.252 ms
64 bytes from 192.168.25.2: icmp_seq=2 ttl=128 time=0.445 ms

打开路由间核心转发(之前编辑文件/etc/sysctl.conf也可以)
[root@node3 ~]# ip netns exec r1 sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1


node1的vm1虚拟机
配置vm1的网关为 node3--r1内部接口--rin0的ip
# route add default gw 10.0.4.100
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.4.100      0.0.0.0         UG    0      0        0 eth0
0.0.0.0         10.0.4.254      0.0.0.0         UG    0      0        0 eth0
10.0.4.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
# ping 192.168.25.100
PING 192.168.25.100 (192.168.25.100): 56 data bytes
64 bytes from 192.168.25.100: seq=0 ttl=64 time=4.090 ms
64 bytes from 192.168.25.100: seq=1 ttl=64 time=1.206 ms
表明node1--vm1可以ping通路由器--r1的外部接口rex0
# ping 192.168.25.2    不能ping通外部网络--网关
PING 192.168.25.2 (192.168.25.2): 56 data bytes


node3的r1上加snat规则
[root@node3 ~]# ip netns exec r1 iptables -t nat -A POSTROUTING -s 10.0.4.0/24 -j SNAT --to-source 192.168.25.100
node1-vm1再ping,可以通
# ping 192.168.25.2
PING 192.168.25.2 (192.168.25.2): 56 data bytes
64 bytes from 192.168.25.2: seq=0 ttl=127 time=3.370 ms


现在期望内部主机可以被外部网络访问,flowting-ip 如何实现
先把iptables规则删除
node3
[root@node3 ~]# ip netns exec r1 iptables -t nat -F
[root@node3 ~]# ip netns exec r1 iptables -t nat -L -n
# 在名称空间内添加一个网卡并给予其地址
[root@node3 ~]# ip netns exec r1 ifconfig rex0:0 192.168.25.101/24 up
[root@node3 ~]# ip netns exec r1 ifconfig
rex0:0: flags=4163 UP,BROADCAST,RUNNING,MULTICAST  mtu 1500
        inet 192.168.25.101  netmask 255.255.255.0  broadcast 192.168.25.255

Windows上的cmd命令里面或者xshell上
[c:\~]$ ping 192.168.25.101
正在 Ping 192.168.25.101 具有 32 字节的数据:
来自 192.168.25.101 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.25.101 的回复: 字节=32 时间<1ms TTL=64
外部可以ping通node3-r1-rex0:0网卡上


node3
内部10.0.4.216的访问---都会sant到192.168.25.101上
[root@node3 ~]# ip netns exec r1 iptables -t nat -A POSTROUTING -s 10.0.4.216/32 -j SNAT --to-source 192.168.25.101
vm1
ping 192.168.25.2  此处不通,还要再加一个规则

node3
而且对192.168.25.101的访问--都会转到内部
[root@node3 ~]# ip netns exec r1 iptables -t nat -A PREROUTING -d 192.168.25.101 -j DNAT --to-destination 10.0.4.216
[root@node3 ~]# ip netns exec r1 iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       all  --  0.0.0.0/0            192.168.25.101       to:10.0.4.216

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  10.0.4.216           0.0.0.0/0            to:192.168.25.101
[root@node3 ~]# ip netns exec r1 ping 10.0.4.216
PING 10.0.4.216 (10.0.4.216) 56(84) bytes of data.
64 bytes from 10.0.4.216: icmp_seq=1 ttl=64 time=1.45 ms
64 bytes from 10.0.4.216: icmp_seq=2 ttl=64 time=1.24 ms


Windows上的cmd命令里面或者xshell上
[c:\~]$ ping 192.168.25.101 -t  让其一直ping可以通
正在 Ping 192.168.25.101 具有 32 字节的数据:
来自 192.168.25.101 的回复: 字节=32 时间=6ms TTL=63
来自 192.168.25.101 的回复: 字节=32 时间=2ms TTL=63


node1--vm1
# ping 192.168.25.2
PING 192.168.25.2 (192.168.25.2): 56 data bytes
64 bytes from 192.168.25.2: seq=0 ttl=127 time=1.434 ms
 # ping 192.168.25.100
PING 192.168.25.100 (192.168.25.100): 56 data bytes
64 bytes from 192.168.25.100: seq=0 ttl=64 time=1.426 ms
64 bytes from 192.168.25.100: seq=1 ttl=64 time=1.481 ms
# ping 192.168.25.101
PING 192.168.25.101 (192.168.25.101): 56 data bytes
64 bytes from 192.168.25.101: seq=0 ttl=63 time=1.886 ms
64 bytes from 192.168.25.101: seq=1 ttl=63 time=4.884 ms

抓包测试

node1
[root@node1 ~]# tcpdump -i eth0 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:06:21.790558 IP 192.168.75.134 > 192.168.75.133: GREv0, length 78: IP 192.168.25.1 > 10.0.4.216: ICMP echo request, id 1, seq 77, length 40
19:06:21.791549 IP 192.168.75.133 > 192.168.75.134: GREv0, length 78: IP 10.0.4.216 > 192.168.25.1: ICMP echo reply, id 1, seq 77, length 40


再启动一个节点  node4
node1-vm1去ping 物理节点node4  可以通
# ping 192.168.25.14
PING 192.168.25.14 (192.168.25.14): 56 data bytes
64 bytes from 192.168.25.14: seq=0 ttl=63 time=3.542 ms
64 bytes from 192.168.25.14: seq=1 ttl=63 time=2.316 ms

node4
[root@node4 ~]# ping 192.168.25.101
PING 192.168.25.101 (192.168.25.101) 56(84) bytes of data.
64 bytes from 192.168.25.101: icmp_seq=1 ttl=63 time=2.70 ms
64 bytes from 192.168.25.101: icmp_seq=2 ttl=63 time=3.20 ms
node1抓包
[root@node1 ~]# tcpdump -i eth0 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:22:34.851859 IP 192.168.75.134 > 192.168.75.133: GREv0, length 102: IP 192.168.25.14 > 10.0.4.216: ICMP echo request, id 1332, seq 18, length 64
19:22:34.852970 IP 192.168.75.133 > 192.168.75.134: GREv0, length 102: IP 10.0.4.216 > 192.168.25.14: ICMP echo reply, id 1332, seq 18, length 64

好了--OK
实现了跨主机的flowting-ip,通过添加netns、基于GRE隧道封装


跨主机、GRE隧道
netns 
启动虚拟实例
基于ovs构建虚拟交换机
上一篇 下一篇

猜你喜欢

热点阅读