本文介绍 MetalLB
的工作原理、安装和使用。MetalLB
是一个使用标准路由协议(ARP/NDP或BGP)为 Kubernetes
集群实现负载平衡器(LoadBalancer)
的方案,多用于测试环境。
背景
Kubernetes
默认没有提供负载均衡器(Create an External Load Balancer)的实现。Kubernetes 的网络负载均衡器的实现都有各种 IaaS 平台(GCP、AWS、Azure等)实现,如果你不在上述 IaaS 平台上运行 Kubernetes
,创建的 Service 中 type: LoadBalancers
将一直处于 Pending 状态,如下所示:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx LoadBalancer 10.96.85.164 <pending> 8080:31312/TCP,443:31105/TCP 1h
该情况下,一般配置 Service 为 NodePort 和 externalIPs 将流量导入 Kubernetes 环境,这些选择都有明显的不足之处,因此使私有部署的 Kubernets 使用者在此生态中沦为二等公民(second-class citizens)。
Metallb 通过标准路由协议能解决该问题。MetalLB 也是 CNCF 的沙箱项目,最早发布在 https://github.com/google/metallb 开发,后来迁移到 https://github.com/metallb/metallb 中。
实现原理
MetalLB 通过 MetalLB hooks 为 Kubernetes 中提供网络负载均衡器的实现。简单的说,它允许你在非云供应商提供的(私有的) Kubernetes 中创建 type: LoadBalancer
的 services。
MetalLB 有两大功能:
- 地址分配:在 IaaS 平台申请 LB,会自动分配一个公网 IP,因此,MetalLB也需要管理 IP 地址的分配工作
- IP 外部声明:当 MetalLB 获取外部地址后,需要对外声明该 IP 在 k8s 中使用,并可以正常通信。
IP 声明可以使用 ARP、 NDP、或 BGP 协议,因此 MetalLB 有两种工作模式:
- BGP 工作模式,使用 BGP 协议分配地址池
- L2 工作模式,使用 ARP/NDP 协议分配地址池
安装
环境需求
- Kubernetes >=1.13.0
- 支持 MetalLB 的 Kubernetes 网络插件,如下:
- 参考 CLOUD COMPATIBILITY 查看你的环境是否支持 MetalLB
- 与 k8s 同网段的 IPv4 地址
- 使用 BGP 工作模式时,需要一台或多台支持 BGP 的路由器
- 使用 L2 工作模式时,必须允许节点之间通过 7946 端口(TCP & UDP,可以配置其他端口)通信,memberlist 服务监听在该端口
- 二层模式不需要将 IP 绑定到工作节点的网络接口上。它的工作原理是直接响应本地网络上的 ARP 请求,将本机的 MAC 地址提供给客户端
- 从 Kubernetes v1.14.2 开始,若 kube-proxy 使用 IPVS 模式,需要开启 strict ARP 模式,使用
kubectl edit configmap -n kube-system kube-proxy
修改如下:
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
安装
MetalLB 支持 Kubernetes manifests、Kustomize 和 Helm 三种安装方式,本文使用 Manifest 模式安装
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
在 metallb-system namespace 下,会安装两个组件
- metallb-system/controller deployment:管理 IP 地址分配的控制器
- metallb-system/speaker daemonset:通过 protocol(s) 维护服务间连通
还有对应的 Service accounts
使用 RBAC 保证和 k8s 的通信权限。
配置
- L2 工作模式下,创建文件
metallb-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.1.240-192.168.1.250
# - 192.168.1.0/28
应用:
kubectl apply -f metallb-config.yaml
通过 kubectl logs -f [metallb-controller-pod]
查看日志
扩展
apiVersion: v1
kind: Service
metadata:
...
annotations:
metallb.universe.tf/allow-shared-ip: "key-to-share-1.2.3.4"
使用相同 annotations 的 service 共享 IP 地址。