- 前言:下面所说的veth pair都是只veth pair这种方式而不是指linux的veth pair. openstack默认使用openvwitch来实现veth pair.
- 为了更容易理解,我们先看无外网IP但是可以访问外网的情形(只能访问外网,不能被外部网络访问、即只出不进)
- 现在我们再看有外网IP的情形
- 总结
前言:下面所说的veth pair都是只veth pair这种方式而不是指linux的veth pair. openstack默认使用openvwitch来实现veth pair.
但是早期资料表示openvwitch实现的veth pair不支持tc,所以要用tc流控需要配置为使用linux自带的veth pair.
dvr参考链接
neutron配置为dvr-snat,这样无外网ip的实例的才能访问外网
1.网络分配(虽然虚拟机要获取ip必须有通过dhcp,但是因为dhcp会多出一个和路由没关的空间,所以暂时不介绍和dhcp相关的东西,所有网络不开DHCP,通过vnc进入到虚拟机中手动分配)
没有实际的外网IP,所以直接用一个172的网段当外网
这里我们使用172.30.0.0/24
虚拟机内部IP段为
我们使用192.168.1.0/24
172.30.0.0/24由于是外网(create network的时候external network打勾),需要由cloud admin创建并设置共享(share打勾)。 创建子网的时候网关设置为对应vlan的网关,我这里用的是172.30.0.1,范围要错开交换机上的vlan interface ip
192.168.1.0/24网段由普通用户创建网络并分配子网,需要通过内网路由到外网,所以需要网关,使用192.168.1.1
2.路由创建
和ulcoud、qcloud一样,虚拟机中只有内网IP,看不到外网IP
通过route,外网IP的访问转发到内网IP上
所以需要创建路由将内网网段和外网网段打通
其实,就是通过namespace、ovs、iptable实现了三层交换机的路由功能
所以,折腾这里之前,建议先通过物理设备联系下vlan划分、交换机上做vlan路由通子网的操作
为了更容易理解,我们先看无外网IP但是可以访问外网的情形(只能访问外网,不能被外部网络访问、即只出不进)
首先看ovs网桥
Bridge br-int
fail_mode: secure
Port "qr-e0711d58-58" 192.168.1.1
tag: 1
Interface "qr-e0711d58-58"
type: internal
Port "tapcf6bc2eb-b1" 192.168.1.3
tag: 1
Interface "tapcf6bc2eb-b1"
Port "sg-8f551a28-9e" 192.168.1.4
tag: 1
Interface "sg-8f551a28-9e"
type: internal
Bridge br-ex
Port br-ex
Interface br-ex
type: internal
Port "enp3s0f1" 物理网卡
Interface "enp3s0f1"
Port "qg-d991dda3-eb" 172.30.0.10
Interface "qg-d991dda3-eb"
type: internal
路由的snat空间
Port "sg-8f551a28-9e" 192.168.1.4 network:router_centralized_snat
Port "qg-d991dda3-eb" 172.30.0.10 network:router_gateway
# snat空间的路由就是default gw 172.30.0.1
路由的qrouter空间,这个空间的路由策略有特殊处理
# 接口
Port "qr-e0711d58-58" 192.168.1.1 network:router_interface_distributed 虚拟机网关地址
Port "tapcf6bc2eb-b1" 192.168.1.3 compute:nova 虚拟机IP
# 路由策略
[root@openstack ~]# ip netns exec qrouter-a74892a9-8fea-4495-ad58-4d1244065b9c ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default # default路由表是空表
3232235777: from 192.168.1.1/24 lookup 3232235777 # main路由表没有被匹配的是后,走这个路由表
# 3232235777路由表信息,就一条,网关是192.168.1.4
default via 192.168.1.4 dev qr-e0711d58-58
重点在于理解192.168.1.4与192.168.1.1,为什么有了192.168.1.1还会需要一个192.168.1.4.
qrouter空间要通向snat,再通过172.30.0.0段穿出去,需要打通两个namespace, 192.168.1.4和192.168.1.1就是打通两个命名空间veth pair(openstack默认用ovs实现这个功能,也就是他俩都在一个Bridge上). veth pair两端都需要IP,所以我们不仅看见了这头的网关IP 192.168.1.1,还另外占用了一个192.168.1.4的IP. 同样外网IP虽然不是veth pair,但是逻辑类似,这一头有一个172.30.0.10, 和外网的网关172.30.0.1是可达的. 其实就是类似三层交换机做路由,需要两边都有相同网段的vlan interface ip
路由过程如下
在没有外网的情况下,我们虚拟机的网关是192.168.1.1,数据包发往192.168.1.1
defalut路由表中没有被匹配到出去的下一条地址,路由策略使用下一个路由表3232235777
这个路由表只有一条默认网关为192.168.1.4的路由
也就是说我们的对外请求先发到192.168.1.1,然后被qr-e0711d58-58发到192.168.1.4
这样出去的数据包就到了snat空间,最后通过snat空间的网关172.30.0.1发到外部
实现上面功能,操作步骤为 1、创建路由,选172.30.0.0/24段 2、进入路由中增加接口,选择内网192.168.1.0/24段,网关不用填,自动使用子网创建时的网关
现在我们再看有外网IP的情形
直接给虚拟机分配外网IP的方式我们就不讨论了,因为实际业务中虚拟机实例绑定IP的做法非常不灵活。 从这里可以看出.阿里云的虚拟机中有2个网卡,一个网卡带有外网IP是非常落后的做法(卸载外网IP需要虚拟机实例的系统配合)。
我们来看普遍做法——内网通过路由链接到外网,然后为虚拟机实例绑定一个浮动IP.前面我们已经完成了路由设置,再为虚拟机绑定一个浮动IP就可以了.
我们来看看绑定浮动IP后的ovs和namespace,因为重建了一次路由,所以IP有些变化,原理和前面一样。
当前内网IP 192.168.1.6, 外网IP 172.30.0.16
ovs网桥
Bridge br-int
Port "sg-72ac01bb-72"
tag: 9
Interface "sg-72ac01bb-72"
type: internal
Port "qr-8868c230-55"
tag: 9
Interface "qr-8868c230-55"
type: internal
Port "tapc8a38809-f6"
tag: 9
Interface "tapc8a38809-f6"
Bridge br-ex
Port br-ex
Interface br-ex
type: internal
Port "qg-cae8db5d-f4"
Interface "qg-cae8db5d-f4"
type: internal
Port "enp3s0f1"
Interface "enp3s0f1"
Port "fg-f4980cc3-de"
Interface "fg-f4980cc3-de"
type: internal
qroute空间
qr-8868c230-55 192.168.1.1/24
rfp-a74892a9-8 169.254.106.114/31
# 路由信息
[root@openstack ~]# ip netns exec qrouter-a74892a9-8fea-4495-ad58-4d1244065b9c ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
57481: from 192.168.1.6 lookup 16
3232235777: from 192.168.1.1/24 lookup 3232235777
# 来自192.168.1.6,全部从通过rfp-a74892a9-8,从169.254.106.115出去
# 也就是直接穿到浮动IP空间的fpr-a74892a9-8
# 也就是说不走到snat空间
[root@openstack ~]# ip netns exec qrouter-a74892a9-8fea-4495-ad58-4d1244065b9c ip route show table 16
default via 169.254.106.115 dev rfp-a74892a9-8
# default table的路由
169.254.106.114/31 dev rfp-a74892a9-8 proto kernel scope link src 169.254.106.114
192.168.1.0/24 dev qr-8868c230-55 proto kernel scope link src 192.168.1.1
snat空间
qg-cae8db5d-f4 172.30.0.10/24
sg-72ac01bb-72 192.168.1.8
default via 172.30.0.1 dev qg-cae8db5d-f4
172.30.0.0/24 dev qg-cae8db5d-f4 proto kernel scope link src 172.30.0.10
192.168.1.0/24 dev sg-72ac01bb-72 proto kernel scope link src 192.168.1.8
浮动IP空间
fpr-a74892a9-8 169.254.106.115/31
fg-f4980cc3-de 172.30.0.11/24
default via 172.30.0.1 dev fg-f4980cc3-de
169.254.106.114/31 dev fpr-a74892a9-8 proto kernel scope link src 169.254.106.115
172.30.0.0/24 dev fg-f4980cc3-de proto kernel scope link src 172.30.0.11
172.30.0.16 via 169.254.106.114 dev fpr-a74892a9-8
iptable的内容就不贴了,可以看到和之前无外网IP单通外网的区别在于
1.多出了个浮动ip空间
2.多了一对veth pair fpr-a74892a9-8与rfp-a74892a9-8
3.qroute空间多了一条路由策略和对应的路由表
4.有浮动ip的情况下,路由策略不再走snat空间,而是通过浮动ip空间到达br-ex
总结
1.dvr-snat是给无外网IP的虚拟机访问外网用的。
2.如果不分配外网虚拟机不需要访问外网,配置为dvr即可(也就是不走snat空间到br-ex)。
3.openstack中虚拟机访问外网,需要经过多个网关、通过iptable多次nat,如果使用ovs,性能堪忧。