MetalLB 是一种用于裸机 Kubernetes 集群的负载均衡器实现,能够通过发布集群外部的 IP 地址来暴露服务。此部分文档介绍 MetalLB 的地址发布模式、安装步骤、以及如何配置地址池并发布服务。
MetalLB 提供两种主要的地址发布模式:
在裸机环境中,Layer 2 模式通常更容易配置和管理,因此我们将重点介绍 Layer 2 模式。
如果您在 IPVS 模式下使用 kube-proxy,自 Kubernetes v1.14.2 起您必须启用严格 ARP 模式。
请注意,如果您使用 kube-router 作为服务代理,则不需要此功能,因为它默认启用严格 ARP。
您可以通过编辑当前集群中的 kube-proxy 配置来实现此目的:
kubectl edit configmap -n kube-system kube-proxy
并设置:
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
如果您尝试自动执行此更改,这些 shell 代码片段可能会对您有所帮助:
# see what changes would be made, returns nonzero returncode if different
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system
# actually apply the changes, returns nonzero returncode on errors only
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system\
安装 MetalLB 组件:
wget https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml
kubectl apply -f metallb-native.yaml
通过helm安装:
helm install metallb metallb/metallb -n metallb-system --create-namespace
使用以下命令检查 MetalLB 是否成功部署:
kubectl get pods -n metallb-system
确保所有 Pod 都在 Running
状态。
创建一个 IPAddressPool,用于定义 MetalLB 使用的 IP 地址池。在此示例中,我们使用 Layer 2
模式。
创建一个名为 metallb-addresspool.yaml
的配置文件:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 192.168.11.64/27
创建一个名为 metallb-l2advertisement.yaml
的配置文件:
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: layer2publish
namespace: metallb-system
spec:
ipAddressPools:
- first-pool
请将192.168.11.64/27
改成你自己本地的地址池。
将 metallb-config.yaml
应用到 Kubernetes 集群:
kubectl apply -f metallb-addresspool.yaml
kubectl apply -f metallb-l2advertisement.yaml
安装 Nginx Ingress Controller,并将 Service 类型设置为 LoadBalancer
,让 MetalLB 为其分配一个外部 IP 地址:
为了确保客户端的真实 IP 地址能够在 NodePort 类型的服务中正确传递,你需要将 externalTrafficPolicy
设置为 Local
。这将保留客户端源地址(source IP preservation)。
使用 Layer 2
模式时,MetalLB 将会感知 ingress-nginx-controller Pod的所在节点,并让所在节点响应EXTERNAL-IP ARP/NDP 请求,确保请求不发送到不存在ingress-nginx-controller Pod的节点。
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
kubectl create namespace ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
--set controller.service.type=LoadBalancer \
--set controller.service.externalTrafficPolicy=Local \
--set ingressClassResource.default=true \
--set controller.watchIngressWithoutClass=true \
--namespace ingress-nginx
使用以下命令检查 Nginx Ingress Controller 的 Service,确保它获得了一个 MetalLB 分配的外部 IP 地址:
kubectl get svc -n ingress-nginx
输出应包含类似如下的信息:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.96.122.1 192.168.11.64 80:30820/TCP,443:31867/TCP 2m
将域名的 DNS A 记录指向 MetalLB 分配的外部 IP 地址(如 192.168.11.64
),以便外部用户能够通过域名访问 Nginx Ingress Controller。
通过 MetalLB,您可以在裸机 Kubernetes 集群中轻松暴露 Nginx Ingress 的 80 和 443 端口。Layer 2 模式的配置相对简单,非常适合小型集群或与 Kubernetes 节点处于同一网络的环境。通过正确配置 IP 地址池和地址发布模式,MetalLB 能够为 Kubernetes 服务提供可靠的负载均衡功能。