为满足用户的业务数据安全、稳定等需求,提供各种基础保障或增值优化服务,在传统网络中,经常使用业务功能节点(如负载均衡、防火墙等)实现服务供应。但这些业务功能节点往往与网络拓扑和硬件资源耦合紧密,各个业务功能节点均为专用的设备形态且部署繁杂。当开通新业务或业务流程发生变更时,需要更改网络拓扑,甚至改造和升级网络设备,对周边的支撑系统也会有影响。
随着云计算网络的普及、虚拟化技术的成熟和应用,网络功能动态加载,资源按需分配,业务灵活开通等特点明显加强,而服务供应也必不可少。如果还使用传统网络的服务供应部署方式,已无法满足云计算网络灵活多变的组网特点、客户多种多样的业务需求。因此,服务链 SFC 技术被提出,该技术从满足客户业务数据安全、稳定等需求角度出发,更契合新时代网络特点,使业务功能灵活性得到更大的发挥。
SFC ( Service Function Chain 服务链)是由一系列业务节点有序构成,各业务节点可对数据流量进行流量检查、处理等操作。通过将用户数据报文依照业务逻辑以此通过各业务功能节点,就能轻松实现 SFC 服务链功能。随着云服务市场规模的扩大,在云内实现 SFC 也有着庞大的市场需求。
SFC 大部分通过 NSH 标准化服务链技术实现,但这些方案仍存在一定程度的限制:配置时需要根据流量的转发路径,基于每条业务流,依次在各个业务节点上逐跳配置。当 SFC 服务链扩容时,其配置复杂度也随之几何上升。由此可见,现有方案操作复杂,可扩展性差,不利于 SFC 的落地推广。
近年来随着云计算、大数据、物联网、人工智能等信息技术的快速发展和传统产业的数字化转型,数据量呈现几何级增长,同时计算成本快速下降,数字经济正进入算力时代。在算力网络中使用 IPv6 作为新一代 IP 承载协议,由此衍生了许多 IP 新技术。其中, SRv6 ( Segment Routing IPv6 )技术通过 IPv6 扩展头的方式,基于现有 IPV6 转发技术,实现了网络可编程化。
若能利用 SRv6 的路由编排特性实现 SFC ,将大幅简化 SFC 逐跳配置的繁杂度,并且也适应新时代大规模网络的发展。因此本文将探索基于 SRv6 技术支持 SFC 的实现,并尝试在云环境中实现该方案。
以城域网中 SRv6 使用场景为例,基于 SRv6 的 SFC 方案主要由用于下发服务链路径信息的( SDN 控制器)、业务分类节点( SC )、服务转发节点( SFF )和服务链集群( SFC Domain )组网构成。
如上图,服务供应商可通过 SDN 控制器向 SFC 业务分类节点下发服务链配置信息。服务链配置信息组织了 SFC 服务域中服务器路径次序,如:( VBRAS, FW, CGN, Server ) 、 ( VBRAS,FW ) 、( CGN, Server ) 等。
SC 和 SFF 将以 SRv6 隧道的形式为业务数据提供服务链。其中, SC 负责将业务流量导入 SRv6 隧道中, SFF 负责将业务流量传递到具体的服务供应机器。详细运作过程如下图:
当用户发起访问,业务数据经过 SC 时, SC 将业务数据引入到 SRv6 隧道中进行转发。业务数据随后传递到 SFF , SFF 解读报文中的路径信息,并按信息次序传递数据包到具体的服务链机器( SF )中处理,之后数据包被返还到 SFF , SFF 按路径信息传递到下一个 SFF 或者隧道尾节点。
数据包经过各服务器成功处理后,到达尾节点时,报文中服务链信息部分将被剥去,并按原始业务数据路径被传递。
SID 标记路径
服务链信息(即服务器地址序列)以 SID 的形式被封装在 IPv6 SRH 扩展头中,作为 SRv6 报文在上文所述的 SRv6 TE Policy 中流转。同时, SC 、 SFF 等地址也可以用 SID 来标记,引导报文路径。因此 SID 相当于网络中的位置标记,其值可使用 IPv6 地址。
不同的 SID 其对应的处理逻辑也不一样。比如 SFF 需要解析并保存 SRv6 报文信息,将数据包分发给不同的 SF ,如果 SF 不支持 SRv6 、 IPv6 等,在分发前 SFF 还需要解封 SRv6 外层报文等等。所以节点在收到 SDN 控制器下发的服务链配置信息后,也会在本地建立相应的 SID 表( Local SID Table ) 。
因此,依据 SID 对应的不同操作,可将其分类如下:
报文转发过程
在 SRv6 TE Policy 中 SC 节点、 SFF 节点、尾节点对 SRv6 报文的转发操作如下:
上文通过城域网中基于 SRv6 的 SFC 应用场景,梳理了 SFC 的实现流程。而在通用服务器中实现服务链功能,则需要系统实现 srv6 技术。目前 linux 系统从 4.10 开始已有支持。
Linux SRv6 协议栈
模型图
在机器中部署 namesapce 模拟 SRv6 网络节点。host 1 请求 host 4 的流量将被引导到 SRv6 封装中,经过 host 2 和 host 3 节点处理后再发送到 host 4。host 4 收到 host1 的请求中不带有 SRv6 报文,对 SRv6 过程不感知。
其中 host1 通过 route 命令对原始报文执行 SRv6 封装操作;host2 作为中间转发节点,通过 route 命令对 SRv6 报文执行转发操作;host3 作为 SRv6 过程的尾节点,通过 route 命令配置剥除 SRv6 报文,并将原始报文发送到目标机器 host4 中。
测试方法
执行如下脚本:
#!/bin/bash
TMUX=4hs1sw
# Kill tmux previous session
tmux kill-session -t $TMUX 2>/dev/null
# Clean up the previous network namespaces
for ns in h1 h2 h3 h4 switch; do
ip netns delete ${ns} 2>/dev/null
done
ip netns add h1
ip netns add h2
ip netns add h3
ip netns add h4
ip netns add switch
ip -netns switch link add veth1 type veth peer name enp0s8 netns h1
ip -netns switch link add veth2 type veth peer name enp0s8 netns h2
ip -netns switch link add veth3 type veth peer name enp0s8 netns h3
ip -netns switch link add veth4 type veth peer name enp0s8 netns h4
###################
#### Node: h1 #####
###################
echo -e "\nNode: h1"
ip netns exec h1 sysctl -w net.ipv6.conf.all.forwarding=1
ip -netns h1 link set dev lo up
ip -netns h1 link set dev enp0s8 address 00:00:00:00:00:01
ip -netns h1 addr add fc00::1/64 dev enp0s8
ip -netns h1 link set dev enp0s8 up
ip -netns h1 -6 route add fcf0:12::100 via fc00::2
# 2 SIDs here!
# - fcf0:12::100 steers the packet to node h2 where the SRv6 End function is
# applied (SL=1 on ingress -> SL=0 on egress)
#
# - fcf0::23::6006 steers the packet to node h3 where the decap function is
# applied (SL=0 on ingress)
ip -netns h1 -6 route add fc00::4 encap seg6 mode encap \
segs fcf0:12::100,fcf0:23::6006 dev enp0s8
###################
#### Node: h2 #####
###################
echo -e "\nNode: h2"
ip netns exec h2 sysctl -w net.ipv6.conf.all.forwarding=1
ip -netns h2 link set dev lo up
ip -netns h2 addr add fc00::2/64 dev enp0s8
ip -netns h2 link set dev enp0s8 address 00:00:00:00:00:02
ip -netns h2 link set dev enp0s8 up
ip -netns h2 -6 route add fcf0:23::6006 via fc00::3
# apply the SRv6 End function for updating the active SID
ip -netns h2 -6 route add fcf0:12::100 encap seg6local action End dev enp0s8
###################
#### Node: h3 #####
###################
echo -e "\nNode: h3"
ip netns exec h3 sysctl -w net.ipv6.conf.all.forwarding=1
ip -netns h3 link set dev lo up
ip -netns h3 addr add fc00::3/64 dev enp0s8
ip -netns h3 link set dev enp0s8 address 00:00:00:00:00:03
ip -netns h3 link set dev enp0s8 up
# apply the SRv6 End.DT6 function to decap the packet and to deliver
# the inner packet to host h4.
ip -netns h3 -6 route add fcf0:23::6006 encap seg6local \
action End.DT6 table 254 dev enp0s8
# all the hosts are in the same network...
#
# +-----+---------------------------------+-----+
# - decap packet: | ... | IPv6 DA=fc00:1, SA=fc00::4, ... | ... |
# +-----+---------------------------------+-----+
#
# host h3 tries to route the decap packet and it finds out that such
# packet can be sent directly from node h1 to node h4.
# As a result, the node h3 sends an icmpv6 redirect packet to host h1.
# We do not want to send this packet to the host h1, so we filter it.
ip netns exec h3 ip6tables -t mangle -A POSTROUTING \
-p icmpv6 --icmpv6-type redirect -j DROP
###################
#### Node: h4 #####
###################
echo -e "\nNode: h4"
ip netns exec h4 sysctl -w net.ipv6.conf.all.forwarding=1
ip -netns h4 link set dev lo up
ip -netns h4 addr add fc00::4/64 dev enp0s8
ip -netns h4 link set dev enp0s8 address 00:00:00:00:00:04
ip -netns h4 link set dev enp0s8 up
#######################
#### Node: switch #####
#######################
echo -e "\nNode: switch"
ip -netns switch link set dev lo up
ip -netns switch link set dev veth1 up
ip -netns switch link set dev veth2 up
ip -netns switch link set dev veth3 up
ip -netns switch link set dev veth4 up
ip -netns switch link add sw0 type bridge
ip -netns switch link set dev sw0 up
ip -netns switch link set dev veth1 master sw0
ip -netns switch link set dev veth2 master sw0
ip -netns switch link set dev veth3 master sw0
ip -netns switch link set dev veth4 master sw0
sleep 1
## Create a new tmux session
tmux new-session -d -s $TMUX -n h1 ip netns exec h1 bash
tmux new-window -t $TMUX -n h2 ip netns exec h2 bash
tmux new-window -t $TMUX -n h3 ip netns exec h3 bash
tmux new-window -t $TMUX -n h4 ip netns exec h4 bash
tmux new-window -t $TMUX -n switch ip netns exec switch bash
tmux set-option -g mouse on
tmux select-window -t :0
tmux attach -t $TMUX
SREXT 实现 unaware SRv6 SFC 代理
linux 协议栈中已经实现了 srv6 封装、解封、转发的功能。但在目前 SFC 应用场景中, SF 不一定能支持 IPv6 ,需要有 unaware srv6 的代理实现来过渡支持。这方面可通过加载 srext 内核模块来实现。
模型图
部署三个虚机,分别模拟入口节点(ingress),出口节点(egress)和 unaware srv6 服务端代理节点(nfv)。
其中 nfv 节点上有三个 namespace ,模拟 unaware srv6 服务端。
当数据进入 nfv 节点中, srext 将剥除 srv6 部分报文并发送到 vnf namespace 中,待 vnf namespace 处理完后,又将 srv6 部分重新封装到报文中,继续向下一个 srv6 节点发送。
以 client ping server 的请求过程为例,报文处理过程如下图所示:
测试方法
https://netgroup.github.io/SRv6-net-prog/testbed-basic.html
在云环境中实现基于 SRv6 的 SFC 方案,需要在 OVS 中实现 SRv6 的操作,控制面可通过 SDN Controller 把 SFC 的编排路径下发到 OVS 流表中, OVS 依据流表配置,将业务链信息压入 SRv6 报文中并转发,由此实现 SFC 业务操作。
OVS 中实现 SRv6 转发
模型图
在云环境中, SFC 的部署可能与客户机器在同一个或者不同节点上,两者对 SRv6 数据包的操作大致一样。用户对 OVS 将流量引至 SFC 的过程无感知。
当用户和 SFC 在不同节点上时, OVS 对业务流量操作如下:
测试方法
为验证 OVS 对 SFC 业务的 SRv6 过程,在此简化模型如下:
在该模型中验证 OVS 对 SRv6 的封装、转发和解封。其中 namespace1 和 namespace4 模拟业务通信的客户机, namespace2 和 namespace3 模拟 SF ,但这里使用的 namespace 并不具备真正的 SF 功能,因此并未对数据包进行任何操作,只是转发给 OVS ,以此验证 OVS 功能。
https://pan.baidu.com/s/1u2cMprwoTE4-MePA9kEnBg?pwd=u67f
云内基于 SRv6 的 SFC 方案
云环境中基于 OVS 实现 SFC 方案通过在 OVS 中配置服务链信息流表规则,简化逐跳策略路由配置的繁杂步骤,实现服务链业务的快速部署。该方案支持 IPv4/IPv6 双栈的业务流量,在 SFC 中通过使用 SREXT 支持 unaware SRv6 的 SF 接入,即也支持 IPv4/IPv6 双栈 SF 。
模型图
云环境中基于 OVS 实现 SFC 方案最小部署方案如下:
user-domain 和 server-domain 上可部署业务访问源和目标,分别接入 OVS 中两个不同的 port ;sfc-domain 作为服务链域机器,其上可部署具体的服务链应用,在此模型中使用三个不同的 vnf 模拟应用容器。考虑到目前许多环境未支持 SRv6 ,此处用 IPv4 来模拟, SF 中的应用都使用 IPv4 中即可。
OVS 中 user1-port 和 user2-port 作为 SFC SRv6 过程的起止端点,绑定了两个 SID (1:2::1, 2:3::2)作为服务链( SID List )中的起止 SID 。
在部署 sfc-domain 时,将具体的 SF 及其 ipv4 地址写入 Local SID Table 中,并使用两个接口(sfc-domain:ens3, sfc-domain:ens10)分别作为 SFC 域的出入接口对接 OVS 的 port (proxy0-port, proxy1-port)。这两个接口(ens3:[1:2::2], ens10:[2:3::1])分别与 OVS 起止 SID 在同一网段。
上图是以 tcp 消息请求过程为例的流量模型。其主要过程如下:
测试方法
综上,本文讨论了 SFC 服务链应用,及其在 linux 中的实现方案,以及在云环境中基于 SRv6 的实现方案,以探索算力网络时代下 SFC 在云环境中的快速部署。模型较为简单,开发仍在不断完善中。