

























本文参考 Calico 官网生产实践:基于 IP 的 Calico 架构
该模型下,两种模式中 Leaf 交换机的路由表数量是一致的,区别仅为谁来承担 BGP Peer 带来的连接压力。

如上图所示,L2 Spine 模式下 Spine 是纯二层交换机,所有 Leaf 建立 eBGP 连接(AS 号不一样),这样会导致 Leaf 交换机承担了所有连接压力:
公式中为什么要 /2,因为 A 跟 B 建立了连接,在 B 处就不能算这条连接了...跟阶梯式九九乘法表一个逻辑
在上图中可能这么一个疑问:L2 Spine 的纯二层交换机有什么意义呢?

如上图所示,L3 Spine 模式下 Spine 是三层交换机,具有路由功能,每台 Leaf 只和几台 Spine 建 eBGP 联系。这样就由性能更强的 Spine 交换机承担所有的 eBGP 连接:
N 为 Spine 交换机,S 为 Leaf 交换机
以 100 台 Leaf 交换机、4 台 Spine 交换机为例:每台 Spine 交换机建立 100 条 eBGP 连接,4 台就是 400 条
该模型将 "每台机架作为 AS 自治系统" 这一概念做到了极致。在前文引用的 IETF RFC 7938 文档中,其整体模型所的假设是:机架顶层交换机(ToR)是第一层的聚合与路由单元。而在 Calico 架构中,即使三层交换机 ToR 具有路由能力,但它实际处于的架构层级也只是第二层,因为服务器本身才是第一层路由器/聚合点:Pod 流量最先也是最后到达的都是服务器上的路由栈。
因此,该模型将 AS 边界从机架上的 ToR 变为了机架中的服务器。
但同机架两台服务器通信必须走 ToR,原因纯碎是 BGP 拓扑结构决定的:
那这样做的意义并不大 😢,况且每台服务器一个 AS 编号,管理成本太高了...

参考 1.1.L2 Spine 模式,仅有机架内服务器是否作为路由器来用这一个区别

参考 1.2.L3 Spine 模式,仅有机架内服务器是否作为路由器来用这一个区别

在前面两种模型中,Calico BGP 路由反射器(RR Leaf)通过 eBGP 连接上层 Spine 交换机,这就带来一个问题:
所以 Calico 官方提供了一种名为 Downward Default 的模型,用于解决 Leaf 交换机压力问题。在此模型中,路由传递遵循原则:
这样 Leaf 只需要记住本机柜(Rack)的 Pod 路由,不需要学习其他机柜的路由,可以大幅降低路由表规模。当一个 Pod 需要访问另一个 Pod 时:
另一方面,为防止网络中其他节点的路由因被识别为源自本地 AS 而无法被成功安装,AS 号会在路由路径的每一个阶段被移除。此处"移除 AS"并不是说配置中删去 asNumber,而是指:BGP 路由的每个阶段都移除 AS Path 内容。假设一条 Pod 路由是这样的:
每经过一个 AS 后,BGP 会把自己的 AS 号追加到 AS Path 前面(最左)。所以 Worker2 收到这条路由时,AS Path 是:
由于 eBGP 防环规则(iBGP 不会修改 AS Path,只有 eBGP 传递), Worker2 一看 AS Path 里面有自己的 AS 号,直接就丢了,也就是被防环机制拒绝了。这时会有一个疑问:既然 BGP 防环靠的就是 AS Path,把它去掉后靠什么防环?
a. 路由通告自下而上:Pod --> Leaf --> Spine,转递 Pod 全量路由,通过 AS Path 防环;
b. 转发请求自上而下:Spine --> Leaf --> Pod,转递 default 路由,每层传递的都是新的默认路由,只有一个 AS 号,所以没有环路。
不过,也正是因为这种路由方式,导致该模型有一个较小的缺点:如果目标 IP 不存在,流量都会在被丢弃之前转发到脊交换机。
root@network-demo:~# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP
calico-bgp-rr-control-plane-downward-default Ready control-plane 140m v1.27.3 10.1.5.10
calico-bgp-rr-worker-downward-default Ready <none> 139m v1.27.3 10.1.5.11
calico-bgp-rr-worker2-downward-default Ready <none> 139m v1.27.3 10.1.8.10
calico-bgp-rr-worker3-downward-default Ready <none> 139m v1.27.3 10.1.8.11
root@network-demo:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-0 1/1 Running 0 134m 10.244.81.64 calico-bgp-rr-control-plane-downward-default
pod-1 1/1 Running 0 134m 10.244.210.64 calico-bgp-rr-worker-downward-default
pod-2 1/1 Running 0 134m 10.244.192.0 calico-bgp-rr-worker2-downward-default
pod-3 1/1 Running 0 134m 10.244.205.68 calico-bgp-rr-worker3-downward-default
## 可以看到 Node 路由表中没有任何去往其他子网 Pod 的路由
## 比如说请求 10.244.192.0,那只能走 default
root@network-demo:~# docker exec -it calico-bgp-rr-control-plane-downward-default ip route show
## Leaf 下发的默认路由
default via 10.1.5.1 dev net0
10.1.5.0/24 dev net0 proto kernel scope link src 10.1.5.10
## 同子网 Pod 直连
10.244.205.64 dev cali668ffc72609 scope link
blackhole 10.244.205.64/26 proto bird
10.244.205.65 dev cali9d019fb9159 scope link
10.244.205.66 dev cali288bfe3097a scope link
10.244.205.67 dev cali34eb2d98f00 scope link
## 本机 Pod 直连
10.244.205.68 dev cali87081bf6f89 scope link
## Docker 创建时带的,不用管
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.4
## 对比 "Calico BGP Route Reflectors 路由反射器" 一文中 Leaf 路由表
## 可以看出没有任何发往其他机柜(跨子网)路由,只有同子网下路由(Downward Default 核心效果)
root@network-demo:~# docker exec -it clab-calico-bgp-rr-leaf0 vtysh -c "show ip bgp"
BGP table version is 6, local router ID is 10.1.5.1, vrf id 0
Default local pref 100, local AS 64512
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
## 这条默认路由就是上面讲的 b,从 spine 传递过来的是一条新路由,只有 spine 的 as 号
## 而 leaf 往下给 k8s node 默认路由,via 是 leaf 的,而不是把 spine 传给 leaf 的这条转给 k8s node
*= 0.0.0.0/0 10.1.12.2 0 0 800 i
*> 10.1.10.2 0 0 500 i
*> 10.1.5.0/24 0.0.0.0 0 32768 i
## containerlab 配置直连 spine0 的接口
*> 10.1.10.0/24 0.0.0.0 0 32768 i
## containerlab 配置直连 spine1 的接口
*> 10.1.12.0/24 0.0.0.0 0 32768 i
## 去往 worker 节点的路由
## AS Path 为 65500,说明是从 k8s node 发过来的
*> 10.244.81.64/26 10.1.5.11 0 65500 i
## 去往 control-plane 节点的路由
## AS Path 为 65500,说明是从 k8s node 发过来的
*> 10.244.205.64/26 10.1.5.10 0 65500 i
## 通过内核路由表验证,所有不知道怎么走的路由全给 Spine 了
root@network-demo:~# docker exec -it clab-calico-bgp-rr-leaf0 ip route show
default nhid 26 proto bgp metric 20
nexthop via 10.1.10.2 dev eth1 weight 1
nexthop via 10.1.12.2 dev eth2 weight 1
10.1.5.0/24 dev eth3 proto kernel scope link src 10.1.5.1
10.1.10.0/24 dev eth1 proto kernel scope link src 10.1.10.1
10.1.12.0/24 dev eth2 proto kernel scope link src 10.1.12.1
10.244.81.64/26 nhid 38 via 10.1.5.11 dev eth3 proto bgp metric 20
10.244.205.64/26 nhid 36 via 10.1.5.10 dev eth3 proto bgp metric 20
172.20.20.0/24 dev eth0 proto kernel scope link src 172.20.20.3
root@network-demo:~# docker exec -it clab-calico-bgp-rr-leaf0 ip route show proto bgp
default nhid 26 metric 20
nexthop via 10.1.10.2 dev eth1 weight 1
nexthop via 10.1.12.2 dev eth2 weight 1
10.244.81.64/26 nhid 38 via 10.1.5.11 dev eth3 metric 20
10.244.205.64/26 nhid 36 via 10.1.5.10 dev eth3 metric 20
root@network-demo:~# docker exec -it clab-calico-bgp-rr-spine0 vtysh -c "show ip bgp"
BGP table version is 10, local router ID is 10.1.10.2, vrf id 0
Default local pref 100, local AS 500
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
## AS Path 64512,两台 Leaf 通告的
*> 10.1.5.0/24 10.1.10.1 0 0 64512 i
*> 10.1.8.0/24 10.1.34.1 0 0 64512 i
## 同一个网段有两条路径,选择了最优的(>)
## 在 spine0 的配置里把这个直连网段通过 ipv4-unicast 发布出去,让其他设备能学到
* 10.1.10.0/24 10.1.10.1 0 0 64512 i
*> 0.0.0.0 0 32768 i
*> 10.1.11.0/24 10.1.34.1 0 0 64512 i
*> 10.1.12.0/24 10.1.10.1 0 0 64512 i
* 10.1.34.0/24 10.1.34.1 0 0 64512 i
*> 0.0.0.0 0 32768 i
## 从 k8s node 一路 eBGP 向上通告过来的
*> 10.244.81.64/26 10.1.10.1 0 64512 65500 i
*> 10.244.192.0/26 10.1.34.1 0 64512 65500 i
*> 10.244.205.64/26 10.1.10.1 0 64512 65500 i
*> 10.244.210.64/26 10.1.34.1 0 64512 65500 i
root@network-demo:~# docker exec -it clab-calico-bgp-rr-spine0 ip route show
default via 172.20.20.1 dev eth0
10.1.5.0/24 nhid 22 via 10.1.10.1 dev eth1 proto bgp metric 20
10.1.8.0/24 nhid 20 via 10.1.34.1 dev eth2 proto bgp metric 20
10.1.10.0/24 dev eth1 proto kernel scope link src 10.1.10.2
10.1.11.0/24 nhid 20 via 10.1.34.1 dev eth2 proto bgp metric 20
10.1.12.0/24 nhid 22 via 10.1.10.1 dev eth1 proto bgp metric 20
10.1.34.0/24 dev eth2 proto kernel scope link src 10.1.34.2
10.244.81.64/26 nhid 22 via 10.1.10.1 dev eth1 proto bgp metric 20
10.244.192.0/26 nhid 20 via 10.1.34.1 dev eth2 proto bgp metric 20
10.244.205.64/26 nhid 22 via 10.1.10.1 dev eth1 proto bgp metric 20
10.244.210.64/26 nhid 20 via 10.1.34.1 dev eth2 proto bgp metric 20
172.20.20.0/24 dev eth0 proto kernel scope link src 172.20.20.5
root@network-demo:~# docker exec -it clab-calico-bgp-rr-spine0 ip route show proto bgp
10.1.5.0/24 nhid 22 via 10.1.10.1 dev eth1 metric 20
10.1.8.0/24 nhid 20 via 10.1.34.1 dev eth2 metric 20
10.1.11.0/24 nhid 20 via 10.1.34.1 dev eth2 metric 20
10.1.12.0/24 nhid 22 via 10.1.10.1 dev eth1 metric 20
10.244.81.64/26 nhid 22 via 10.1.10.1 dev eth1 metric 20
10.244.192.0/26 nhid 20 via 10.1.34.1 dev eth2 metric 20
10.244.205.64/26 nhid 22 via 10.1.10.1 dev eth1 metric 20
10.244.210.64/26 nhid 20 via 10.1.34.1 dev eth2 metric 20
如果机房 Leaf/Spine 层设备能够存储集群中的路由表(当前 + 后续可能的),建议采用 AS Per Rack 每台机架作为 AS 自治系统
如果机房 Leaf/Spine 层设备不能存储集群中的路由表,建议采用 Downward Default
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。