Title here
Summary here
在大规模 Calico 集群中,Full Mesh 拓扑会产生 O(n²) 的 BGP 连接数,导致严重的扩展性问题。路由反射器(Route Reflector,RR)通过引入层次化结构,将连接数降低到 O(n),是大规模部署的关键技术。
iBGP 规定:从 iBGP 邻居学到的路由不能再通告给其他 iBGP 邻居。这是为了防止路由环路。
解决方案:
| 路由来源 | 反射目标 | 是否反射 |
|---|---|---|
| RR Client | 其他 RR Clients | 是 |
| RR Client | 非 Client iBGP | 是 |
| 非 Client iBGP | RR Clients | 是 |
| 非 Client iBGP | 非 Client iBGP | 否 |
| eBGP | 所有 iBGP | 是 |
RR 在反射路由时会添加/修改以下属性:
优点:资源隔离,RR 稳定性高 缺点:需要额外节点
优点:充分利用现有节点 缺点:Master 负载增加
优点:极佳扩展性 缺点:配置复杂
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
nodeToNodeMeshEnabled: false
asNumber: 64512calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
nodeToNodeMeshEnabled: false
asNumber: 64512
EOF# 添加标签
kubectl label node master-1 route-reflector=true
kubectl label node master-2 route-reflector=true
kubectl label node master-3 route-reflector=true# 为每个 RR 配置相同的集群 ID
calicoctl patch node master-1 -p '{"spec": {"bgp": {"routeReflectorClusterID": "224.0.0.1"}}}'
calicoctl patch node master-2 -p '{"spec": {"bgp": {"routeReflectorClusterID": "224.0.0.1"}}}'
calicoctl patch node master-3 -p '{"spec": {"bgp": {"routeReflectorClusterID": "224.0.0.1"}}}'集群 ID 选择:
- 使用点分十进制格式
- 同一集群内的 RR 使用相同 ID
- 不同集群使用不同 ID
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rr-mesh
spec:
# 所有 RR 节点
nodeSelector: has(route-reflector)
# 与其他 RR 节点对等
peerSelector: has(route-reflector)apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: client-to-rr
spec:
# 非 RR 节点
nodeSelector: "!has(route-reflector)"
# 与所有 RR 对等
peerSelector: has(route-reflector)// confd/pkg/backends/calico/bgp_processor.go:530-550
func (c *client) buildPeerFromData(peer *bgpPeer, ...) *types.BirdBGPPeer {
// ...
// 路由反射器处理
// 如果本节点是 RR(有 cluster ID)且对等是 iBGP 且对等不在同一集群
if result.ASNumber == effectiveNodeAS && nodeClusterID != "" {
if peer.RRClusterID == "" || peer.RRClusterID != nodeClusterID {
result.RouteReflector = true
result.RRClusterID = nodeClusterID
}
}
return result
}生成的 BIRD 配置:
protocol bgp 'Node_10_0_0_10' {
local as 64512;
neighbor 10.0.0.10 as 64512;
# RR 配置
rr client;
rr cluster id 224.0.0.1;
import all;
export filter {
calico_export_to_bgp_peers(true);
reject;
};
}| 集群规模 | RR 数量 | 部署位置 |
|---|---|---|
| 100-200 | 2-3 | 跨可用区 |
| 200-500 | 3-5 | 跨可用区 |
| 500+ | 5-7 或分层 | 跨区域 |
客户端配置了多个 RR 对等,单个 RR 故障时自动切换到其他 RR。
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
nodeMeshMaxRestartTime: 120s # 优雅重启超时apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: client-to-rr
spec:
nodeSelector: "!has(route-reflector)"
peerSelector: has(route-reflector)
maxRestartTime: 120s # 对等级别的优雅重启| 节点数 | Full Mesh 连接 | 3 RR 连接 | 节省比例 |
|---|---|---|---|
| 100 | 4,950 | 303 | 94% |
| 500 | 124,750 | 1,503 | 99% |
| 1000 | 499,500 | 3,003 | 99.4% |
# 使用拓扑感知分配 RR 客户端
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rack1-to-rr
spec:
nodeSelector: topology.kubernetes.io/zone == 'zone-a'
peerSelector: route-reflector == 'true' && topology.kubernetes.io/zone == 'zone-a'
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rack2-to-rr
spec:
nodeSelector: topology.kubernetes.io/zone == 'zone-b'
peerSelector: route-reflector == 'true' && topology.kubernetes.io/zone == 'zone-b'# 查看节点 BGP 状态
calicoctl node status
# 预期输出
# Calico process is running.
#
# IPv4 BGP status
# +---------------+-------------------+-------+----------+-------------+
# | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
# +---------------+-------------------+-------+----------+-------------+
# | 10.0.0.11 | node-to-node mesh | up | 10:00:00 | Established |
# | 10.0.0.12 | node-to-node mesh | up | 10:00:00 | Established |
# +---------------+-------------------+-------+----------+-------------+# 进入 calico-node
kubectl exec -it -n kube-system calico-node-xxxxx -c calico-node -- /bin/sh
# 查看协议状态
birdc show protocols
# 查看详细状态
birdc show protocols all Node_10_0_0_10
# 查看路由
birdc show route
# 查看 RR 客户端路由
birdc show route where from = 10.0.0.10| 问题 | 症状 | 解决方案 |
|---|---|---|
| RR 未配置集群 ID | 路由不反射 | 设置 routeReflectorClusterID |
| Mesh 未禁用 | 连接数过多 | 设置 nodeToNodeMeshEnabled: false |
| 对等配置错误 | BGP 会话不建立 | 检查 nodeSelector/peerSelector |
| 集群 ID 冲突 | 路由环路 | 确保 ID 唯一性 |
#!/bin/bash
# deploy-rr.sh
# 1. 禁用 mesh
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
nodeToNodeMeshEnabled: false
asNumber: 64512
EOF
# 2. 标记 RR 节点
kubectl label node master-1 route-reflector=true --overwrite
kubectl label node master-2 route-reflector=true --overwrite
# 3. 配置集群 ID
calicoctl patch node master-1 -p '{"spec": {"bgp": {"routeReflectorClusterID": "1.0.0.1"}}}'
calicoctl patch node master-2 -p '{"spec": {"bgp": {"routeReflectorClusterID": "1.0.0.1"}}}'
# 4. RR 互联
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rr-mesh
spec:
nodeSelector: has(route-reflector)
peerSelector: has(route-reflector)
EOF
# 5. 客户端到 RR
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: client-to-rr
spec:
nodeSelector: "!has(route-reflector)"
peerSelector: has(route-reflector)
EOF
# 6. 验证
echo "等待 BGP 会话建立..."
sleep 30
calicoctl node status# 1. 查看当前状态
calicoctl node status
# 2. 模拟 RR 故障(drain 节点)
kubectl drain master-1 --ignore-daemonsets --delete-emptydir-data
# 3. 观察客户端切换
watch calicoctl node status
# 4. 恢复节点
kubectl uncordon master-1
# 5. 验证恢复
calicoctl node status# 为不同区域配置 RR
# Zone A
kubectl label node zone-a-master route-reflector=true zone=a
calicoctl patch node zone-a-master -p '{"spec": {"bgp": {"routeReflectorClusterID": "1.0.0.1"}}}'
# Zone B
kubectl label node zone-b-master route-reflector=true zone=b
calicoctl patch node zone-b-master -p '{"spec": {"bgp": {"routeReflectorClusterID": "1.0.0.2"}}}'
# RR 互联
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rr-inter-zone
spec:
nodeSelector: has(route-reflector)
peerSelector: has(route-reflector)
EOF
# Zone A 客户端到 Zone A RR
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: zone-a-client-to-rr
spec:
nodeSelector: zone == 'a' && !has(route-reflector)
peerSelector: route-reflector == 'true' && zone == 'a'
EOF
# Zone B 客户端到 Zone B RR
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: zone-b-client-to-rr
spec:
nodeSelector: zone == 'b' && !has(route-reflector)
peerSelector: route-reflector == 'true' && zone == 'b'
EOF路由反射器是大规模 Calico 集群的关键组件:
最佳实践: