抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

MetalLB负载均衡器

在这里插入图片描述

概述

​ 在k8s中创建service时,需要指定type类型,可以分别指定ClustrerIP,NodePort,LoadBalancer三种,其中前面两种无论在内网还是公网环境下使用都很常见,只有LoadBalancer大部分情况下只适用于支持外部负载均衡器的云提供商(AWS,阿里云,华为云等)使用。

​ 如果想要在内网环境中,使用type=LoadBalancer就需要部署另外的插件,下面主要介绍一下MetalLB组件。

MetalLB介绍

熟悉k8s的都知道,k8s的LoadBalancer类型的Service依赖于外部的云提供的Load Balancer。

​ 当我们把k8s部署在裸机上面时,或者是测试环境时,需要简单的LoadBalancer来验证工作,开源的metallb就是一个不错的选择

​ Metallb一开始是挂在github.com/google下面的,估计是某个员工的个人项目,现在已经挂到了个人名下,它的作用就是通过k8s原生的方式提供LB类型的Service支持,开箱即用。

MetalLB功能

MetalLB 提供了两个功能

地址分配

用户需要在配置中提供一个地址池,Metallb 将会在其中选取地址分配给服务

​ 当创建 LoadBalancer Service 时,MetalLB 会为其分配 IP 地址,这个 IP 地址是从预先配置的 IP 地址库获取的。同样,当 Service 删除后,已分配的 IP 地址会重新回到地址库。

​ 在公有云环境下,当购买或指定一个负载均衡器时,云平台将为用户分配一个IP地址,通过这个IP地址就能实现LoadBalancer,而在私有云集群中,MetalLB将负责IP地址的分配。

​ MetalLB无法凭空创建IP地址,因此需要在配置过程中为MetalLB指定一个IP地址池,当服务创建或者删除时,MetalLB负责从IP地址池中分配或者销毁服务对应的IP地址。

对外广播

分配了 IP 地址之后,需要让集群外的网络知道这个地址的存在,MetalLB 使用了标准路由协议实现:ARP、NDP 或者 BGP

在这里插入图片描述

工作原理

Metallb包含两个组件,Controller和Speaker,Controller为Deployment部署方式,而Speaker则采用daemonset方式部署到Kubernetes集群各个Node节点

​ 具体的工作原理如下图所示,Controller负责监听service变化,当service配置为LoadBalancer模式时,从IP池分配给到相应的IP,并进行IP的生命周期管理。Speaker则依据Service的变化,按具体的协议发起相应的广播或应答,根据工作模式(Layer2/BGP)的不同,可采用Leader的方式或负载均衡的方式来响应请求

​ 当业务流量通过TCP/UDP协议到达指定的Node时,由Node上面运行的Kube-Proxy组件对流量进行处理,并分发到对应的Pod上面。

Kubernetes负载均衡器:Metallb_Kubernetes_02

工作模式

MetalLB支持两种模式,一种是Layer2模式,一种是BGP模式

Layer2模式

第2层模式下,Metallb会在Node节点中选出一台做为Leader,与服务IP相关的所有流量都会流向该节点。在该节点上, kube-proxy将流量传播到所有服务的Pod,而当leader节点出现故障时,会由另一个节点接管。

局限性

在二层模式中会存在以下两种局限性:单节点瓶颈以及故障转移慢的情况。

​ 单个leader选举节点接收服务IP的所有流量。这意味着服务的入口带宽被限制为单个节点的带宽,单节点的流量处理能力将成为整个集群的接收外部流量的瓶颈。

​ 在当前的实现中,节点之间的故障转移取决于客户端的合作,当发生故障转移时,MetalLB发送许多2层数据包,以通知客户端与服务IP关联的MAC地址已更改。大多数操作系统能正确处理数据包,并迅速更新其邻居缓存,在这种情况下,故障转移将在几秒钟内发生。

​ 在计划外的故障转移期间,在有故障的客户端刷新其缓存条目之前,将无法访问服务IP。对于生产环境如果要求毫秒性的故障切换,目前Metallb可能会比较难适应要求

BGP模式

在BGP模式下,群集中的每个节点都与网络路由器建立BGP对等会话,并使用该对等会话通告外部群集服务的IP

​ 假设您的路由器配置为支持多路径,则可以实现真正的负载平衡:MetalLB发布的路由彼此等效,这意味着路由器将一起使用所有下一跳,并在它们之间进行负载平衡。数据包到达节点后,kube-proxy负责流量路由的最后一跳,将数据包送达服务中的一个特定容器

局限性

​ 基于BGP的路由器实现无状态负载平衡,他们通过对数据包头中的某些字段进行哈希处理,并将该哈希值用作可用后端数组的索引,将给定的数据包分配给特定的下一跳。
​ 但路由器中使用的哈希通常不稳定,因此,只要后端集的大小发生变化(例如,当节点的BGP会话断开时),现有连接就会被随机有效地重新哈希,这意味着大多数现有连接连接最终将突然转发到另一后端,而该后端不知道所讨论的连接

安装 MetalLB

环境要求

根据部署模式不同,MetalLB 可能需要以下环境:

  1. 一个 Kubernetes 集群,运行 Kubernetes 1.13.0 或更高版本。
  2. Kubernetes 集群的网络配置可以与 MetalLB 共存。
  3. 有一些提供给 MetalLB 分发的 IPv4 地址。
  4. 根据部署模式,可能需要一个或多个 BGP 的路由器 。
网络插件支持

MetalLB 目前支持网络插件范围

网络插件 兼容性
Calico 部分支持(有附加文档)
Flannel 支持
Kube-router 不支持
Romana 支持(有附加文档)
Weave Net 支持

从 Kubernetes 1.9 开始, Kube-Proxy 除了支持默认的 Iptables 模式之外,还支持更高效的 IPVS 模式。

开启ARP模式

如果 k8s 中 kube-proxy 使用 ipvs 模式,最新版本(即高于v1.14.2)需要开启 strict ARP 模式

注意,如果使用 kube-router 作为服务代理,则不需要这个,因为它默认启用严格的 ARP

1
2
kubectl edit configmap -n kube-system kube-proxy
# 修改其中的 strictARP 为 true,下面字段不是连续的上下行,只展示了需要注意的行数
1
2
3
4
5
6
7
...
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
...

image-20221209093823928

生效配置

保存退出后就会生效配置

image-20220713114811795

准备资源清单

Metallb 支持 yaml文件、Kustomize、Helm 和 MetalLB Operator多种安装方法,这里使用yaml方式进行安装

下载资源清单
1
2
wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml

因为网络等原因可能导致下载文件困难,这里将具体配置列出来

命名空间配置
1
vi namespace.yaml
1
2
3
4
5
6
apiVersion: v1
kind: Namespace
metadata:
name: metallb-system
labels:
app: metallb
MetalLB资源清单
1
vi metallb.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
labels:
app: metallb
name: controller
spec:
allowPrivilegeEscalation: false
allowedCapabilities: []
allowedHostPaths: []
defaultAddCapabilities: []
defaultAllowPrivilegeEscalation: false
fsGroup:
ranges:
- max: 65535
min: 1
rule: MustRunAs
hostIPC: false
hostNetwork: false
hostPID: false
privileged: false
readOnlyRootFilesystem: true
requiredDropCapabilities:
- ALL
runAsUser:
ranges:
- max: 65535
min: 1
rule: MustRunAs
seLinux:
rule: RunAsAny
supplementalGroups:
ranges:
- max: 65535
min: 1
rule: MustRunAs
volumes:
- configMap
- secret
- emptyDir
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
labels:
app: metallb
name: speaker
spec:
allowPrivilegeEscalation: false
allowedCapabilities:
- NET_RAW
allowedHostPaths: []
defaultAddCapabilities: []
defaultAllowPrivilegeEscalation: false
fsGroup:
rule: RunAsAny
hostIPC: false
hostNetwork: true
hostPID: false
hostPorts:
- max: 7472
min: 7472
- max: 7946
min: 7946
privileged: true
readOnlyRootFilesystem: true
requiredDropCapabilities:
- ALL
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- configMap
- secret
- emptyDir
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: metallb
name: controller
namespace: metallb-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: metallb
name: speaker
namespace: metallb-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app: metallb
name: metallb-system:controller
rules:
- apiGroups:
- ''
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- services/status
verbs:
- update
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resourceNames:
- controller
resources:
- podsecuritypolicies
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app: metallb
name: metallb-system:speaker
rules:
- apiGroups:
- ''
resources:
- services
- endpoints
- nodes
verbs:
- get
- list
- watch
- apiGroups: ["discovery.k8s.io"]
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resourceNames:
- speaker
resources:
- podsecuritypolicies
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app: metallb
name: config-watcher
namespace: metallb-system
rules:
- apiGroups:
- ''
resources:
- configmaps
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app: metallb
name: pod-lister
namespace: metallb-system
rules:
- apiGroups:
- ''
resources:
- pods
verbs:
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app: metallb
name: controller
namespace: metallb-system
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- create
- apiGroups:
- ''
resources:
- secrets
resourceNames:
- memberlist
verbs:
- list
- apiGroups:
- apps
resources:
- deployments
resourceNames:
- controller
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app: metallb
name: metallb-system:controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: metallb-system:controller
subjects:
- kind: ServiceAccount
name: controller
namespace: metallb-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app: metallb
name: metallb-system:speaker
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: metallb-system:speaker
subjects:
- kind: ServiceAccount
name: speaker
namespace: metallb-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: metallb
name: config-watcher
namespace: metallb-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: config-watcher
subjects:
- kind: ServiceAccount
name: controller
- kind: ServiceAccount
name: speaker
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: metallb
name: pod-lister
namespace: metallb-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-lister
subjects:
- kind: ServiceAccount
name: speaker
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: metallb
name: controller
namespace: metallb-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: controller
subjects:
- kind: ServiceAccount
name: controller
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: metallb
component: speaker
name: speaker
namespace: metallb-system
spec:
selector:
matchLabels:
app: metallb
component: speaker
template:
metadata:
annotations:
prometheus.io/port: '7472'
prometheus.io/scrape: 'true'
labels:
app: metallb
component: speaker
spec:
containers:
- args:
- --port=7472
- --config=config
- --log-level=info
env:
- name: METALLB_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: METALLB_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: METALLB_ML_BIND_ADDR
valueFrom:
fieldRef:
fieldPath: status.podIP
# needed when another software is also using memberlist / port 7946
# when changing this default you also need to update the container ports definition
# and the PodSecurityPolicy hostPorts definition
#- name: METALLB_ML_BIND_PORT
# value: "7946"
- name: METALLB_ML_LABELS
value: "app=metallb,component=speaker"
- name: METALLB_ML_SECRET_KEY
valueFrom:
secretKeyRef:
name: memberlist
key: secretkey
image: quay.io/metallb/speaker:v0.12.1
name: speaker
ports:
- containerPort: 7472
name: monitoring
- containerPort: 7946
name: memberlist-tcp
- containerPort: 7946
name: memberlist-udp
protocol: UDP
livenessProbe:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_RAW
drop:
- ALL
readOnlyRootFilesystem: true
hostNetwork: true
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: speaker
terminationGracePeriodSeconds: 2
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Exists
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: metallb
component: controller
name: controller
namespace: metallb-system
spec:
revisionHistoryLimit: 3
selector:
matchLabels:
app: metallb
component: controller
template:
metadata:
annotations:
prometheus.io/port: '7472'
prometheus.io/scrape: 'true'
labels:
app: metallb
component: controller
spec:
containers:
- args:
- --port=7472
- --config=config
- --log-level=info
env:
- name: METALLB_ML_SECRET_NAME
value: memberlist
- name: METALLB_DEPLOYMENT
value: controller
image: quay.io/metallb/controller:v0.12.1
name: controller
ports:
- containerPort: 7472
name: monitoring
livenessProbe:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
nodeSelector:
kubernetes.io/os: linux
securityContext:
runAsNonRoot: true
runAsUser: 65534
fsGroup: 65534
serviceAccountName: controller
terminationGracePeriodSeconds: 0

应用配置

1
2
kubectl apply -f namespace.yaml
kubectl apply -f metallb.yaml

image-20220713134325857

查看状态

查看运行的pods,metalLB包含两个部分,controllerspeaker

1
kubectl get pod -o wide -n metallb-system

image-20220713134527972

其中controllerdeploymentspeaker是DaemonSet

1
2
kubectl get deployment -n  metallb-system
kubectl get daemonset -n metallb-system

image-20220713153033681

目前还没有宣布任何内容,因为我们没有提供ConfigMap,也没有提供负载均衡地址的服务

部署组件说明

部署完成后,将在 metallb-system 命名空间下将 MetalLB 部署到集群,YAML 文件中主要包含以下一些组件

  1. metallb-system/controller,这是处理 IP 地址分配的控制器。
  2. metallb-system/speakerdaemonset 这是支持你选择协议以使服务可达的组件。
  3. ControllerSpeakerService Accounts,以及组件需要运行的 RBAC 权限

通过 YAML 安装文件部署并不包含 MetalLB 配置文件,但 MetalLB 的组件仍能启动,但在你定义和部署 configmap 之前将保持空闲状态

Layer 2 模式(ARP/NDP)

在二层模式下,一个节点承担向本地网络发布服务的责任,从网络的角度看,这台机器看起来好像已经为其网络接口分配了多个IP地址。

​ 二层模式的主要优点是它的通用性,可以在任何以太网网络上运行,不需要特殊的硬件(路由器等)

负载均衡

在二层模式下,服务IP的所有流量都流向一个节点,从那里, kube-proxy将流量传播到所有服务的Pod。

​ 从这个意义上讲,二层没有实现负载平衡器,相反,它实现了故障转移机制,以便当当前的领导节点由于某种原因发生故障时,另一个节点可以接管。

​ 如果领导节点由于某种原因失败,则故障转移是自动的,此时新节点将接管发生故障的节点的IP地址所有权。

局限性

单节点瓶颈

单个领导者当选节点接收服务IP的所有流量,这意味着服务的入口带宽被限制为单个节点的带宽。

​ 在当前的实现中,节点之间的故障转移取决于客户端的合作。当发生故障转移时,MetalLB发送大量免费的二层数据包,以通知客户端与服务IP关联的MAC地址已更改。

故障转移速度慢

​ 所有主要版本的现代操作系统(Windows,Mac,Linux)都能正确处理“免费”数据包,并迅速更新其邻居缓存。在这种情况下,故障转移将在几秒钟内发生。但是,某些系统要么根本不执行免费处理,要么存在错误的实现,从而延迟了缓存的更新。

配置Layer2模式

创建config.yaml提供IP地址池,修改ip地址池,从集群IP地址段中为MetalLB分配部分IP地址

创建资源清单
1
vi metallb.layer2.config.yaml

注意下面分配地址池为 192.168.245.100-192.168.245.150 ,这里和集群节点位于同一个网段

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.245.100-192.168.245.150
应用配置
1
2
kubectl apply -f metallb.layer2.config.yaml
kubectl get pod -o wide -n metallb-system

image-20220713141720349

请求测试

创建测试环境
创建资源清单

创建一个包含了deployment和一个LoadBalancer类型的service的测试用例

1
vi loadBalancer-test.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.io/library/nginx:1.20
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
应用配置
1
2
kubectl apply -f loadBalancer-test.yaml
kubectl get pod -o wide

image-20220713142400967

查看service

查看service分配的EXTERNAL-IP

1
kubectl get service

我们发现已经分配了IP地址

image-20220713142538123

访问测试
外部访问

从集群外访问该IP地址

1
curl 192.168.245.100

image-20220713142705521

通过宿主机浏览器也可以进行访问了

image-20220713142732703

工作原理

Layer 2 中的 Speaker 工作负载是 DeamonSet 类型,在每台节点上都调度一个 Pod

​ 首先,几个 Pod 会先进行选举,选举出 Leader。Leader 获取所有 LoadBalancer 类型的 Service,将已分配的 IP 地址绑定到当前主机到网卡上。也就是说,所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上。

​ 当外部主机有请求要发往集群内的某个 Service,需要先确定目标主机网卡的 mac 地址,这是通过发送 ARP 请求,Leader 节点的会以其 mac 地址作为响应,外部主机会在本地 ARP 表中缓存下来,下次会直接从 ARP 表中获取。

​ 请求到达节点后,节点再通过 kube-proxy 将请求负载均衡目标 Pod,所以说,假如Service 是多 Pod 这里有可能会再跳去另一台主机。

99acf3c894dad9da6f5cc00e6803c8b3.png

BGP模式

BGP 是边界网关协议(Border Gateway Protocol)的缩写

BGP概述

边界网关协议是互联网上一个核心的去中心化自治路由协议。

​ 它通过维护IP路由表或“前缀”表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。

​ BGP的邻居关系(或称通信对端/对等实体,peer)是通过人工配置实现的,对等实体之间通过TCP端口179建立会话交换数据。BGP路由器会周期地发送19字节的保持存活(keep-alive)消息来维护连接(默认周期为60秒)。在各种路由协议中,只有BGP使用TCP作为传输层协议。

​ 同一个AS自治系统中的两个或多个对等实体之间运行的BGP被称为iBGP(Internal/Interior BGP)。归属不同的AS的对等实体之间运行的BGP称为eBGP(External/Exterior BGP)。在AS边界上与其他AS交换信息的路由器被称作边界路由器(border/edge router),边界路由器之间互为eBGP对端。在Cisco IOS中,iBGP通告的路由距离为200,优先级比eBGP和任何内部网关协议(IGP)通告的路由都低。其他的路由器实现中,优先级顺序也是eBGP高于IGP,而IGP又高于iBGP。Mar 6, 2022Mar 6, 2022 iBGP和eBGP的区别主要在于转发路由信息的行为。例如,从eBGP peer获得的路由信息会分发给所有iBGP peer和eBGP peer,但从iBGP peer获得的路由信息仅会分发给所有eBGP peer,所有的iBGP peer之间需要全互联。

这里提到了三个名词:自治系统(AS)、内部网关协议(IGP)和外部网关协议(EGP)。

自治系统 AS

自制系统(Autonomous system,缩写 AS),是指在互联网中,一个或多个实体管辖下的所有IP 网络和路由器的组合,它们对互联网执行共同的路由策略

​ 自治系统编号都是16位长的整数,这最多能被分配给65536个自治系统,自治系统编号被分成两个范围。第一个范围是公开的ASN,从1到64511,它们可在互联网上使用;第二个范围是被称为私有编号的从64512到65535的那些,它们仅能在一个组织自己的网络内使用

​ 简单理解,电信、移动、联通都有自己的 AS 编号,且不只一个,有兴趣的可以查看维基百科中的中国互联网骨干网条目。

​ 除了互联网公开的 ASN 以外,私有的编号可以在内部使用。比如我可以我的家庭网络中使用私有编号创建几个 AS。

内部路由协议 IGP

内部路由协议(Interior Gateway Protocol 缩写为 IGP)是指在一个自治系统(AS)内部所使用的一种路由协议。

外部网关协议 EGP

外部网关协议(Exterior Gateway Protocol,错写 EGP)是一个已经过时互联网路由协议,已由 BPG 取代。

BPG 的由来

BPG 是为了替换 EGP 而创建的,而除了应用于 AS 外部,也可以应用在 AS 内部,因此又分为 EBGP 和 IBGP

8c7b5b1c29abfac561f1893eb2cd8af6.png

配置要求

对于配置为具有一个 BGP 路由器和一个 IP 地址范围的 BGP 模式,你需要先准备好以下 4 条配置信息

  1. MetalLB 应连接的路由器 IP 地址。
  2. 路由器的 AS 号。
  3. MetalLB 应该使用的 AS 编号。
  4. IP 地址范围,表示为 CIDR 前缀。

​ 由于这种配置方式需要具备 BGP 功能的硬件路由器支持,目前我们环境中不具备此等条件,这里就简单说下 MetalLB 对应的配置方式,具体内容就不展开讲解了。

资源配置

由于前面已经安装了 MetalLB 的 ControllerSpeaker,只是使用的是 Layer 2 模式,这里只需要改为 BGP 模式,我们修改 Configmap 中 Config 配置就可以了

1
vi metallb.bgp.config.yaml

假如要为 MetalLB 提供范围 192.168.9.0/24 和 AS 号 65009,并将其连接到 192.168.0.1 的 AS 号为 65000 的路由器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
peers:
- peer-address: 192.168.0.1
peer-asn: 65000
my-asn: 65009
address-pools:
- name: default
protocol: bgp
addresses:
#- 192.168.0.10-192.168.0.100
- 192.168.9.0/24

评论