Kubernetes开源LoadBalancer—MetalLB(BGP)
1、背景
最近一年为了迎接亚运会,单位开发了很多大屏展示界面,这些大屏展示页面需要提供给外部门访问,起初使用Ingress方式,但是需要外部门配置DNS,所以我们准备使用NodePort,但是领导想用LoadBalancer,众所周知,LoadBalancer大部分情况下只能在提供了外部负载均衡器的云提供商上使用,而我们是裸机集群,没办法,我们只能找开源的LoadBalancer解决方案。
在寻找资料的时候我们找到了两种解决方案,一种是Kubesphere的OpenELB,一种是MetalLB。但是OpenELB的文档实在是太少了,而且还是很久之前的文档,所以我们选择了MetalLB。
2、Metallb介绍
贴一段官方的介绍
Kubernetes没有为裸金属集群提供网络负载均衡器(LoadBalancer)。Kubernetes发布的网络负载均衡器的实现都是调用各种IaaS平台的外部负载均衡器。如果你不是运行在一个受支持的IaaS平台上,那么loadbalancer在创建时就会无限期地保持“Pending”状态。
裸金属集群运营商只剩下两个方式来将用户流量引入集群,即“NodePort”和“externalIPs”服务。这两种选择对生产用途都有显著的不利影响,这使得裸金属集群在Kubernetes生态系统中成为二等公民。
MetalLB的目标是通过提供一个与标准网络设备集成的网络负载均衡器实现来纠正这种不平衡,这样裸金属集群上的外部服务也可以尽可能地“正常工作”。
MetalLB有两个共同提供此服务的特性:地址分配和外部通知。
3、部署MetalLB(BGP)
(1)部署环境
这是我们内部集群拓扑的一个简化图:
注意:如果集群的CNI使用的是calico,你需要禁用calico的BGP模式,否则会影响MetalLB的正常工作。
(2)部署
# 安装前准备
# 如果kube-proxy使用的是IPVS模式,你需要启用staticARP
kubectl edit configmap -n kube-system kube-proxy
# 设置staticARP为true
mode: "ipvs"
ipvs:
strictARP: true
# 部署metalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
# 检查pod运行状态
[root@node1 ~]# kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-6554b76d68-gxwml 1/1 Running 0 35d
speaker-p9x5v 1/1 Running 0 35d
speaker-pgxkw 1/1 Running 0 35d
# 配置metalLB
cat > metallb-eip.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
peers:
- peer-address: 192.168.0.254 # BGP邻居IP(Core Switch的IP)
peer-asn: 50000 # 对端AS号
my-asn: 50001 # 本地AS号
address-pools:
- name: default
protocol: bgp # 协议使用BGP
addresses: # 地址池
- 10.11.11.1-10.11.11.254
EOF
# 之前我地址池配置成10.11.11.0/24,Metallb分配地址时会把10.11.11.0也分配出去。
# 配置核心交换机
[Core-Switch]bgp 50000
[Core-Switch-bgp]peer 192.168.0.1 as-num 50001
[Core-Switch-bgp]peer 192.168.0.2 as-num 50001
[Core-Switch-bgp]peer 192.168.0.3 as-num 50001
查看BGP邻居建立情况 [Core-Switch]dis bgp peer。
# 现在使用K8S dashboard做个实验
kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.1.189.92 <none> 8000/TCP 35d
kubernetes-dashboard NodePort 10.1.88.59 <none> 443:31956/TCP 35d
# 现在使用的是NodePort,把他修改成LoadBalancer
kubectl edit svc -n kubernetes-dashboard kubernetes-dashboard
type: LoadBalancer
# 保存退出, 再次查看svc
kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.1.189.92 <none> 8000/TCP 35d
kubernetes-dashboard LoadBalancer 10.1.88.59 10.11.11.1 443:31956/TCP 35d
# 可以看到kubernetes-dashboard的EXTERNAL-IP已经被分配了一个地址
现在到交换机上看一下 [Core-Switch]dis bgp routing-table [Core-Switch]dis ip rou 10.11.11.1。
可以看到交换机已经学习到了10.11.11.1的路由 在浏览器中访问https://10.11.11.1。