
概述
在k8s中创建service时,需要指定type
类型,可以分别指定ClustrerIP,NodePort,LoadBalancer
三种,其中前面两种无论在内网还是公网环境下使用都很常见,只有LoadBalancer
大部分情况下只适用于支持外部负载均衡器的云提供商(AWS,阿里云,华为云等)使用。
如果想要在内网环境中,使用type=LoadBalancer
就需要部署另外的插件,下面主要介绍一下MetalLB组件。
熟悉k8s的都知道,k8s的LoadBalancer类型的Service依赖于外部的云提供的Load Balancer。
当我们把k8s部署在裸机上面时,或者是测试环境时,需要简单的LoadBalancer来验证工作,开源的metallb就是一个不错的选择
Metallb一开始是挂在github.com/google下面的,估计是某个员工的个人项目,现在已经挂到了个人名下,它的作用就是通过k8s原生的方式提供LB类型的Service支持,开箱即用。
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上面。

工作模式
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 可能需要以下环境:
- 一个 Kubernetes 集群,运行 Kubernetes 1.13.0 或更高版本。
- Kubernetes 集群的网络配置可以与 MetalLB 共存。
- 有一些提供给 MetalLB 分发的 IPv4 地址。
- 根据部署模式,可能需要一个或多个 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 ...
|

生效配置
保存退出后就会生效配置

准备资源清单
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 2 3 4 5 6
| apiVersion: v1 kind: Namespace metadata: name: metallb-system labels: app: metallb
|
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 - 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
|

查看状态
查看运行的pods,metalLB包含两个部分,controller
和speaker
1
| kubectl get pod -o wide -n metallb-system
|

其中controller
是deployment
而speaker
是DaemonSet
1 2
| kubectl get deployment -n metallb-system kubectl get daemonset -n metallb-system
|

目前还没有宣布任何内容,因为我们没有提供ConfigMap,也没有提供负载均衡地址的服务
部署组件说明
部署完成后,将在 metallb-system
命名空间下将 MetalLB 部署到集群,YAML 文件中主要包含以下一些组件
metallb-system/controller
,这是处理 IP
地址分配的控制器。
metallb-system/speakerdaemonset
这是支持你选择协议以使服务可达的组件。
Controller
和 Speaker
的 Service 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
|

请求测试
创建测试环境
创建资源清单
创建一个包含了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
|

查看service
查看service分配的EXTERNAL-IP
我们发现已经分配了IP地址

访问测试
外部访问
从集群外访问该IP地址

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

工作原理
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 这里有可能会再跳去另一台主机。

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

配置要求
对于配置为具有一个 BGP
路由器和一个 IP 地址范围的 BGP 模式,你需要先准备好以下 4 条配置信息
- MetalLB 应连接的路由器 IP 地址。
- 路由器的 AS 号。
- MetalLB 应该使用的 AS 编号。
- IP 地址范围,表示为 CIDR 前缀。
由于这种配置方式需要具备 BGP 功能的硬件路由器支持,目前我们环境中不具备此等条件,这里就简单说下 MetalLB 对应的配置方式,具体内容就不展开讲解了。
资源配置
由于前面已经安装了 MetalLB 的 Controller
和 Speaker
,只是使用的是 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
|