跳至主要内容

FW: VPC中的那些功能与基于OpenStack Neutron的实现

深入浅出新一代云网络


(一)-简述与端口转发


VPC的概念与基于vxlan的overlay实现很早就有了,标题中的“新”只是一个和传统网络的相对概念。但从前年开始,不同于以往基础网络架构的新一代SDN网络才真正越来越多的走进国内甲方厂商的视野,而从去年至今,笔者经历的诸多客户也在历经学习、测试后逐步将其部署入生产。与此同时,国内的公有云厂商们也或多或少地投入了对市场的教育成本,鼓励客户使用功能更强大,安全性更好的VPC网络。
  • 什么是VPC
VPC即virtual private cloud ,因其最大的特点还是网络方面,故行业内有时也称其为私有网络,在基础云计算环境之上,支持用户定义自己的虚拟网络,这个网络在逻辑上与云中的其他虚拟网络隔绝,用户可选择私有 IP 地址范围、创建子网以及配置路由表、网络网关和安全设置等。
传统基础网络的管理员视角:
(当然实际上,以往的IT集成架构会基于业务需求和安全需求作复杂的 外-核心-汇聚-接入-用户的层次划分。)
从用户的视角甚至可以简化为:
实际云环境中,抛开云主机的安全组策略、上层交换设备的ACL等不谈,各用户处于同一层次的网络中,IP自然也由平台管理端分配。
而对于使用VPC网络的环境来说:
左边颜色区域是一个用户,右边颜色区域是另一个用户。两者各自的网络广播域不会互相影响,IP自然也可以由用户指定。从图中不难发现,与基础网络相比,路由正是VPC网络的核心。
那么开头所说的“功能更强大,安全性更好”具体指什么呢?功能更强大,指的是更便利、形式多样的互联互通、带宽分配等网络功能;安全性更好,指的是用户的私有网络隐藏在路由之内,不仅互不影响,还可以将访问控制的执行者,从云主机本身一直延伸到三层。
  • VPC-NAT
NAT即网络地址转换,分为DNAT(目的地址转换)与SNAT(源地址转换),最直白地从常见功能目的来说, DNAT可以用于实现一个上层(路由的外层)地址的端口转发到下层(路由的内层)网络某个地址的某端口,SNAT可以用于实现多台云主机共享一个网关地址访问上层(路由的外层)网络。
第一个很好理解,4层端口转发。
有时候为了管理需要,要能在外层网络管理私网中的三台云主机,而这三台云主机仅有私网地址没有外层地址,那么可以使用端口转发,将路由外层地址 114.123.123.x 的22端口转发至第一台云主机10.1.1.3的22端口,将114.123.123.x的23端口转发至第二台云主机的22端口,将路由的24端口转发至第三台云主机的22端口。如此通过SSH一个外层地址的不同端口来连接到私网内的三台云主机。
其实和7层的转发有那么点相似之处,比如 Nginx的80端口代理后端应用服务器的8080端口,81端口代理另一台服务器的8080端口。还真别说,Nginx自从1.9版本后开始支持TCP代理了。
抛开应用层转发不谈,基于OpenStack该如何实现呢?
熟悉虚拟化与容器技术的朋友肯定熟悉linux的namespace(命名空间),在Neutron 的L3节点上,不同用户的VPC路由正是用namespace技术实现的隔离,这一点和不同vxlan网络的隔离还是有很大区别的,本篇不谈。
netns是在Linux中提供网络虚拟化的一个项目,使用netns网络空间虚拟化可以在本地虚拟化出多个网络环境
所以,在L3节点使用ip netns 可以看到含本地所有网络命名空间的list:
可以发现,其实不同网络的dhcp服务与负载均衡服务(非Octavia)也是使用类似的方式。
qrouter后面接的uuid正是路由的uuid。通过这种方式即可进入VPC路由所在命名空间并使用iptables 执行对NAT表规则的增删。
故端口转发的功能API流程可以简单描述为:
输入数据为 VPC路由uuid 及端口,私网云主机IP及端口,生成
VPC路由IP:端口 →  云主机IP:端口
的一条 DNAT规则。
进入VPC命名空间执行规则。
执行后NAT表效果:
系列下一篇 《深入浅出新一代云网络——VPC中的那些功能与基于OpenStack Neutron的实现(二)》中将给出上文的简单API 代码,并展开另一块内容——VPC网络带宽的共享与分离。考虑篇幅, VPC网络中实现互联互通的路由技术与隧道技术可能会放在系列的第三篇。


(二)-带宽控制


在VPC功能实现第一篇中,简单介绍了一下VPC网络对租户间隔离能力的提升以及基于路由提供的一系列网络功能。在这一篇中,将继续介绍VPC网络中十分重要的一个内容:网络带宽的控制,共享以及分离。
首先是对第一篇中,端口转发功能的样例代码,all-in-one http service 风格的实现。
核心功能:
find_router_ip = "ip netns exec qrouter-{router_id} ifconfig |grep -A1 qg- | grep inet | awk '{{print $2}}'".format(router_id=router_id)

(status, output) = commands.getstatusoutput(find_router_ip)

run_router_dnat = "ip netns exec qrouter-{router_id} iptables -t nat -D PREROUTING -d {router_gwip} -p {protocol} --dport {router_port} -j DNAT --to-destination {vm_ip}:{vm_port}".format(router_id=router_id,router_gwip=router_gwip,protocol=protocol,router_port=router_port,vm_ip=vm_ip,vm_port=vm_port)

(status, output) = commands.getstatusoutput(run_router_dnat)
Git repo地址
opencloudshare/Op_portforward
在readme中有简单的介绍,通过最基本的rest请求即可实现功能。
Demo级的代码,逻辑十分好理解,根据输入的router_uuid ,找到 L3 节点上的命名空间,修改iptables实现转发功能即可。
如果要在环境中正式使用,建议引入数据库作为转发记录的存储。引入了数据存储后推荐加入额外的两个流程:
1. 一致性
在通过commands或popen等执行系统命令的时候,通过不同的return status 及回显作逻辑分支或try-exception。保证调用功能时的数据库里的存储规则和nat表上规则一致性。
如果nat规则的写入和代码里不同——不是直接在preforward主链而是在neutron-l3的子链里写入,会发现执行某些网络操作之后,nat规则会丢失,这是因为Neutron-l3-agent在router所控制的floating_ip发生变动时,自身会重写nat表中自身子链的规则,这是neutron自己对l3数据一致性的保证。
2. 恢复
在l3节点所有配置清零重置后,能够恢复之前各命名空间内的nat规则。这个功能简单说就是一个读取数据库规则并解析执行的批量过程,也和Neutron的sync过程相似。
另外,从安全角度考虑,结合 keystone 加一层认证是更好的。
接下来进入带宽控制的主题。
Neutron在以OVS组网时提供的 qos_policy功能实际上调用的是 ovs已有的对挂接在ovs-br上port的bandwidth limit,但只能控制 port 的出流量,是单向的。
如同:
ovs-vsctl set interface nic-id ingress_policing_rate=xxx
ovs-vsctl set interface nic-id ingress_policing_burst=xxx
底层都绕不开linux TC: Tc (Linux) - Wikipedia
TC规则涉及到队列(queue),分类器(class)和过滤器(filter)三个概念.
   队列用来实现控制网络的收发速度.通过队列,linux可以将网络数据包缓存起来,然后根据用户的设置,在尽量不中断连接(如TCP)的前提下来平滑网络流量.需要注意的是,linux对接收队列的控制不够好,所以我们一般只用发送队列,即“控发不控收”,。
  class用来表示控制策略.很显然,很多时候,我们很可能要对不同的IP实行不同的流量控制策略,这时候我们就得用不同的class来表示不同的控制策略了.
  filter用来将用户划入到具体的控制策略中(即不同的class中).正如前述,我们要对A,B两个IP实行不同的控制策略(C,D),这时,我们可 用filter将A划入到控制策略C,将B划入到控制策略D,filter划分的标志位可用u32打标功能或IPtables的set-mark功能来实 现。
Tc控发不控收,注意发送指的是发出/上传/出网/上行 的意思,因此原生ovs bandwidth limit在单纯的对外提供数据的服务场景下是足够适用的。但是在提供用户上传功能、云主机软件更新等需要下行流量的场景则无法约束,更别提当云主机被入侵,攻击者植入程序产生或作为肉鸡发起对其它被攻击对象的爆发性大规模下行流量了。在做了双向的流量控制后,也更能分担监控、抗D等系统的压力。因此无论是用户业务需求还是平台层考量,双向QoS都是有意义的。
tc中的htb(令牌桶)算法简单描述:
假如用户配置的平均发送速率为r,则每隔1/r秒一个令牌被加入到桶中;
假设桶最多可以存发b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃;
当一个n个字节的数据包到达时,就从令牌桶中删除n个令牌,并且数据包被发送到网络;
如果令牌桶中少于n个令牌,那么不会删除令牌,并且认为这个数据包在流量限制之外;
算法允许最长b个字节的突发,但从长期运行结果看,数据包的速率被限制成常量r。对于在流量限制外的数据包可以以不同的方式处理:
它们可以被丢弃;
它们可以排放在队列中以便当令牌桶中累积了足够多的令牌时再传输;
它们可以继续发送,但需要做特殊标记,网络过载的时候将这些特殊标记的包丢弃。
注意:令牌桶算法不能与另外一种常见算法“漏桶算法(Leaky Bucket)”相混淆。这两种算法的主要区别在于“漏桶算法”能够强行限制数据的传输速率,而“令牌桶算法”在能够限制数据的平均传输速率外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量。
在用原生tc代替neutron qos policy时,可以使用两种模式:
1. 云主机模式
即只对云主机做流量控制,这里要提一下计算节点上云主机连接网卡的原理。
在计算节点ip a的话,我们可以看到大量的虚拟网卡,在libvirt的虚机xml文档中,可以明确看到云主机与连接网卡的信息。
但除了tap设备外,计算节点上还有qvo,qvb,qbr。这些分别是什么呢。
openstack neutron 解释的很详细,可以直接参考。
不难归纳出 上行流量控制:
下行流量控制:
由前文,tc控制网卡设备的发出流量,所以当我们对上行或下行想做限制的时候,实际tc生效的设备只能是方向路径上的设备。故云主机模式的qos控制,可以分别对 qvo和 qvb设备进行规则写入,即可实现上下行双向控制。
tc qdisc del dev qvo233 root  //删除原有规则
tc qdisc add dev qvo233 root handle 1: htb default 100 //创建htb队列 
tc class add dev qvo233 parent 1: classid 1:1 htb rate 1gbit  //
tc qdisc add dev qvo233 parent 1:1 sfq perturb 10  //sfq队列,避免单会话永占  
tc class add dev qvo233 parent 1: classid 1:100 htb rate 10mbit ceil 10mbit //子类100 带宽10mb
tc qdisc add dev qvo233 parent 1:100 sfq perturb 10
tc class add dev qvo233 parent 1: classid 1:101 htb rate 100mbit ceil 100mbit
//子类101 带宽100mb
tc qdisc add dev qvo233 parent 1:101 sfq perturb 10
tc filter add dev qvo233 protocol ip parent 1: prio 1 u32 match ip src 10.0.0.0/8 flowid 1:101
tc filter add dev qvo233 protocol ip parent 1: prio 1 u32 match ip src 172.16.0.0/12 flowid 1:101
tc filter add dev qvo233 protocol ip parent 1: prio 1 u32 match ip src 192.168.0.0/16 flowid 1:101
上面即是对qvo233这个设备的带宽控制,实际为下行规则。默认子类为100 (10mb),但是当源地址为 10.0.0.0/8 和 172.16.0.0/12、192.168.0.0/16 时,使用子类101 (100mb),这样保证私有地址间带宽为百兆,而公网流量的带宽为十兆。
为什么私有地址间的流量也要做限制?是因为即使是用户VPC内云资产产生的东西向流量,仍要占用计算节点物理网卡的实际带宽,以及用于构建 VXLAN 网络的交换机处理能力,考虑到云资产较多的情景,因此是不得不注意的。
顺带一提,公网流量既包含 L3 节点的南北向流量,也包含L3节点上网关路由到实际云资产所在宿主机的东西向流量。 带宽在 L3 处更容易出现瓶颈。
2. VPC模式
对VPC与外网间的流量控制可以更灵活,在系列第一篇里介绍了VPC的路由,而这个路由实际上通过至少两张网卡连接了租户内网与外部网络,
上图左上角的路由,有两张网卡,内连VPC的router_interface 与外连外部网络的 router_gateway。
在 L3_agent上也可以看出来:
qg为外部网络的网卡,qr为VPC内某一网络的网关。
在限制vpc总体的上行流量时,实际将 tc 规则写在 qg 即可,在限制VPC总体下行流量时,将tc 规则写在 qr 即可。
这是VPC共享带宽的一种思路。
如此实现了VPC内所有云资产的公网流量共享,无需再限制云主机单台的公网带宽,其实这种在公有云场景更满足用户预期,因为这样用户就不必为每一台VPC内的云资产带宽买单,只用支付总体带宽费即可。
在实现了VPC内云资源和外网流量的共享后,就有了新的问题,当发生资源抢占时该怎么办。
如果任由抢占,那么我们使用的随机序列算法就会生效,每隔10秒重新分配队列。
但这对有良好业务规划的用户来说并不合理,用户可能需要某些业务能保持一定的独占性。
所以我们通过对 不同子类带宽的划分 以及 filter 规则的细化,即可实现源或目的不同转发路径的带宽控制,对floating IP 以及 上一篇中的 NAT 功能同样适用 。
上图的样例设计即可满足 部分云资产的带宽独占性,同时在总共享带宽未满的情况下,可以进行借用的场景功能。
系列下一篇 《深入浅出新一代云网络——VPC中的那些功能与基于OpenStack Neutron的实现(三)》中将给出实现QOS带宽控制的类似开头DNAT功能 rest api 的demo代码,并展开下一块内容——VPC网络中实现互联互通的路由技术与隧道技术,和场景案例。

(三)-路由与隧道


在系列的上一篇,
深入浅出新一代云网络--VPC中的那些功能与基于OpenStack Neutron的实现(二) - 知乎专栏 ,主要讲了在多租户场景下一个重要的网络功能——带宽QOS的原理与实现。
先同样给出一份 aio风格的 REST API 示例代码,同样可以在不修改Neutron代码的情况下独立使用。
opencloudshare/Op_vmqos
逻辑原理在上一篇中介绍的比较详细,主要就是通过 OpenStack API 找到云主机的虚拟NIC设备所在的宿主机,通过paramiko到宿主机上执行写入TC规则。
使用的话可以灵活的修改 region、domain等参数,代码里使用的默认的。
找到虚拟NIC设备也不一定通过VM id的方式,可以根据需要修改。比如,在之前的一个项目中,涉及到了 “根据当前网络流量自动扩容带宽” 功能,简单来说是 “当前云资产带宽使用率达到X时,自动通过控制器对云资产所享有的带宽进行扩容”。当时的环境没有Ceilometer ,使用的方案是 在宿主机上装了 Zabbix agent,对所有网卡实现自动发现,然后监控并在触发阈值后,传值调用 QOS的REST API,当时传的值,就是具体的 NIC设备名,而不是 VM id。
实现三层共享带宽与控制原理是相同的,只是提取L3 namespace里的NIC设备名时,为 router-port 相关方法。
进入今天的正题——路由、隧道与案例,在实际的云计算场景中,混合云占了很大一部分,一般我们对混合云的概念定义,是指既有私有云的内容,又结合了在公有云上的部分,共同建设、组成的云环境。
经典案例,是在各大峰会上被经常拿来说的 新浪微博混合云架构实践。既包含了业务层面 网络、存储、Docker 等领域的挑战,也存在 控制层面的 运维管理、弹性调度等的考量。
上面说的“私有云内容”,其实可以扩充为 “任何私有IT环境” 。各位云计算工程师们一定遇到过很多 在“云” 的概念提出以前的IT建设项目 与 新的云计算环境打通接入 的需求。就好像私有云项目中客户经常会要求能和以前的IT设施互访,而不是简单的部署一个割裂的环境或迁移。直接使用VLAN技术将租户网络接入外部网络可能并不是一个通用性的选择,因为与VXLAN二层+VPC网络相比,前者有更多的侵入性、需要更复杂的网关层面的路由控制等。NAT技术则是将网络连接的层次提高了一层,用户有明确的感知,在云资产数量较多及全端口的需求下,对NAT规则的控制与上层网络可使用的IP数量成了瓶颈。因而隧道技术成了更好的选择。
接下来我将以几个参与的case为例,讲讲在面对复杂的互联互通需求时,可以考虑的方案,与利用 OpenStack Neutron 完成的功能。
  • case 1
客户已有一套传统IT环境,现要求与新部署的OpenStack环境某一VPC内云资产进行互访。
OpenStack 的 neutron-vpn-agent 可以提供 IPsec VPN服务,在路由间建立隧道。
在企业内网环境,还可以使用配置更方便的 GRE隧道和IPIP隧道。
当然,具体使用何种协议,更多的是看路由设施对协议的支持程度,l3-agent 在 namespace建立的软路由因为基于linux kernel ,在没有极高性能要求的场景下可以支撑种类繁多的协议。而当对端是物理设备时,则得确定是否支持。
IPsec VPN就不做示例了,官方文档即可查看。
软实现GRE隧道打通的简单示例:
# 加载模块
modprobe ip_gre
# 建立隧道,隧道名,隧道类型,远端地址,本地地址
ip tunnel add mytunnel mode gre remmote 10.200.11.22 local 10.100.1.11
# 设置隧道接口地址,任一不和待打通的网络冲突的即可
ifconfig mytunnel 10.199.199.1 netmask 255.255.255.0
# 添加到对端网络的路由
ip route add 192.168.3.0/24 dev mytunnel
在对端:
# 加载模块
modprobe ip_gre
# 建立隧道,隧道名,隧道类型,远端地址,本地地址
ip tunnel add mytunnel mode gre remmote 10.100.1.11 local 10.200.11.22
# 设置隧道接口地址,任一不和待打通的网络冲突的即可
ifconfig mytunnel 10.199.199.2 netmask 255.255.255.0
# 添加到对端网络的路由
ip route add 192.168.1.0/24 dev mytunnel
之后,便可测试OpenStack VPC内的这个网络到右侧已有网络的打通互访效果。
  • case 2
客户已有一套传统IT环境,现要求与新部署的OpenStack环境内 多个 VPC内云资产进行互访。
这个case是上一个的加强版。如果是在OpenStack环境内的网络打通,同一project下,我们会将多个网络连接同一路由,如果接口不是默认网关,添加对应的路由表。
在这个案例中,传统IT环境与OpenStack环境的外部网络其实是通过物理专线相连接的,而OpenStack内多个VPC的使用者是企业的不同项目组。简而言之,这多个项目组,要求共用同一条物理专线,但都能访问到各自的VPC内。
在各VPC原有路由不变(默认网关为 x.x.x.1)的情况下,建立一个专用路由,将各VPC内各网络接入该专用路由(专线网关为 x.x.x.99),用该路由通过物理专线与传统环境形成打通。
软实现IPIP隧道打通的简单示例:
# 加载模块
modprobe ipip
# 建立隧道,隧道名,隧道类型,远端地址,本地地址
ip tunnel add mytunnel mode ipip remmote 10.200.11.22 local 10.100.1.11
# 设置隧道接口地址,任一不和待打通的网络冲突的即可
ifconfig mytunnel 10.199.199.1 netmask 255.255.255.0
# 添加到对端网络的路由
ip route add 192.168.3.0/24 dev mytunnel
在对端:
# 加载模块
modprobe ipip
# 建立隧道,隧道名,隧道类型,远端地址,本地地址
ip tunnel add mytunnel mode ipip remmote 10.100.1.11 local 10.200.11.22
# 设置隧道接口地址,任一不和待打通的网络冲突的即可
ifconfig mytunnel 10.199.199.2 netmask 255.255.255.0
# 添加到对端网络的路由
ip route add 192.168.1.0/24 dev mytunnel
ip route add 192.168.2.0/24 dev mytunnel
ip route add 192.168.0.0/24 dev mytunnel
还没有完,因为对VPC内的云资产来说,默认网关是 x.x.x.1 ,意味着在不改动云资产内路由表的情况下,发往 192.168.3.0/24 的数据包都将发往 x.x.x.1 。所以我们需要对三个VPC的路由设施添加路由表,将数据包转发至 x.x.x.99 。
vpc1_routes: {"destination": "192.168.3.0/24", "nexthop": "192.168.1.99"}
vpc2_routes: {"destination": "192.168.3.0/24", "nexthop": "192.168.2.99"}
vpc3_routes: {"destination": "192.168.3.0/24", "nexthop": "192.168.0.99"}
由传统环境到云上多个VPC的互访功能即可实现,且 VPC 与VPC 间仍是不能互访的。
在这个 case 中,我更推荐将用于专线的路由不使用默认的L3-agent —— neutron api 中的router 去创建,而是以云主机的形式建立,理由如下:
  1. 原router所有的内部接口现在是云主机的各NIC,可以通过对云主机的控制来改变配置,避免了直接操作L3节点可能的风险;
  2. 可以在云主机而非L3节点内装 满足复杂网络监控需求的软件/Agent;
  3. 通过调整CPU来调整转发能力;
  4. 通过控制port 来控制各VPC对专线带宽的占用情况与应急断连的保护;
  5. 云主机可以主备,在自动切换、恢复与迁移方面更方便。
在OpenStack环境建立用于转发功能的云主机,除了将 云主机操作系统内核参数的 ip_forward打开外,还需通过Neutron 对该云主机的port 进行 port_security_enabled = False 的操作。这一点在部署云主机版的NAT网关时同样适用。
  • case 3
  • 客户要求将一台高性能物理机接入云上VPC内,方便资源的互访。
    
    走南北方向的其它区域,是最简单的方案。

    但难点在于,客户并不想暴露OpenStack环境所在区域南北方向上的其它IP地址。换而言之,想让VPC内租户通过VPC内网络的地址访问到物理机。NAT是个不错的选择,基于前两个case的路由隧道方案也可以不必暴露基础环境中南北方向的IP规划。

    但我们也可以利用 OVS 的特性,将以有这个需求的VPC内网络用 VLAN 组网,实现基于物理 VLAN 交换机的跨物理服务器二层虚拟网络 ;或是 仍用 VXLAN 组网,但使用支持 VXLAN 的物理交换机来扩展原本架构。
    我们知道, VTEP 和 VXLAN GW 是VXLAN组网在东西向扩展的核心组件,混合Overlay 方案通过结合软硬实现VTEP等组件的功能, 同时对虚拟化环境与物理机提供了很好的支持。
    不过这当然需要物理硬件的支撑。如果在宿主机上安装openvswitch 等软实现,不可避免的会在物理机shell暴露东西向VXLAN GW,肯定是在考虑之外的。
    关于Neutron VXLAN的内容可以参考云极星创(现海航云)CTO 刘大神写得非常详细的系列:
    Neutron 理解 (1): Neutron 所实现的虚拟化网络 [How Netruon Virtualizes Network]
    在有其它SDN控制器的场景下,通过Neutron 加载不同 driver 实现对控制器的调度,也能达到效果。
    之前在和 VMware NSX做技术交流的时候,NSX在对同样需求时给出的参考建议也是通过NSX直接控制 用于物理机接入的交换机。
    在公有云上,云资产向VPC的引入更常见的方法是通过私有DNS解析与NAT技术相结合的方式,这方面就不展开多谈了,结合前面的文章可以思考他们的大致实现。
    企业内网与专线环境下,对互联互通功能实现的选择可以使用payload更小,性能更好的隧道技术。但在公网环境下,基于IPSec与SSL的隧道技术从传输安全的角度上是必须考虑的。

    (四)-云主机vip与vip绑定浮动IP


    这个系列接下来将介绍面对客户实际需求时的一些技术实践和需要考虑的细节。

    客户要求在openstack环境内创建的多台云主机配置keepalived作主备,默认情况下无法生效,直接对云主机一张网卡配置两个IP进行测试也是同样结果,因为:
    可以看到,port所在的宿主机上iptables 对 MAC地址和IP进行了限制。所以需要如下操作:
    pre. 确认云主机网卡port_id
    nova interface-list [vm_id]
    1. 确认 ml2 配置中
    arp_responder = False
    或 未配置(因为默认为false);
    2. 对需要配置vip的port,可以直接 disable 安全组 (不推荐):
    neutron port-update --no-security-groups --port-security-enabled=False [port_id]
    eg.
    neutron port-update --no-security-groups --port-security-enabled=False aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
    也可以使用 allowed-address-pair功能 (推荐) :
    neutron port-update --allowed-address-pair ip_address=[CIDR] [port_id]
    eg.
    neutron port-update --allowed-address-pair ip_address=10.1.100.100 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
    或 段也可以
    neutron port-update --allowed-address-pair ip_address=10.1.100.100/31 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
    到这一步为止,云主机内配置上面的 vip 就已经可以使用了。

    3. 为了避免后续创建的云资产使用vip的地址 ,创建闲置的port,占用掉vip地址:
    neutron port-create --fixed-ip ip_address=[IP_ADDR] [network_id]
    neutron port-create --fixed-ip ip_address=10.1.100.100 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
    此时这个port 只是一个DB里的一个记录,不会在宿主机上创建tap设备或增加iptables chain,不用担心额外的资源损耗。它的用途仅仅是占用IP地址以免被其它资源使用而已。
    如下图,dhcp不会再分配 10.1.100.100 这个ip
    接下来开始将浮动IP绑定给vip,平时我们在dashboard处是给云主机绑定浮动IP,常用的CLI /api 是
    nova floating-ip-associate <server> <address>
    ,可这样浮动IP绑定的是云主机网卡原始IP (10.1.100.7),不是vip (10.1.100.100)

    ,所以我们得使用neutron 的相关接口。
    4. 创建浮动IP
    neutron floatingip-create [floating_net_id]
    neutron floatingip-create cccccccc-cccc-cccc-cccc-cccccccccccc
    5. 绑定
    neutron floatingip-associate [floatingip_id] [port_id]
    先将刚才通过nova CLI 绑定的解绑
    开始绑定
    neutron floatingip-associate cccccccc-cccc-cccc-cccc-cccccccccccc aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
    再去l3 节点的net ns里可以看到
    已经绑定的是 vip (10.1.100.100) 了


    可以将这一整套封为一个接口方便上层应用调用。

    评论

    此博客中的热门博文

    Set up Python3 Environment on CentOS

    Required Software Packages, Tools, and Files Installing Packages $ sudo su - $ yum update $ yum groupinstall -y "development tools" $ yum install -y \ lsof \ wget \ vim-enhanced \ words \ which $ exit Configuring Git $ git config --global user.name "Your Name" $ git config --global user.email "your_email@example.com" Customizing Bash $ curl https://raw.githubusercontent.com/linuxacademy/content-python3-sysadmin/master/helpers/bashrc -o ~/.bashrc Customizing Vim $ curl https://raw.githubusercontent.com/linuxacademy/content-python3-sysadmin/master/helpers/vimrc -o ~/.vimrc Download and Install Python 3 from Source $ sudo su - [root] $ yum groupinstall -y "development tools" [root] $ yum install -y \ libffi-devel \ zlib-devel \ bzip2-devel \ openssl-devel \ ncurses-devel \ sqlite-devel \ readline-devel \ tk-devel \ gdbm-devel \ db4-devel \ libpcap-devel \ xz-devel \ expat-devel [root ] $...