对于自建的Kubernetes集群,默认情况下是不支持负载均衡的。当需要提供服务的外部访问时,可选用的方案不外乎 Ingress、NodePort等方式。但这些方案本身并不算非常完美,他们或多或少都存在着一些不足之外 ,如Ingress不支持TCP协议,而NodePort则是使用随机端口。
一. 部署要求
MetalLB部署需要以下环境才能运行:
运行Kubernetes 1.13.0或更高版本的群集,尚不具有网络负载平衡功能; 一些用于MetalLB分配的IPv4地址; 如果使用BGP模式,需要准备一台或多台支持BGP的路由器; 如果使用layer 2模式时,集群节点间必须允许7946端口的访问 ,用户代理之间的通信; 集群的网络类型需要支持MetalLB,详见下图
网络类型 | 兼容性 |
---|---|
Antrea | Yes |
Calico | Mostly |
Canal | Yes |
Cilium | Yes |
Flannel | Yes |
Kube-ovn | Yes |
Kube-router | Mostly |
Weave Net | Mostly |
二. 工作原理
MetalLB支持两种模式,一种是Layer2模式,一种是BGP模式。
Layer2模式
在2层模式下,Metallb会在Node节点中选出一台作为Leader,与服务IP相关的所有流量都会流向该节点。在该节点上, kube-proxy将接收到的流量传播到对应服务的Pod。当leader节点出现故障时,会由另一个节点接管。从这个角度来看,2层模式更像是高可用,而不是负载均衡,因为同时只能在一个节点负责接收数据。
在二层模式中会存在以下两种局限性:单节点瓶颈和故障转移慢的情况。
由于Layer 2 模式会使用单个选举出来的Leader来接收服务IP的所有流量,这就意味着服务的入口带宽被限制为单个节点的带宽,单节点的流量处理能力将成为整个集群的接收外部流量的瓶颈。
在故障转移方面,目前的机制是MetalLB通过发送2层数据包来通知各个节点,并重新选举Leader,这通常能在几秒内完成。但如果是计划外的事故导致的,此时在有故障的客户端刷新其缓存条目之前,将无法访问服务IP。
BGP模式
BGP模式是真正的负载均衡,该模式需要路由器支持BGP协议 ,群集中的每个节点会与网络路由器建议基于BGP的对等会话,并使用该会话来通告负载均衡的IP。MetalLB发布的路由彼此等效,这意味着路由器将使用所有的目标节点,并在它们之间进行负载平衡。数据包到达节点后,kube-proxy负责流量路由的最后一跳,将数据包发送到对应服务的Pod。
负载平衡的方式取决于您特定的路由器型号和配置,常见的有基于数据包哈希对每个连接进行均衡,这意味着单个TCP或UDP会话的所有数据包都将定向到群集中的单个计算机。
三. 部署安装
Metallb支持通过Kuberntes清单、Helm和Kustomize方式进行部署,本文我们将以Kuberntes清单为例介绍产品的部署安装,部署的版本为最新的v0.13.4。
1. 启用kube-proxy的ARP模式
如果集群是使用IPVS模式下kube-proxy,则从kubernetes v.1.14.2开始,必须启用ARP模式。
kubectl edit configmap -n kube-system kube-proxy
#设置strictARP值为true
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
2. 安装MetalLB相关组件
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.4/config/manifests/metallb-native.yaml
Layer2模式配置
创建IPAddressPool,并指定用于分配的IP池。
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ip-pool
namespace: metallb-system
spec:
addresses:
192.168.214.50-192.168.214.80 #分配给LB的IP池
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2adver
namespace: metallb-system
BGP模式配置
对于具有一个BGP路由器和一个IP地址范围的基本配置,您需要4条信息:
MetalLB应该连接的路由器IP地址, 路由器的AS号, MetalLB应该使用的AS号, 以CIDR前缀表示的IP地址范围。
创建BGPPeer
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: sample
namespace: metallb-system
spec:
myASN: 64500
peerASN: 64501
peerAddress: 10.0.0.1
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
192.168.10.0/24
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: bgpadver
namespace: metallb-system
四. 功能验证
1. 创建示例yaml文件并执行,包括svc与deployment。
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
selector:
app: myapp
ports:
protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer #类型选择LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
name: nginx
image: nginx:1.19.4
ports:
containerPort: 80
------------------ END ------------------
关注公众号,获取更多精彩内容