亚马逊AWS官方博客

亚马逊云科技 VPC 网络中的路由冗余方案

我们的客户在 VPC 中部署生产业务的时候,为保证应用在出现意外故障的时候仍然可以正常提供服务,需要借助各种高可用方案。通常 VPC 中的高可用实现可以分为两大类:一类为应用级别的冗余,另外一类为网络级别的冗余。

应用冗余和网络冗余

应用冗余

应用冗余是指在一个应用程序模块中使用多个相同的组件来增加系统的可靠性。在这种方式下,组成一个应用程序模块的组件通常是无状态的,即应用不会在服务模块本地维护客户端会话的状态信息,会话信息存储在外部数据库中,以保证任何一个应用服务模块都可以独立处理任何客户端的请求。客户端在访问应用程序模块时,需要一种流量分发机制来将请求均衡地分发到模块的多个组件中。同时为保证服务的可靠性,流量分发机制需要及时发现不能正常提供服务的组件并将其排除在流量分发的目标之外。在 VPC 网络中,常用的流量分发机制为使用负载均衡器(ALB:Application Load Balancer 应用负载均衡器 / NLB:Network Load Balancer 网络负载均衡器)或 Route53 DNS 解析服务,这两种服务都提供了内建的健康检查功能用于自动检测和移除不健康的目标组件。

应用冗余是在 VPC 中部署高可用应用所使用的最常见方式,我们推荐用户在部署应用时首先考虑使用这种方式实现高可用。

图 1: 使用 ELB(Elastic Load Balancer)实现应用高可用

图 2:使用 Route53 健康检查实现应用高可用

网络冗余

有些客户需要在 VPC 中部署虚拟网络设备,例如防火墙、虚拟路由器等。这些虚拟网络设备被称作 VNF(virtual network function)。VNF 通常不是应用数据报文的最终目的,而是网络路径中的中间节点,所以也经常被称作 middle box。当  VNF 软件或者承载 VNF 的底层资源发生故障时,VNF 将无法正常提供服务,造成该节点所在网络路径的中断,从而影响关联的应用无法正常提供服务。这就要求 VNF 承载的网络功能同样需要高可用设计,以保证其提供的网络功能不会因单个 VNF 节点故障造成中断。

由于 VNF 不是应用数据报文的最终目的,前面提到的基于负载均衡器或 DNS 的应用冗余手段无法应用于 VNF。VNF 的高可用需要与应用冗余不同的机制,这一类机制通常是在网络层面实现的。传统数据通信网络技术中积累了非常丰富的多层次的冗余机制。由于在 VPC 网络中已经内建了底层网络连接的高可用机制,VNF 的网络冗余设计仅需要关注 IP 层。传统网络中的冗余机制有些可以直接使用在 VPC 网络中,有些需要进行适当的配置调整,有些则完全不适用。VPC 中实现网络冗余的常用机制包括:

  • 事件驱动的路由更新(通常为 keepalived)
  • BGP 动态路由更新
  • Gateway Load Balancer

等等。

在本博客中我们来详细介绍几个常用的 VPC 网络路由冗余解决方案。

AWS VPC 中的网络路由冗余解决方案

网络路由冗余解决方案的考虑因素

在选择不同的网络路由冗余解决方案时,您可能需要针对以下因素进行初步评估。

  1. 最大可以容忍的网络中断时间

不同的应用对网络中断的敏感程度不同。应用对于故障恢复时间的要求使用 RTO(Recovery Time Objective)来定义。一般情况下,关键应用需要更短的故障恢复时间。另外,还应该充分考虑到客户端到服务端的网络路径可能跨越多个网络基础设施或网络提供商,端到端的网络中断时间依赖于这些网络基础设施和网络提供商的整体表现。在计划端到端的网络故障 RTO 时,需要根据所跨越网络的具体能力设计切合实际的目标值。例如,期望的端到端故障恢复时间不能少于所依赖的任一关键基础设施所能提供的最好能力。

  1. 解决方案所需的运行成本

较快的故障恢复方案通常要求更高的资源成本支出。这些资源包括冗余的网络线路、冗余的带宽配置或者具有更高硬件配置的网络设备等等。在比较不同的网络路由冗余解决方案时,需要评估方案所需的较高成本是否能带来与之匹配的业务价值,即由较高成本方案提供的较低网络中断时间,其减少的业务损失是否与方案所要求的成本增加相匹配。

  1. 方案的复杂度如何,以及维护方案正常工作所需要的网络专业能力

一些网络路由冗余方案依赖特定的网络协议,例如 BGP,BFD,VRRP 等。完整的方案通常需要在多个网络节点之间组合配置多种网络协议。在实施和维护这类方案时,需要用到专门的网络协议知识和调试排错能力。在采用这类方案之前,您需要确认您有相匹配的专业技术资源和预算,以发挥方案的完整能力。

解决方案 1:基于 keepalived 的主备切换

Keepalived 是一种使用虚拟 IP(Virtual IP,VIP)实现高可用的网络解决方案。Keepalived 是 IP 网络协议 VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)在主机上的实现,在主流的 Linux 操作系统和 Windows 操作系统中均有支持。VRRP 的原理是一组节点(称为虚拟路由器组)共同关联一个虚拟 IP 对外提供网络访问。这一组节点通过 VRRP 协议确定一个主节点,所有与虚拟 IP 相关的网络访问均由主节点来完成。虚拟路由器组成员通过 VRRP 协议定期交换节点活动信息,一旦主节点发生故障,未能在预定的时间通告自身状态,则由剩余节点选举出新的主节点,替换原有主节点提供虚 IP 的网络访问,从而保证网络服务的连续性。

路由器上通常使用保留组播地址承载 VRRP 协议。虽然 AWS 的 VPC 网络提供了组播能力,但是暂不支持保留组播。在 VPC 网络中使用 VRRP(keepalived)时,需要使用单播模式。在 VPC 中使用的虚拟 IP 地址有两种可能的分配方式:使用辅助 IP(secondary IP)或者独立的网络接口(Elastic Network Interface – ENI)。在 VPC 中,每个网络接口都包含一个主 IP(primary IP)。在主 IP 之外,一个网络接口还可以分配一定数量的额外 IP 做为辅助 IP。虚拟 IP 的一种分配方式是使用辅助 IP,但是辅助 IP 在使用上有一些限制。辅助 IP 必须与主 IP 位于相同的子网,这就限制了使用辅助 IP 做为虚拟 IP 的节点组必须位于同一个子网内,即这些节点只能在部署在同一个可用区,从而降低了节点组可用性。另外一种更推荐的虚拟 IP 分配方式是使用独立的网络接口。每个 EC2 实例都包含一个缺省的网络接口。除此之外,EC2 实例还可以附加额外的网络接口(EC2 实例可支持的网络接口数量与实例规格相关,具体数量请参考用户文档)。这个独立的网络接口的主 IP 或者辅助 IP 可以用作虚拟 IP。该网络接口可以灵活地附加到同 VPC 的 EC2 实例上,也可以随时从 EC2 中解除关联,从而实现虚拟 IP 与节点的关联。

上面描述的方案中所涉及的虚拟 IP 均为私网 IPv4 地址。通过创建弹性公网 IP 并与私网 IP 关联,所关联的弹性公网 IP 同样可以做为 VIP 来使用。此方案同样适用于 IPv6,差别在于 IPv6 地址可以直接提供公网访问而无需关联弹性公网 IP。

图 3:使用 keepalived 和 Elastic Network Interface 实现 VNF 高可用

Keepalived 方案配置示例

以下配置示例基于 Amazon Linux 2 操作系统。部分脚本需要使用 aws 命令行工具,并关联操作弹性网卡需要的 IAM 权限策略。

Node-1: /etc/keepalived/keepalived.conf

! node-1 configuration

vrrp_script health_check {
    script /etc/keepalived/health-check.sh
    interval 2
}

vrrp_instance VI_1 {
    debug 2
    interface eth0
    virtual_router_id 10
    priority 100
    advert_int 1
    unicast_peer {
        <node-2 ip address>
    }

    ! check node health (optional)
    track_script {
        health_check
    }
    
    ! triggered when this node becomes master
    notify_master /etc/keepalived/i-am-master.sh
}

Node-2: /etc/keepalived/keepalived.conf

! node-2 configruation

vrrp_script health_check {
    script /etc/keepalived/health-check.sh
    interval 2
}

vrrp_instance VI_1 {
    debug 2
    interface eth0
    virtual_router_id 10
    priority 100
    advert_int 1
    unicast_peer {
        <node-1 ip address>
    }
    
    ! check node health (optional)
    track_script {
        health_check
    }
    
    ! triggered when this node becomes master
    notify_master /etc/keepalived/i-am-master.sh
}

Node-1/2: /etc/keepalived/i-am-master.sh

#!/bin/bash
ENI=<!!!enixxxxx!!!> 
#Note: this script is based on EC2 IMDSv1 
METADATA=http://169.254.169.254/latest/meta-data/instance-id

# get ENI attachment information

attach=$(aws ec2 describe-network-interface-attribute --network-interface-id $ENI --attribute attachment)

# check if ENI has already been attached to this instance
inst=$(curl -qs $METADATA)
attachedInst=$(echo $attach | jq -r ".Attachment.InstanceId")

if [ $inst == $attachedInst ]; then
    exit 0
fi

# get attachment ID and detach it
id=$(echo $attach | jq -r ".Attachment.AttachmentId")

if [[ $id == eni-attach-* ]]; then
  aws ec2 detach-network-interface --attachment-id $id
fi

# attach to this instance
aws ec2 attach-network-interface --network-interface-id $ENI --instance-id $inst --device-index 1

在 VPC 中使用 VRRP/keepalived 实现 VNF 高可用时,需要在路由表中将 keepalived 节点组的 VIP(即 ENI 的私有 IP)设置为路由表的下一跳 IP。如果 VNF 提供公网访问,则需要分配一个弹性公网 IP 与 VIP 关联,VNF 的公网访问通过该弹性公网 IP 来提供。

需要注意的是,ENI 具有子网属性,只能与相同可用区的实例绑定。

解决方案 2:使用 AWS Transit Gateway 和 BGP 协议实现 ECMP

AWS Transit Gateway 是一种具有强大网络连接能力的虚拟网络设备。AWS Transit Gateway 可以为 VPC 提供多种网络连接服务,包括多个 VPC 之间互联,VPC 与 Direct Connection 互联及 VPC 与 IPSec VPN 互联等。AWS Transit Gateway 还提供了将第三方的虚拟网络设备(例如防火墙)集成到网络路径中的能力。在这种方式下,Transit Gateway 通过 GRE 隧道(称为 Connect Attachment)与虚拟网络设备进行通信,并通过 BGP 协议与虚拟网络设备交换动态路由信息。使用 BGP 协议可以实现路由条目的动态更新,从而减少手工配置的工作量,避免路由配置错误。在虚拟网络设备发生故障的时候,BGP 协议可以及时感知并更新路由信息,避免因此造成网络连接中断。BGP 协议支持等价路由(Equal Cost Multiple Path – ECMP,等价多路径),在这种方式下,多个虚拟网络设备可以同时承载流量。而在传统的主备模式下,同一时刻仅有一个主设备提供服务,通常会造成资源的浪费。

使用 Transit Gateway 的 BGP 等价路由方式,流量会自动分配到多个虚拟网络设备,虚拟网络设备所提供的容量可以得到充分的利用。同时,如果某个虚拟网络设备发生故障,流量会在其余正常工作的网络设备之间重新分配,实现网络能力的高可用。

需要注意的是,某些虚拟网络功能是基于会话的,例如 TCP 的连接状态,网络地址转换的端口映射关系等等。由于虚拟网络设备保存了会话信息,这要求同一组会话的网络报文必须由同一个虚拟网络设备来处理。在这种情况下,需要启用 Transit Gateway 的 appliance mode,以保证 Transit Gateway 可以将同一组会话的报文发送到同一个虚拟网络设备。

图 4:使用 Transit Gateway 和 BGP 动态路由实现 VNF 高可用

解决方案 3:使用 Gateway Load Balancer 实现 NFV 高可用

有些网络设备被设置为工作在透明网络模式(BITW,Bump in The Wire),例如防火墙、入侵检测系统(IDS)、入侵防护系统(IPS)、深度报文检测(DPI)等 。工作在透明模式的虚拟网络设备在三层(IP 层)不可见,不适用 BGP 动态路由及 ECMP 等基于路由等高可用机制。

AWS Gateway Load Balancer(GWLB) 服务将透明的网络网关与负载均衡器相结合,该负载均衡器可进行健康检查、分发流量并根据需求扩展虚拟网络设备。这项服务使部署、扩展和管理第三方虚拟网络设备(如防火墙、IDS/IPS、云中的深度数据报文检测系统)的可用性变得简单且经济高效。除了安全设备之外,GWLB 还为数据分析、电信、物联网(IoT)和自定义设备提供同样的好处。AWS 合作伙伴网络AWS Marketplace 合作伙伴还可以为 AWS 客户提供虚拟网络设备即服务,而无需用户自己解决规模、可用性和服务交付等复杂问题。

GWLB 在与虚拟网络设备通信时使用 GENEVE 隧道封装,将原始的网络报文完整地发送给虚拟网络设备。任何支持 GENEVE 封装的开源网络设备软件(例如 suricatavyos)可以方便地与 GWLB 集成。您可以从这个博客文章了解更多与 GWLB 集成的细节。对于没有内置 GENEVE 隧道封装能力的网络应用,您可以参考 AWS 提供的示例代码来实现虚拟网络设备与 GWLB 的集成。

由于不需要 BGP 动态路由协议,基于 GWLB 提供高可用的虚拟网络能力的 VPC 网络配置与 Transit Gateway 相比大大简化。您只需要调整 VPC 子网路由表,将需要处理的流量转发到 GWLB 端点,相应的流量就会被分发给 GWLB 后端的虚拟网络设备进行处理。需要注意的是您需要保证双向的流量均被转发到同一个 GWLB 端点,以保证虚拟网络设备可以处理网络连接的完整会话。

图 5:使用 Gateway Load Balancer 实现 VNF 高可用

结论

在本文中我们讨论了几种常见的 VPC 中应用高可用能力的提供方式。这些方式针对不同的应用需求,提供不同的能力,同时复杂度、成本也不同。

在可能的情况下,我们推荐使用负载均衡或者 DNS 方式实现应用的高可用,这种方式复杂度最低,容易扩展,可移植性较好,更符合“云原生”的理念。

我们也介绍了使用网络路由提供冗余能力的方案,这一类方案特别针对虚拟网络设备(例如防火墙、虚拟路由器)的场景。网络路由冗余的解决方案包括 keepalived 虚拟网卡 ENI 的重新绑定,使用 Transit Gateway 和 BGP 动态路由实现 ECMP 多路径转发,及使用 Gateway Load Balancer 实现多个虚拟网络设备的多活高可用。相对于使用 Transit Gateway 的解决方案,Gateway Load Balancer 无需配置动态路由,部署和维护更加简便,是优先建议考虑的方案。

本文中所描述的解决方案的复杂程度、故障恢复时间和成本各有不同,匹配不同的业务需求。下表比较了这些方案的关键特点,您可以参考下表选择合适的网络路由冗余方案。

方案名称 主备 多活 方案复杂度 方案成本 故障恢复时间 其它
Keepalived ENI 虚拟网卡重新绑定 支持 不支持 数秒~数十秒
Transit Gateway BGP 动态路由 支持 支持 数十秒~100+秒 需支持 GRE 及 BGP
Gateway Loadbalancer 不支持 支持 数秒~数十秒 需支持 GENEVE

本篇作者

刘俊辉

亚马逊云科技高级解决方案架构师,在通信、互联网、云计算行业有多年从业经验,对云原生产品技术及解决方案有非常深入的理解。长期跟踪云计算前沿技术动态,目前专注于亚马逊云科技初创生态。