在 Kubernetes 集群中,可以使用 NodePort、LoadBalancer 和 Ingress 三种方式来将服务暴露给外部访问,但是,在 Kubernetes 却只实现了 NodePort 和 Ingress,要使用 LoadBalancer 就只能使用商用的云平台,比如阿里云、GCP、AWS、AKS等。 如果你是使用 kubeadm
搭建的“裸集群”是没有 LoadBalancer 的,所以裸集群在生产环境下根本不能用,这使得裸集成为了 Kubernetes 生态中的“二等公民”。本文介绍如何利用 MetalLB 让“裸集群”也可以有负载均衡。
原理
MetalLB 在 Kubernetes 内运行,监控服务对象的变化,一旦发现有新的 LoadBalancer 服务运行,并且没有可以申请的负载均衡器之后,便会完成两部分的工作:
- 分配地址:用户需要在配置中提供一个地址池, MetalLB 会在其中选择地址分配给 LoadBalancer 服务
- 地址广播:根据不同的配置, MetalLB 会依据 layer2(ARP/NDP) 协议或者 BGP 协议的方式进行地址的广播。
安装
MetaLB 支持两种方式安装,一种是通过 kubectl apply
:
kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/metallb.yaml |
另一种是通过 helm
:
helm install --name metallb stable/metallb |
安装好之后会创建一个 metallb-system
的 Namespace,在这个 Namespace 下会生成叫作 controller
的 Deployment 和 叫作 speaker
的 DeamonSet:
$ kubectl get pods -n metallb-system |
配置 MetalLB
创建配置文件 layer2-config.yaml
:
apiVersion: v1 |
该配置文件指定在metallb-system
下生成一个名为config
的标准Kubernetes ConfigMap,配置项中包含两条信息,一个是使用了layer2
协议,一个是地址的取值范围为 192.168.1.240-192.168.1.250
。
注意: 地址的取值范围要根据自己的集群IP来配置
将这个 ConfigMap 部署到集群上:
kubectl apply -f layer2-config.yaml |
测试
然后我们就可以创建一个 LoadBalancer 类型的服务了,使用官方提供的nginx
LoadBalancer 测试:
kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/tutorial-2.yaml |
然后我们可以查看其状态:
$ kubectl get pods |
查看 speaker
的日志观察路由变化:
$ kubectl logs -l component=speaker -n metallb-system |
访问服务就会看到 nginx
的欢迎页面:
$ curl http://192.168.1.240 |
兼容性
按理来说,MetalLB 是不关心集群究竟使用的是哪种网络插件,但是不同的 CNI 实现可能存在一些隐藏的问题,下表是官方给出的兼容性表:
网络插件 | 兼容性 |
---|---|
Calico | 部分支持 |
Flanner | 支持 |
Kube-router | 不支持 |
Romana | 支持 |
Weave Net | 支持 |