Anycast从原理到实践

了解Anycast

说起anycast很多小伙伴可能不清它到底是什么,其实它并不是什么新技术,早在1993年就被提出,我们把它翻译过来就是"任意播",这个就和我们平常听到的"单播"、"组播"、"广播"就很相似了,没错它们都是相同的概念。anycast就像是"组播"和"单播"的结合,它的核心思想就是:一个 IP 地址,多个端点,路由到最优的一个端点。

anycast在公有云也被广泛的应用,常见的服务有:腾讯云-anycast加速阿里云-anycast-eip

参考:

RFC 1546: Host Anycasting Service

RFC 4786: Operation of Anycast Services

Anycast的优势与短板

优势

  1. 多个后端接入实现负载均衡,对网络拥堵和DDoS 攻击的自然保护

  2. 当后端的网络出现故障时,无需人为干预路由会被指向目前可达的最优后端,实现高可用

  3. 可根据路由策略调整请求的后端,保证低延迟

短板

  1. 需要bgp协议的支持

  2. anycast的IP无法作为源IP发出请求:例如外网anycast IP无法作为出口IP,因为服务端的回包不难准确的发送的请求发出的后端

适用场景

最适用、最常见的Anycast场景是基于UDP、无状态的、一问一答的场景,我们已经广泛应用在DNS、Nginx、Haproxy、Kubeapiserver等应用上

Anycast改造

Anycast 的操作基本上基于边界网关协议(BGP),这是使互联网路由器能够在自治系统之间交换路由信息的标准路由协议。在 Anycast 设置中,不同位置的多个服务器向 BGP 路由基础设施宣布相同的 IP 地址。当对此 Anycast IP 地址发出请求时,BGP 路由确保它根据当前的网络条件到达拓扑上最近的服务器。

FRR配置优化

通过配置BFD for BGP功能,为BGP提供更为快速的故障检测机制,提高网络收敛速度。

python 复制代码
router bgp xxx
 bgp router-id xxx
 bgp graceful-restart
 bgp graceful-restart preserve-fw-state
 neighbor 10.48.x.x remote-as xxx
 neighbor 10.48.x.x bfd ### 添加

使用redistribute匹配route-map的方式发布路由

python 复制代码
address-family ipv4 unicast
  redistribute kernel
  redistribute connected route-map V4VIP ### 添加
  neighbor 10.48.x.x soft-reconfiguration inbound
  neighbor 10.48.x.x route-map from-gw in
  neighbor 10.48.x.x route-map to-gw out
  maximum-paths 16
 exit-address-family
!
ip prefix-list V4VIP-LIST seq 10 permit 10.48.xxx.0/26 ge 32  ### 添加申请的vip网段
ip prefix-list V4VIP-LIST seq 1000 deny any  ### 添加
!
route-map V4VIP permit 1
 match interface dummy0   ### 添加至允许dummy0的网口发出的IP
 match ip address prefix-list V4VIP-LIST  ### 添加匹配V4VIP-LIST规则
!

需要注意点问题

不同机房发布路由的方式需要一致

使用network发布的路由和 redistribute发布的路由优先级不一样,network会比redistribute优先,导致路由无均衡。(network -> igp,redistribute->incomplete)

故障迁移

网络异常

服务器宕机、网络不通,交换机异常等情况,因为网络异常bgp路由会自动销毁,该情况无需人工介入

服务异常

当网络都正常的事实,服务因为某种原因崩溃,请求还是会持续转发到异常后端。为了避免这种问题带来的影响,我们需要添加服务检测脚本,当服务异常的时候我们就主动撤销bgp路由,从而实现故障自动隔离

shell 复制代码
# /opt/cloudsa/check_bgp_vip.sh
#!/bin/bash
valid_services=("nginx" "haproxy" "named" "kube-apiserver" "kubelet" "etcd")

if [ $# -ne 1 ] || ! [[ " ${valid_services[*]} " =~ " $1 " ]]; then
    echo "Usage: $0 ( ${valid_services[*]} )"
    exit 1
fi

i="0"
while [ $i -lt 60 ]
do
    i=$[$i+4]
    /bin/pidof "$1"
    if [ $? -ne 0 ] ; then
        /sbin/ifdown dummy0
    else
        /sbin/ifup dummy0
    fi
    sleep 4
done

# /etc/cron.d/check_bgp_vip 定时任务
* * * * * root /bin/bash /opt/cloudsa/check_bgp_vip.sh haproxy >/dev/null 2>&1

服务器半死不活

服务器网络、服务都正常,因为自身原因(例如:磁盘抖动,网络抖动),该情况就需要通过告警和预案来进行快速恢复了

相关推荐
yuren_xia2 小时前
Spring Boot中保存前端上传的图片
前端·spring boot·后端
JohnYan5 小时前
Bun技术评估 - 04 HTTP Client
javascript·后端·bun
shangjg35 小时前
Kafka 的 ISR 机制深度解析:保障数据可靠性的核心防线
java·后端·kafka
青莳吖6 小时前
使用 SseEmitter 实现 Spring Boot 后端的流式传输和前端的数据接收
前端·spring boot·后端
我的golang之路果然有问题7 小时前
ElasticSearch+Gin+Gorm简单示例
大数据·开发语言·后端·elasticsearch·搜索引擎·golang·gin
cooldream20097 小时前
利用 Scrapy 构建高效网页爬虫:框架解析与实战流程
爬虫·scrapy·架构
扎Zn了老Fe8 小时前
掌握系统架构(三):打造高性能、高可用、可伸缩技术架构
架构·后端开发
mldong8 小时前
我的全栈工程师之路:全栈学习路线分享
前端·后端
噼里啪啦啦.9 小时前
SpringBoot统一功能处理
java·spring boot·后端
考虑考虑9 小时前
JPA自定义sql参数为空和postgresql遇到问题
spring boot·后端·spring