网络虚拟化技术三
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构建虚拟交换机