对于负载均衡,我们有很多种办法。
负载均衡实际上包含了两个方面:健康探测以及流量分担。如果我们不能健康探测而将流量错误地分到宕机上,会导致流量黑洞。
首先最豪华的解决方案就是硬件负载均衡器,但是一般我们买不起。
其次是路由器 NAT Pool 地址池转换,不过这种不靠谱,因为这种就是简单地将流量分发到服务器上,万一服务器掉线了
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! 需要人工去改地址池,也就是缺少健康探测的功能。我们也可以通过 ipvs 找一台服务器来进行负载均衡,这也是 K8s 集群内部的负载均衡办法,但是这样还是给转发的那台机器带来不必要的负担。
最后一种办法是在路由器上配置等价路由,由路由器进行负载均衡,这样其实和 NAT Pool 缺点是一样的,不过,我们有大杀器——动态路由协议可以帮我们搞定这个问题。
所以我们最后实现了这么一种迂回的办法,就是让机器发布路由信息到路由器上,然后由路由器选择机器进行转发,同时每台机器也及时监控其他机器,一旦发现宕机,则更新路由信息,避免路由器将流量转发到宕机上。
理解 MetalLB 的原理需要对 K
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! 8s 控制原理以及计算机网络有着比较深入的理解。但理解了之后,配置的东西其实相当简单。
一、Load Balancer 原理
如果我们使用 GKE、AWS 等公有云,那么一般来说我们给 Service 的 Type 写成 LoadBalancer,云服务厂商就会分配一个 External IP 给我们的 Service,我们只需要访问这个 External IP,其内部就能自动均衡我们的流量到各个实例上。然而作为穷鬼的我们,没有金钱享受如此高端的服务,开源版 Kubernetes 是不会给我们的 LoadBalancer Service 分配 External IP 的。难道穷鬼就不配用负载均衡了吗!!
幸好,即使没有高端的负载均衡器,
最简单的,我们可以在服务器的内部子网里找没用的 IP,然后等其他电脑访问这个 IP 的时候,我想办法回应一个 ARP 包,其他电脑就知道这个 IP 在哪里可以通信了,尽管这个 IP 其实没有绑定到任何网卡上,可能只是 iptables 里的一条记录。
然而,通过 ARP 广播的方式局限性非常大,分配的 IP 只能和服务器其他 IP 位于同一子网,但其实对于我们这种小型集群已经够了,但是这不够 geek!有没有高端一点的办法?
有!那就是 BGP。BGP 的原理比较复杂,简单来说就是运行 BGP 的设备之间可以交换路由信息,我们可以将自己的 IP 段通过 BGP 协议告诉其他设备,这样其他设备就能正确的路由数据包到服务器上了。BGP 需要路由器的支持,好在我们的路由器是支持的。BGP 尽管更复杂了一些,但是在 IP 段的选取上有更大的灵活性。尽管负载均衡器原理十分复杂,配置却很简单。
二、安装 metallb 控制器
请根据自己的需要选择对应的版本。
kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml
三、配置路由器
在配置控制器之前,我们需要配置路由器的 BGP 功能,简单来说就是给路由自己分配一个 AS
路由器的 AS 号是 65315,集群 AS 号是 65199。
[Huawei] bgp 65315 # 打开路由器 BGP 功能,分配 65315 AS 号
[Huawei-bgp] group servers external # 声明外部邻居组
[Huawei-bgp] peer servers as-number 65199 # 声明组 AS 号为 65199
[Huawei-bgp] peer 192.168.1.110 group servers # 声明组内邻居
[Huawei-bgp] peer 192.168.1.111 group servers
[Huawei-bgp] peer 192.168.1.113 group servers
[Huawei-bgp] peer 192.168.1.114 group servers
[Huawei-bgp] peer 192.168.1.115 group servers
[Huawei-bgp] peer 192.168.1.116 group servers
[Huawei-bgp] peer 192.168.1.117 group servers
[Huawei-bgp] peer 192.168.1.118 group servers
[Huawei-bgp] peer 192.168.1.119 group servers
[Huawei-bgp] maximum load-balancing 4 # 默认情况下,路由只会从学习到的 BGP 路由信息中选取最佳的 1 条写进路由表,而只有路由表中同一目的地址含有多个等价下一条才能实现负载均衡。所以,我们要指示 BGP 将多条路由同时写进路由表,我们的路由器型号最大只支持 4
到这里路由器就配置完了。
四、配置 metallb 控制器
直接应用下面的 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
peers:
- peer-address: 192.168.1.1 # 路由器的 IP 地址
peer-asn: 65315 # 路由器的 AS 号
my-asn: 65199 # 集群 AS 号
address-pools:
- name: default
protocol: bgp
addresses:
- 192.168.15.0/24 # 希望分配的 IP 地址池,到时候会分配给 Service 的 ExternalIP
五、检查负载均衡是否生效
首先将一个 Service 改成 LoadBalancer,然后查看是否分配到了 External IP:
$ kubectl get svc traefik-load-balance-service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik-load-balance-service LoadBalancer 10.97.104.52 192.168.15.1 80:32703/TCP,443:32237/TCP 13h
可以看到确实分配到了一个我们地址池中的 IP。
然后检查路由是否学习到了 BGP 路由表:
<Huawei>display bgp routing-table
BGP Local router ID is 192.168.1.1
Status codes: * - valid, > - best, d - damped,
h - history, i - internal, s - suppressed, S - Stale
Origin : i - IGP, e - EGP, ? - incomplete
Total Number of Routes: 8
Network NextHop MED LocPrf PrefVal Path/Ogn
*> 192.168.15.1/32 192.168.1.110 0 65199?
* 192.168.1.111 0 65199?
* 192.168.1.114 0 65199?
* 192.168.1.115 0 65199?
* 192.168.1.116 0 65199?
* 192.168.1.117 0 65199?
* 192.168.1.118 0 65199?
* 192.168.1.119 0 65199?
可以看到路由器已经收到来自集群的 BGP 信息。
然后检查路由器路由表,是否有多个下一跳:
<Huawei>display ip routing-table
Route Flags: R - relay, D - download to fib
------------------------------------------------------------------------------
Routing Tables: Public
Destinations : 12 Routes : 15
Destination/Mask Proto Pre Cost Flags NextHop Interface
0.0.0.0/0 Static 60 0 D 222.200.180.254 GigabitEthernet0/0/4
127.0.0.0/8 Direct 0 0 D 127.0.0.1 InLoopBack0
127.0.0.1/32 Direct 0 0 D 127.0.0.1 InLoopBack0
127.255.255.255/32 Direct 0 0 D 127.0.0.1 InLoopBack0
192.168.1.0/24 Direct 0 0 D 192.168.1.1 Vlanif1
192.168.1.1/32 Direct 0 0 D 127.0.0.1 Vlanif1
192.168.1.255/32 Direct 0 0 D 127.0.0.1 Vlanif1
192.168.15.1/32 EBGP 255 0 D 192.168.1.110 Vlanif1
EBGP 255 0 D 192.168.1.111 Vlanif1
EBGP 255 0 D 192.168.1.114 Vlanif1
EBGP 255 0 D 192.168.1.115 Vlanif1
222.200.180.0/24 Direct 0 0 D 222.200.180.45 GigabitEthernet0/0/4
222.200.180.45/32 Direct 0 0 D 127.0.0.1 GigabitEthernet0/0/4
222.200.180.255/32 Direct 0 0 D 127.0.0.1 GigabitEthernet0/0/4
255.255.255.255/32 Direct 0 0 D 127.0.0.1 InLoopBack0
针对 192.168.15.1,路由表被应用了多个下一跳,因此可以负载均衡。
最后查看 FIB 转发表:
<Huawei>display fib
Route Flags: G - Gateway Route, H - Host Route, U - Up Route
S - Static Route, D - Dynamic Route, B - Black Hole Route
L - Vlink Route
--------------------------------------------------------------------------------
FIB Table:
Total number of Routes : 15
Destination/Mask Nexthop Flag TimeStamp Interface TunnelID
192.168.15.1/32 192.168.1.110 DGHU t[5340582] Vlanif1 0x0
192.168.15.1/32 192.168.1.111 DGHU t[5340582] Vlanif1 0x0
192.168.15.1/32 192.168.1.114 DGHU t[5340582] Vlanif1 0x0
192.168.15.1/32 192.168.1.115 DGHU t[5340582] Vlanif1 0x0
222.200.180.255/32 127.0.0.1 HU t[611645] InLoop0 0x0
222.200.180.45/32 127.0.0.1 HU t[611645] InLoop0 0x0
192.168.1.255/32 127.0.0.1 HU t[201] InLoop0 0x0
192.168.1.1/32 127.0.0.1 HU t[201] InLoop0 0x0
255.255.255.255/32 127.0.0.1 HU t[79] InLoop0 0x0
127.255.255.255/32 127.0.0.1 HU t[79] InLoop0 0x0
127.0.0.1/32 127.0.0.1 HU t[79] InLoop0 0x0
127.0.0.0/8 127.0.0.1 U t[79] InLoop0 0x0
192.168.1.0/24 192.168.1.1 U t[201] Vlanif1 0x0
222.200.180.0/24 222.200.180.45 U t[611645] GE0/0/4 0x0
0.0.0.0/0 222.200.180.254 GSU t[611645] GE0/0/4 0x0
可以看到路由器在路由表的指导下,为 192.168.15.1 分配了多个下一跳。
您好~我是腾讯云开发者社区运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan
作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器等,另外还有些周边礼物。