共计 7112 个字符,预计需要花费 18 分钟才能阅读完成。
在上一篇《在 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。
说了这么多可能有些形象,间接上 demo 吧。
Demo
环境还是应用之前的,依照事后构想咱们心愿创立两个 AS:65000 和 65001。<u> 前者作为路由器和客户端所在的 AS,而后者是咱们集群服务 LoadBalancer IP 所在的 AS</u>。
咱们要先让 OpenWrt 反对 BGP。
OpenWrt 反对 BGP
为了让 OpenWrt 反对 BGP,这里要用到路由软件套件 Quagga。Quagga 提供了 OSPFv2、OSPFv3、RIP v1 v2、RIPng 和 BGP-4 的实现。
Quagga 架构由外围守护过程和 zebra 组成,后者作为底层 Unix 内核的形象层,并通过 Unix 或者 TCP 向 Quagga 客户端提供 Zserv API。正是这些 Zserv 客户端实现了路由协定,并将路由的更新发送给 zebra 守护过程。以后 Zserv 的实现是:
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 <none> 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 模式。
文章对立公布在公众号
云原生指北