SFC架构草案

来自: rfc7665-Service Function Chaining (SFC) Architecture

端到端服务的交付通常需要各种服务功能。这些功能包括传统网络服务功能,如防火墙和传统的IP网络地址转换器(NATs),以及网络应用功能

SFC定义: 一组有序的服务功能的定义和实例化,以及随后通过它们进行的流量"控制"。

The definition and instantiation of an ordered set of service functions and subsequent "steering" of traffic through them is termed Service Function Chaining (SFC).

SFCs支持由一个或多个服务功能构造的组合服务。

当前的服务功能部署模型是相对静态的,与网络拓扑和物理资源耦合,极大地降低或消除了操作员引入新服务或动态创建服务功能链的能力。该体系结构提供了一个解决现有服务部署问题的模型,包括拓扑独立性和配置复杂性。

对称SFC

在对称性方面也存在权衡。根据SFF和分类器功能,可以通过多种方式实现对称:

  • 在某些情况下,镜像分类(即可以部署(从源到目的地和从目的地到源)策略,
  • 在其他情况下,可以使用分类器之间的共享状态来确保正确标识对称流,

在高层次上,各种常见的情况可能有(单、集群、分布式、学习、SFF实现):

  • 单个分类器(或少量的分类器),在这种情况下,进出口流量可以在同一个分类器上实现分类;
  • 有状态分类器,几个分类器组成的集群,其之间共享状态;
  • 完全分布的分类器,其中需要通过未指定的方法提供同步
  • 从出口包/流中学习状态的分类器,然后用于为返回包/流提供状态。
  • 在某些实现中,SFF中的有状态转发逻辑也可以提供对称性。

SFP(Service Function Paths)

一个SFC可以有多个SFPs,如数据中心1一个,数据中心2一个。
一个SFF下面可以有多个SFs.

服务链(SEC), 服务路径(SFP), 已渲染的服务路径(RSP)

服务功能链(SFC):使用此链的数据包应传递到防火墙和缓存引擎。
服务功能路径(SFP):指定防火墙和缓存引擎都位于特定的数据中心(例如在DC1中),或者可能确切指定要使用每个防火墙和缓存引擎的实例。
已渲染的服务路径(rendered service path, RSP):是包含实际访问的SFFs和SFs的序列。所以对比SFP选择DC, RSP会更具体。

架构原则

服务功能链接基于几个关键的体系结构原则:

  1. 拓扑独立性:部署和调用SF或SFC不需要更改底层网络转发拓扑(隐式或显式)。
  2. 平面分离:SFP的动态实现与数据包处理操作(例如,数据包转发)分离。
  3. 分类:满足分类规则的流量将根据特定的SFP转发。 SFC内可能有多个分类点(即形成服务图),从而使SF可以更改/更新SFC
    分类可以以不同程度的粒度进行;例如,分类可以使用5元组,传输端口或一组端口,这是数据包有效负载的一部分,它可以是高级检查的结果,也可以来自外部系统。
  4. 共享元数据:元数据/上下文数据可以在SF和分类器之间,SF之间以及外部系统和SF之间共享(例如,编排)。
    元数据的一种用法是沿SFP提供和共享分类结果(发生在启用SFC的域内或外部)。例如,外部存储库可能向服务链分类器提供用户/租户信息。该分类器又可以将该信息强加在SFC封装中,以传递到必要的SF。 SF可以依次将用户/租户信息用于本地策略决策。元数据还可以沿SFP共享SF输出。
  5. 服务定义独立性:SFC体系结构不依赖于SF本身的细节。
  6. SF的独立性:SFC的创建,修改或删除对其他SFC没有影响。 SFP也是如此。
  7. 异构控制/策略点:该体系结构允许SF使用独立机制(在本文档的范围之外)来填充和解析本地策略和(如果需要)本地分类标准。

SFF

SFF的主要职责如下:

  • 转发:与转发职责相关,SFF应该能与元数据交互;
  • 终止SFP:SFF去掉SFC的封装,将数据包发送回网络进行转发
  • 维护流状态:在某些情况下,SFF可能是有状态的。它创建流并存储以流为中心的信息。此状态信息可用于一系列与sfp相关的任务,如确保给定流中所有包的一致性处理、确保对称性,或用于状态感知的SFC代理功能。

虽然在SFF看来,交付给定SF的方式可能只有一种,但是SFP的约束也可能允许多种选择。如果有多个选择,SFF需要保留这样一个属性,即给定流的所有包都以相同的方式处理,因为SF很可能是有状态的。
此外,SFF可以基于流之上的其他属性(如订阅者、会话或应用程序实例标识)保留对数据包的处理

SFF还具有允许它在应用本地服务功能后将包转发到下一个SFF的信息

即使SFF支持并利用多个选择,关于是使用特定于流的机制还是使用粗粒度的方法来确保特定流的行为是稳定的,这也是特定解决方案和特定实现的问题。

如上所述,SFP转发直接依赖于SFC封装中包含的服务路径信息的使用。然而,现有的实现可能无法作用于SFC封装。如果可以安排,这些平台可以选择使用现有的传输信息来提供明确的服务路径信息

分类器SCL

分类由SCL处理;初始分类发生在SFC域的入口。

初始分类的粒度取决于分类器的能力和sfc策略的要求。

例如,分类可能相对粗糙:来自此端口的所有数据包都受SFC策略X的约束,并定向到SFP A,
或者相当精细:与此5元组匹配的所有数据包都受SFC策略Y的约束,并定向到SFP B。

重分类与分支

sfc架构也支持重新分类(或非初始分类)。
当包通过sfp时,可能发生重新分类: 通常由与SF的分类功能执行。
重新分类可能会导致选择新的SFP、更新关联的元数据,或两者兼而有之。这被称为分支。

例如,初始分类的结果选择SFP A: DPI_1 -> SLB_8。
但是,当执行DPI服务功能时,将在应用层检测到攻击流量。DPI_1将流量重新分类为攻击,并将服务路径更改为SFP B,
以包含用于策略实施的防火墙:删除流量:DPI_1-> FW_4。
在FW_4之后,幸存的通信流将返回到原始SFF。
在这个简单的示例中,DPI SF根据本地应用层分类功能对流量进行重新分类

当通过一个没有SFC感知的SF引导流量到达时,SFC代理必须对流量进行重新分类,以确定SFP。
SFC代理负责为不支持SFC的SFs重新附加信息,而有状态SFC代理将这种分类简化为流查找。

SFC Proxy

为了使SFC架构支持不支持SFC的SFs(例如,遗留服务功能),可以使用一个逻辑SFC代理功能。
SFC Proxy位于SFF和一个或多个SFF之间。
SFC Proxy代表SF接受来自SFF的数据包。它去掉了SFC的封装,然后使用一个本地连接将包发送到没有SFC感知的SFs。
它还接收来自SF的数据包,重新应用SFC封装,并将它们返回到SFF,以便沿着服务功能路径进行处理。
因此,从这个角度来看SFC代理似乎是感知SFC的SF的一部分。
对于从代理所代表的SF接收的SFF流量,即SFC代理:

  • 从SFC封装的数据包中移除SFC封装;
  • 根据元信息(包括封装在SFC中的信息)确定需要应用的SF;
  • 选择适当的出站本地连接,通过该电路可以到达此SFP的下一个SF;
  • 通过选择的本地连接电路将原始负载转发到适当的SF。

当流量从SF返回:

  • 应用所需的SFC封装。封装细节的确定可以通过接收包和/或帧的本地连接,或通过包分类或其他本地策略来推断。在某些情况下,为了重新应用正确的SFC封装,SF可能需要对包排序或修改进行额外的分类。
  • 将带有SFC封装的包传递给SFF,就像从具有SFC感知的SF返回的包一样。

NEO-NSH

参考论文: Neo-NSH: Towards Scalable and Efficient Dynamic Service Function Chaining of Elastic Network Functions
主要工作: Neo-NSH重新设计了24bits SPI,表示服务链ID,而不是服务路径。

中间件功能,如防火墙、入侵包检测、缓冲优化、负载均衡,即Service Function

两个关键:

  • 拓扑独立
  • 重分类与更新SFC的能力

VPP NSH设计

OpenNFV的实现

ODL使用NSH-VXLAN-GPE封装SFC,VXLAN-GPE在SF VM中终结,SF可以看到NSH Header, 处理NSI和NSH Metadata。
而OpenStack中,VXLAN终结在br-int网桥上。

目前使用的是OVS的一个NSH分支,其VXLAN的封装和解封装通过VTEP实现,正式版OVS将通过FLOW实现。

  1. 通过GBP(Group Based Policy)将Client报文redirect到Ingress Classifier
  2. Classifier对报文进行识别分类,分配NS,进行VXLAN-NSH封装,然后发送的SFF
  3. SFF解封装VXLAN报文,如果需要发送到SF,则通过VTEP发送到Linux Kernel
  4. VTEP对报文进行第二次的VXLAN-NSH的封装.
  5. 封装完成之后,查询Linux Kernel Route表,从TAP口发送回SFF。
  6. 在SFF中,报文根据VXLAN匹配要去的SF,然后将报文上送给SF
  7. 从TAP口将VXLAN-NSH报文上送给SF。

  1. SF将封装好的VXLAN-NSH报文发给SFF
  2. SFF根据入端口和VXLAN匹配此报文,交给Linux Kernel处理
  3. 报文查询路由通过VTEP口返回SFF
  4. VTEP解封装VXLAN-NSH
  5. SFF继续下一步处理,将报文交给下一个SF,或是从Egress Classfier出去。

OpenStack中的实现

MPLS

OpenStack 业务链networking-sfc介绍 (3) - 底层原理: https://blog.csdn.net/bc_vnetwork/article/details/65630475

以下下列配置为例, 创建业务链串联sf1, sf2, sf3 三台nfv虚拟机, 并从VM1处发包进入业务链:

         +------+     +------+        +------+         | SF1  |     | SF2  |        | SF3  |         +------+     +------+        +------+         p1|   |p2    p3|   |p4       p5|   |p6           |   |        |   |           |   |VM 1-->----+   +--------+   +-----------+   +---->

根据代码中的一些限制(参考后面"限制"章节), p1必须和logical-source-port在一个子网中, p2、p3必须在一个子网中, p4、p5必须在一个子网中。

所以, 本示例中, 我们定义p1的子网为: 1.0.0.0/24, p2的子网为: 2.0.0.0/24, p3的子网为: 2.0.0.0/24, p4的子网为: 3.0.0.0/24, p5的子网为: 3.0.0.0/24, p6子网为4.0.0.0/24。

$ openstack network create sfc-net-1$ openstack network create sfc-net-2$ openstack network create sfc-net-3$ openstack network create sfc-net-4$ openstack network create sfc-net-5$ openstack network create sfc-net-6$ openstack subnet create --network sfc-net-1 --subnet-range 1.0.0.0/24 sfc-subnet-1$ openstack subnet create --network sfc-net-2 --subnet-range 2.0.0.0/24 sfc-subnet-2$ openstack subnet create --network sfc-net-3 --subnet-range 3.0.0.0/24 sfc-subnet-3$ openstack subnet create --network sfc-net-4 --subnet-range 4.0.0.0/24 sfc-subnet-4# 创建虚拟机, 命名为sfc-vm-1, 加入2个网络: sfc-net-1, sfc-net-2# 创建虚拟机, 命名为sfc-vm-2, 加入2个网络: sfc-net-2, sfc-net-3# 创建虚拟机, 命名为sfc-vm-3, 加入2个网络: sfc-net-3, sfc-net-4# 修改虚拟机sfc-vm-1的nova port名字为: p1, p2# 修改虚拟机sfc-vm-2的nova port名字为: p3, p4# 修改虚拟机sfc-vm-3的nova port名字为: p5, p6$ openstack sfc port pair create --ingress p1 --egress p2 port-pair-1    # port-pair有进口与出口,一个pair是一个SF$ openstack sfc port pair create --ingress p3 --egress p4 port-pair-2$ openstack sfc port pair create --ingress p5 --egress p6 port-pair-3$ openstack sfc port pair group create --port-pair port-pair-1 port-pair-group-1   # 多个SFs,组成group,可用于负载均衡$ openstack sfc port pair group create --port-pair port-pair-2 port-pair-group-2$ openstack sfc port pair group create --port-pair port-pair-3 port-pair-group-3$ openstack sfc flow classifier create --source-ip-prefix 1.0.0.0/24 --logical-source-port p1 sfc-flow-class-1$ openstack sfc port chain create --flow-classifier sfc-flow-class-1 --port-pair-group port-pair-group-1 --port-pair-group port-pair-group-2 --port-pair-group port-pair-group-3 sfc-port-chain-1   # 一个分类器,加上多个Group组成一个服务链

br-int flow信息:

每一跳入口的sfc flow匹配和负载均衡, 在table:0中实现:table=0, priority=30,ip,in_port=997 ,nw_src=1.0.0.0/24 actions=group:1【匹配p1端口和流分类规则, 转发到group:1,做第1跳的出口负载均衡,并转发给第1个NFV虚拟机】table=0, priority=30,ip,in_port=998 ,nw_src=1.0.0.0/24 actions=group:2【匹配p2端口和流分类规则, 转发到group:2,做第2跳的出口负载均衡,并转发给第2个NFV虚拟机】table=0, priority=30,ip,in_port=1000 ,nw_src=1.0.0.0/24 actions=group:3【匹配p4端口和流分类规则, 转发到group:2,做第3跳的出口负载均衡,并转发给第3个NFV虚拟机】table=0, priority=30,ip,in_port=1002 ,nw_src=1.0.0.0/24 actions=NORMAL 【匹配p6(即业务链出端口), 然后走正常转发流程】每一跳出口的sfc报头封装, 在table:5中实现:table=5, priority=0,ip,dl_dst=fa:16:3e:4d:10:37 actions=push_mpls:0x8847,set_field:511->mpls_label,set_mpls_ttl(255),push_vlan:0x8100,set_field:4150->vlan_vid,resubmit(,10) 【匹配发往p1 tap的报文,封装sfc头(这里是mpls),并打上本地vlan, 发往远端计算节点或发给本地table:10】table=5, priority=0,ip,dl_dst=fa:16:3e:b5:64:7e actions=push_mpls:0x8847,set_field:510->mpls_label,set_mpls_ttl(254),push_vlan:0x8100,set_field:4128->vlan_vid,resubmit(,10) 【匹配发往p3 tap的报文,封装sfc头(这里是mpls),并打上本地vlan, 发往远端计算节点或发给本地table:10】table=5, priority=0,ip,dl_dst=fa:16:3e:51:39:b6 actions=push_mpls:0x8847,set_field:509->mpls_label,set_mpls_ttl(253),push_vlan:0x8100,set_field:4169->vlan_vid,resubmit(,10) 【匹配发往p5 tap的报文,封装sfc头(这里是mpls),并打上本地vlan, 发往远端计算节点或发给本地table:10】本地sfc报头解封装,并发往nfv虚拟机, 在table:10中实现:table=10, priority=1,mpls,dl_vlan=54,dl_dst=fa:16:3e:4d:10:37,mpls_label=511 actions=pop_vlan,pop_mpls:0x0800,output:997【p1在本地, 匹配目的mac为p1的业务链1报文, mpls解封装, 并发送p1】table=10, priority=1,mpls,dl_vlan=32,dl_dst=fa:16:3e:b5:64:7e,mpls_label=510 actions=pop_vlan,pop_mpls:0x0800,output:999【p3在本地, 匹配目的mac为p1的业务链1报文, mpls解封装, 并发送p3】table=10, priority=1,mpls,dl_vlan=73,dl_dst=fa:16:3e:51:39:b6,mpls_label=509 actions=pop_vlan,pop_mpls:0x0800,output:1001【p5在本地, 匹配目的mac为p5的业务链1报文, mpls解封装, 并发送p5】

br-int group信息, 这里主要是用来在每个sf出口处做负载均衡的:

group_id=1,type=select,bucket=actions=set_field:fa:16:3e:4d:10:37->eth_dst,resubmit(,5)【修改目的mac为p1 tap口,并转发到table 5】group_id=2,type=select,bucket=actions=set_field:fa:16:3e:b5:64:7e->eth_dst,resubmit(,5)【修改目的mac为p3 tap口,并转发到table 5】group_id=3,type=select,bucket=actions=set_field:fa:16:3e:51:39:b6->eth_dst,resubmit(,5)【修改目的mac为p5 tap口,并转发到table 5】

参考

Was this helpful?

0 / 0

发表回复 0