服务功能链

服务功能链 (SFC) 本质上是指软件定义网络 (SDN) 版本的基于策略的路由 (PBR)。在许多情况下,SFC 涉及安全性,但它也可以包括各种其他功能。

从根本上说,SFC 将数据包路由通过一个或多个服务功能,而不是使用目标 IP 地址进行路由的传统路由。服务功能本质上模拟了一系列通过电缆连接在一起的物理网络设备。

SFC 的一个基本示例是将数据包从一个位置路由到另一个位置,通过一个防火墙,该防火墙缺乏传统路由角度的“下一跳”IP 地址。一个更复杂的示例涉及一系列有序的服务功能,每个功能都使用多个实例 (VM) 实现。数据包必须流经一个实例,并且哈希算法在每个跃点上将流分布到多个实例。

架构

所有 OpenStack Networking 服务和 OpenStack Compute 实例都通过端口连接到虚拟网络,这使得仅使用端口就可以创建一个用于服务链的流量引导模型。将这些端口包含在端口链中,可以实现通过一个或多个提供服务功能的实例来引导流量。

端口链,或服务功能路径,由以下内容组成

  • 一组定义服务功能序列的端口。

  • 一组指定进入链的分类流量流的流分类器。

如果服务功能涉及一对端口,则第一个端口充当服务功能的入口端口,第二个端口充当服务功能的出口端口。如果两个端口使用相同的值,则它们充当单个双向虚拟端口。

端口链是单向服务链。第一个端口充当服务功能链的头部,第二个端口充当服务功能链的尾部。双向服务功能链由两个单向端口链组成。

一个流分类器只能属于一个端口链,以防止在哪个链应该处理流中的数据包时产生歧义。一个检查可以防止这种歧义。但是,您可以将多个流分类器与一个端口链关联,因为多个流可以请求相同的服务功能路径。

目前,SFC 不支持多项目服务功能。

端口链插件支持支持服务提供商,包括 OVS 驱动程序和各种 SDN 控制器驱动程序。通用的驱动程序 API 使不同的驱动程序能够为服务链路径渲染提供不同的实现。

Port chain architecture Port chain model

有关更多信息,请参阅 networking-sfc 文档

资源

端口链

  • id - 端口链 ID

  • project_id - 项目 ID

  • name - 可读名称

  • description - 可读描述

  • port_pair_groups - 端口对组 ID 列表

  • flow_classifiers - 流分类器 ID 列表

  • chain_parameters - 链参数字典

端口链由一系列端口对组组成。每个端口对组是端口链中的一个跃点。一组端口对代表提供等效功能的的服务功能。例如,一组防火墙服务功能。

流分类器标识一个流。端口链可以包含多个流分类器。省略流分类器有效地阻止了通过端口链引导流量。

chain_parameters 属性包含端口链的一个或多个参数。目前,它仅支持一个关联参数,该参数默认为 mpls,以与 Open vSwitch (OVS) 功能保持一致。关联参数的未来值可能包括网络服务头 (NSH)。

端口对组

  • id - 端口对组 ID

  • project_id - 项目 ID

  • name - 可读名称

  • description - 可读描述

  • port_pairs - 服务功能端口对列表

端口对组可以包含一个或多个端口对。多个端口对可以实现对一组功能等效的服务功能的负载均衡/分配。

端口对

  • id - 端口对 ID

  • project_id - 项目 ID

  • name - 可读名称

  • description - 可读描述

  • ingress - 入口端口

  • egress - 出口端口

  • service_function_parameters - 服务功能参数字典

端口对代表一个服务功能实例,包括一个入口端口和一个出口端口。包含双向端口的服务功能使用相同的入口端口和出口端口。

service_function_parameters 属性包括服务功能的一个或多个参数。目前,它仅支持一个关联参数,该参数确定将数据包与链关联。此参数默认为 none,用于不支持关联(如 NSH)的传统服务功能。如果设置为 none,数据平面实现必须提供服务功能代理功能。

流分类器

  • id - 流分类器 ID

  • project_id - 项目 ID

  • name - 可读名称

  • description - 可读描述

  • ethertype - 以太类型 (IPv4/IPv6)

  • protocol - IP 协议

  • source_port_range_min - 最小源协议端口

  • source_port_range_max - 最大源协议端口

  • destination_port_range_min - 最小目标协议端口

  • destination_port_range_max - 最大目标协议端口

  • source_ip_prefix - 源 IP 地址或前缀

  • destination_ip_prefix - 目标 IP 地址或前缀

  • logical_source_port - 源端口

  • logical_destination_port - 目标端口

  • l7_parameters - L7 参数字典

源属性的组合定义了流的源。目标属性的组合定义了流的目标。 l7_parameters 属性是一个占位符,可用于支持使用第 7 层字段(例如 URL)进行流分类。如果未指定,logical_source_portlogical_destination_port 属性默认为 noneethertype 属性默认为 IPv4,并且所有其他属性默认为通配符值。

操作

创建端口链

以下示例使用 openstack 命令行界面 (CLI) 创建一个由三个服务功能实例组成的端口链,以处理从 192.0.2.11:1000 到 198.51.100.11:80 的 HTTP (TCP) 流量流。

  • 实例 1

    • 名称:vm1

    • 功能:防火墙

    • 端口对:[p1, p2]

  • 实例 2

    • 名称:vm2

    • 功能:防火墙

    • 端口对:[p3, p4]

  • 实例 3

    • 名称:vm3

    • 功能:入侵检测系统 (IDS)

    • 端口对:[p5, p6]

注意

示例网络 net1 必须在创建其上的端口之前存在。

  1. 获取拥有 net1 网络的项目的凭据。

  2. 在网络 net1 上创建端口并记录 UUID 值。

    $ openstack port create p1 --network net1
    $ openstack port create p2 --network net1
    $ openstack port create p3 --network net1
    $ openstack port create p4 --network net1
    $ openstack port create p5 --network net1
    $ openstack port create p6 --network net1
    
  3. 使用端口 p1p2 启动服务功能实例 vm1,使用端口 p3p4 启动 vm2,以及使用端口 p5p6 启动 vm3

    $ openstack server create --nic port-id=P1_ID --nic port-id=P2_ID vm1
    $ openstack server create --nic port-id=P3_ID --nic port-id=P4_ID vm2
    $ openstack server create --nic port-id=P5_ID --nic port-id=P6_ID vm3
    

    P1_IDP2_IDP3_IDP4_IDP5_IDP6_ID 替换为各自端口的 UUID。

    注意

    此命令需要其他选项才能成功启动实例。有关更多信息,请参阅 CLI 参考

    或者,您可以先使用一个网络接口启动每个实例,然后再附加其他端口。

  4. 创建流分类器 FC1,以匹配适当的数据包头。

    $ openstack sfc flow classifier create \
      --description "HTTP traffic from 192.0.2.11 to 198.51.100.11" \
      --ethertype IPv4 \
      --source-ip-prefix 192.0.2.11/32 \
      --destination-ip-prefix 198.51.100.11/32 \
      --protocol tcp \
      --source-port 1000:1000 \
      --destination-port 80:80 FC1
    

    注意

    在使用 (默认) OVS 驱动程序时,还需要 --logical-source-port 参数

  5. 使用端口 p1p2 创建端口对 PP1,使用端口 p3p4 创建 PP2,以及使用端口 p5p6 创建 PP3

    $ openstack sfc port pair create \
      --description "Firewall SF instance 1" \
      --ingress p1 \
      --egress p2 PP1
    
    $ openstack sfc port pair create \
      --description "Firewall SF instance 2" \
      --ingress p3 \
      --egress p4 PP2
    
    $ openstack sfc port pair create \
      --description "IDS SF instance" \
      --ingress p5 \
      --egress p6 PP3
    
  6. 使用端口对 PP1PP2 创建端口对组 PPG1,以及使用端口对 PP3 创建 PPG2

    $ openstack sfc port pair group create \
      --port-pair PP1 --port-pair PP2 PPG1
    $ openstack sfc port pair group create \
      --port-pair PP3 PPG2
    

    注意

    您可以重复 --port-pair 选项以指定功能等效的服务功能的多个端口对。

  7. 使用端口对组 PPG1PPG2 以及流分类器 FC1 创建端口链 PC1

    $ openstack sfc port chain create \
      --port-pair-group PPG1 --port-pair-group PPG2 \
      --flow-classifier FC1 PC1
    

    注意

    您可以重复 --port-pair-group 选项以指定端口链中的其他端口对组。端口链必须包含至少一个端口对组。

    您可以重复 --flow-classifier 选项以指定端口链的多个流分类器。每个流分类器标识一个流。

更新端口链或端口对组

  • 使用 openstack sfc port chain set 命令动态添加或删除端口链上的端口对组或流分类器。

    • 例如,将端口对组 PPG3 添加到端口链 PC1

      $ openstack sfc port chain set \
        --port-pair-group PPG1 --port-pair-group PPG2 --port-pair-group PPG3 \
        --flow-classifier FC1 PC1
      
    • 例如,将流分类器 FC2 添加到端口链 PC1

      $ openstack sfc port chain set \
        --port-pair-group PPG1 --port-pair-group PPG2 \
        --flow-classifier FC1 --flow-classifier FC2 PC1
      

      SFC 将匹配附加流分类器的流量引导到端口链中的端口对组。

  • 使用 openstack sfc port pair group set 命令执行动态扩展或缩减操作,方法是在端口对组上添加或删除端口对。

    $ openstack sfc port pair group set \
      --port-pair PP1 --port-pair PP2 --port-pair PP4 PPG1
    

    SFC 在端口对组中的其他服务功能上执行负载均衡/分配。