Kubernetes 1.28.2 负载均衡解决方案 MetalLB实践
MetalLB 是一个用于在 Kubernetes 集群中提供外部 IP 地址的负载均衡器实现。
安装须知:
- Kubernetesv1.13.0 或者更新的版本
- 规划 IPv4 地址给 MetalLB 用于分配。
- 当使用 BGP 操作模式时,你将需要一个或多个能够支持 BGP 协议的路由器。
- L2 模式下需要各个节点间 7946 端口(TCP & UDP)需要互通。
- 集群中的 CNI 要能兼容 MetalLB,最新的兼容性参考 https://metallb.universe.tf/installation/network-addons/
常见的 Flannel、Cilium 等都是兼容的,Calico 的话大部分情况都兼容,BGP 模式下需要额外处理。因为 BGP 单 session 的限制,如果 CNI 插件为 Calico ,同时 Calico 也是使用的 BGP 模式,就会有冲突从而导致 MetalLB 无法正常工作。
确保Kubernetes 集群已经部署并且运行正常。
[root@k8s-master-01 ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master-01 Ready control-plane 38d v1.28.2 192.168.61.147 <none> Rocky Linux 8.7 (Green Obsidian) 4.18.0-425.3.1.el8.x86_64 docker://26.1.3
k8s-worker-01 Ready <none> 38d v1.28.2 192.168.61.148 <none> Rocky Linux 8.7 (Green Obsidian) 4.18.0-425.3.1.el8.x86_64 docker://26.1.3
k8s-worker-02 Ready <none> 38d v1.28.2 192.168.61.149 <none> Rocky Linux 8.7 (Green Obsidian) 4.18.0-425.3.1.el8.x86_64 docker://26.1.3
##### 网络组件
[root@k8s-master-01 ~]# kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-658d97c59c-5rkzg 1/1 Running 1 (12d ago) 38d 10.244.151.133 k8s-master-01 <none> <none>
calico-node-5ch6s 1/1 Running 1 (12d ago) 38d 192.168.61.148 k8s-worker-01 <none> <none>
calico-node-kqwjf 1/1 Running 1 (12d ago) 38d 192.168.61.149 k8s-worker-02 <none> <none>
calico-node-q8ztz 1/1 Running 1 (12d ago) 38d 192.168.61.147 k8s-master-01 <none> <none>
coredns-66f779496c-8hsjx 1/1 Running 1 (12d ago) 38d 10.244.151.132 k8s-master-01 <none> <none>
coredns-66f779496c-bdt8k 1/1 Running 1 (12d ago) 38d 10.244.151.134 k8s-master-01 <none> <none>
etcd-k8s-master-01 1/1 Running 1 (12d ago) 38d 192.168.61.147 k8s-master-01 <none> <none>
kube-apiserver-k8s-master-01 1/1 Running 1 (12d ago) 38d 192.168.61.147 k8s-master-01 <none> <none>
kube-controller-manager-k8s-master-01 1/1 Running 2 (12d ago) 38d 192.168.61.147 k8s-master-01 <none> <none>
kube-proxy-rph9c 1/1 Running 0 51m 192.168.61.149 k8s-worker-02 <none> <none>
kube-proxy-s4kd9 1/1 Running 0 51m 192.168.61.148 k8s-worker-01 <none> <none>
kube-proxy-zdx6t 1/1 Running 0 51m 192.168.61.147 k8s-master-01 <none> <none>
kube-scheduler-k8s-master-01 1/1 Running 2 (12d ago) 38d 192.168.61.147 k8s-master-01 <none> <none>
部署 MetalLB
官方提供了好几种安装方式,yaml、helm、operator 等,这里使用 yaml 方式安装。
如果kube-proxy使用的是IPVS模式,在v1.14.2版本之后,需要启用strict ARP mode。
[root@k8s-master-01 ~]# kubectl edit configmap -n kube-system kube-proxy
...
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: true # 启用strictARP
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
logging:
flushFrequency: 0
options:
json:
infoBufferSize: "0"
verbosity: 0
metricsBindAddress: ""
mode: "ipvs" # kube-proxy模式,默认为iptables
nodePortAddresses: null
oomScoreAdj: null
...
# 重启kube-proxy生效
[root@k8s-master-01 ~]# kubectl rollout restart daemonset/kube-proxy -n kube-system
kube-proxy默认使用的是iptables转发模式,在大规模集群中,建议改为ipvs。如果当前转发模式是ipvs,启用严格的 ARP。
- 创建 MetalLB 命名空间
[root@k8s-master-01 ~]# kubectl create namespace metallb-system
- 使用Manifest安装MetalLB
MetalLB 提供了一组清单文件来部署所需的组,使用如下命令部署:
[root@k8s-master-01 ~]# curl https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml -O
kubectl apply -f metallb-native.yaml
查询官网文档获取最新的安装命令。https://metallb.io/installation/
- 验证安装
[root@k8s-master-01 ~]# kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-56bb48dcd4-6qvx4 1/1 Running 0 65m
speaker-6k7m2 1/1 Running 0 65m
speaker-jsckg 1/1 Running 0 65m
speaker-kwzrm 1/1 Running 0 65m
- 配置 MetalLB
MetalLB 支持两种操作模式:Layer 2 模式和 BGP 模式。因为 BGP 对路由器有要求,POC测试时建议使用 Layer2 模式。
Layer2模式配置:
Layer 2 模式是最简单的配置方式:在许多情况下,你不需要任何特定协议的配置,只需要 IP 地址。
Layer 2 模式不需要将 IP 绑定到你的工作节点的网络接口上。它通过直接响应本地网络上的 ARP 请求,向客户端提供机器的 MAC 地址来工作。
Layer2模式配置,首先创建一个IPAddressPool资源对象:
[root@k8s-master-01 ~]# cat ip-pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.61.156-192.168.61.160 #分配给LB的IP池
[root@k8s-master-01 ~]# kubectl apply -f ip-pool.yaml
备注
- IP地址池与集群IP位于同一个网段。
- 多个实例IP地址池可以共存,并且可以分配IPV4和IPV6地址。
创建一个广播声明,关联上面的 IP 池对象:
cat advertise.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2adver
namespace: metallb-system
spec:
ipAddressPools:
- ip-pool
说明:
- 如果不设置关联到 IPAdressPool,L2Advertisement 默认会关联所有可用的 IPAdressPool。
Layer2模式demo应用示例
为了验证 MetalLB 的配置是否正确,你可以创建一个简单的 Nginx 服务。
创建一个 nginx-deployment.yaml 文件,内容如下
[root@k8s-master-01 ~]# cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
[root@k8s-master-01 ~]# cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
[root@k8s-master-01 ~]# kubectl apply -f nginx-deployment.yaml
[root@k8s-master-01 ~]# kubectl apply -f nginx-service.yaml
[root@k8s-master-01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d
nginx-service LoadBalancer 10.96.64.154 192.168.61.156 80:32145/TCP 25m
作者:一毛
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
不管遇到了什么烦心事,都不要自己为难自己;无论今天发生多么糟糕的事,都不应该感到悲伤。记住一句话:越努力,越幸运。