做酒店销售上哪个网站好,编程训练网站,网站封了给个能用的,外链生成Kubernetes 负载均衡解决方案 MetalLB实践
MetalLB 是一个用于在 Kubernetes 集群中提供外部 IP 地址的负载均衡器实现。
准备工作
1. 安装需知
安装 MetalLB 有一些前置条件#xff1a; Kubernetesv1.13.0 或者更新的版本 集群中的 CNI 要能兼容 MetalLB#xff0c;最新…Kubernetes 负载均衡解决方案 MetalLB实践
MetalLB 是一个用于在 Kubernetes 集群中提供外部 IP 地址的负载均衡器实现。
准备工作
1. 安装需知
安装 MetalLB 有一些前置条件 Kubernetesv1.13.0 或者更新的版本 集群中的 CNI 要能兼容 MetalLB最新的兼容性参考NETWORK ADDON COMPATIBILITY Network addonCompatibleAntreaYes (Tested on version 1.4 and 1.5)CalicoMostly (see known issues)CanalYesCiliumYesFlannelYesKube-ovnYesKube-routerMostly (see known issues)Weave NetMostly (see known issues) 备注 常见的 Flannel、Cilium 等都是兼容的Calico 的话大部分情况都兼容BGP 模式下需要额外处理。因为 BGP 单 session 的限制如果 CNI 插件为 Calico 同时 Calico 也是使用的 BGP 模式就会有冲突从而导致 MetalLB 无法正常工作。 提供一些 IPv4 地址给 MetalLB 用于分配。 当使用 BGP 操作模式时你将需要一个或多个能够支持 BGP 协议的路由器。 L2 模式下需要各个节点间 7946 端口(TCP UDP)需要互通。
最新信息参考requirements
2. 本文部署的环境
确保你的 Kubernetes 集群已经部署并且运行正常。
rootmaster1:~# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master1 Ready control-plane 2d19h v1.28.2 192.168.0.61 none Ubuntu 24.04 LTS 6.8.0-36-generic containerd://1.7.12
node1 Ready none 2d19h v1.28.2 192.168.0.62 none Ubuntu 24.04 LTS 6.8.0-36-generic containerd://1.7.12
node2 Ready none 2d19h v1.28.2 192.168.0.63 none Ubuntu 24.04 LTS 6.8.0-36-generic containerd://1.7.12CNI插件及版本信息
rootmaster1:~# calicoctl version
Client Version: v3.28.0
Git commit: 413e6f559
Cluster Version: v3.28.0
Cluster Type: typha,kdd,k8s,operator,bgp,kubeadm# calico使用bgp模式
rootmaster1:~# calicoctl node status
Calico process is running.IPv4 BGP status
---------------------------------------------------------------
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
---------------------------------------------------------------
| 192.168.0.62 | node-to-node mesh | up | 01:33:35 | Established |
| 192.168.0.63 | node-to-node mesh | up | 02:48:04 | Established |
---------------------------------------------------------------IPv6 BGP statusrootmaster1:~# calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 10.244.0.0/16 true Never CrossSubnet false false all()rootmaster1:~# kubectl get pod -n calico-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-b7fb9d96c-pbf9s 1/1 Running 3 (80m ago) 4d18h
calico-node-gdsjw 1/1 Running 30 (2m32s ago) 4d18h
calico-node-hvqg4 1/1 Running 3 (80m ago) 4d18h
calico-node-rj9dd 1/1 Running 3 (80m ago) 4d17h
calico-typha-55ccdf44bf-v2zmm 1/1 Running 3 (80m ago) 4d18h
calico-typha-55ccdf44bf-w5l8w 1/1 Running 3 (80m ago) 4d18h
csi-node-driver-bqvb7 2/2 Running 6 (80m ago) 4d18h
csi-node-driver-cw59h 2/2 Running 6 (80m ago) 4d18h
csi-node-driver-hbw2n 2/2 Running 6 (80m ago) 4d18h概念原理说明
1. Layer2模式
该部分的官方文档请参考[layer2模式](https://metallb.universe.tf/concepts/layer2/)
以下时摘取部分进行翻译
在 Layer 2 模式下一个节点承担起向本地网络广告服务的责任。从网络的角度来看这台机器的网络接口上似乎分配了多个 IP 地址。
在底层MetalLB 响应 IPv4 服务的 ARP 请求和 IPv6 服务的 NDP 请求。
Layer 2 模式的主要优势是其普遍性它可以在任何以太网网络上工作无需特殊硬件甚至不需要高级路由器。
负载均衡行为
在 Layer 2 模式下所有针对服务 IP 的流量都会转发到一个节点然后kube-proxy 会将流量分发到所有的服务 pod。
从这个意义上讲Layer 2 并没有实现一个负载均衡器而是实现了一种故障转移机制以便在当前主节点由于某种原因失败时其他节点可以接管。
如果主节点由于某种原因失败故障转移是自动的使用 memberlist 检测到失败节点此时新节点接管失败节点的 IP 地址。
局限性
Layer 2 模式有两个主要限制需要注意单节点瓶颈和潜在的故障转移速度慢。
单节点瓶颈
在 Layer 2 模式下一个通过选举产生的主节点接收所有服务 IP 的流量。这意味着服务的入口带宽被限制在单个节点的带宽范围内。这是使用 ARP 和 NDP 引导流量的一个根本性限制。
潜在的故障转移速度慢
在故障转移方面MetalLB 也实现了自动故障转移。目前的机制是通过 memberlist 这个基于 gossip 协议的成员和故障检测的库其他节点检测到 Leader 故障后自动重新选举出新 Leader新的 Leader 自动接管所有 ExternalIP 并发送大量二层数据包来通知客户端(也就是区域网中的其他节点) ExternalIP 的 MAC 地址变化。
根据官网文档描述大部分主流操作系统的现代版本Windows、Mac、Linux都正确实现了 Layer 2 故障转移问题只会出现在较旧或不常见的操作系统上。故障转移正常情况下会在几秒内完成一般不会超过 10 秒。在更新完成前 ExternalIP 会无法访问。
L2 主节点选举的工作原理
给定负载均衡器 IP 的“主节点”将要广播 IP 的节点的选举是无状态的其工作方式如下
每个 speaker 收集给定 IP 的潜在广播者列表考虑活跃的 speaker、外部流量策略、活跃的端点、节点选择器等因素。每个 speaker 都进行相同的计算获取“节点VIP”元素的哈希值排序列表并在自己是该列表的第一个条目时宣布服务。
2. BGP模式
该部分的官方文档请参考bgp模式
在BGP模式下集群中的每个节点都会与你的网络路由器建立BGP对等会话并利用这个对等会话来通告集群外部服务的IP地址。
假设你的路由器配置支持多路径这就能实现真正的负载均衡MetalLB发布的路由彼此等价除了它们的下一跳nexthop不同。这意味着路由器会同时使用所有下一跳并在这之间进行负载均衡。
当数据包到达节点后kube-proxy负责最后一跳的流量路由将数据包定向到服务中特定的一个Pod上。
负载均衡行为
负载均衡的具体行为取决于你使用的具体路由器型号和配置但通常的行为是基于包哈希值按连接进行负载均衡。“按连接”指的是单个TCP或UDP会话的所有数据包都将被导向集群中的单一机器。流量的分发仅发生在不同的连接间而不是在一个连接内的数据包之间。
将单个连接的数据包分散到多个集群节点会导致以下问题 将单个连接分散到多条路径上会导致线路上的数据包重排序这对终端主机的性能影响巨大。 Kubernetes内部的节点间流量路由并不保证一致性。这意味着两个不同的节点可能会将同一连接的数据包路由到不同的Pod导致连接失败。
局限性
BGP 模式最大的弊端就是不能优雅的处理节点下线。当集群中某个节点下线时所有客户端对这个节点的连接都会被主动断开。 客户端一般会出现一个 Connection reset by peer 错误 同时由于是对每个数据包基于 hash 值进行负载均衡因此对后端节点数是非常敏感的这也是 BGP 的一个优点故障转移非常快。
正因为 BGP 故障转移很快反而引发了一个 BGP 模式的最大缺点由于 BGP 会对每个数据包做负载均衡在主机发生故障时会快速切换到新的主机上从而引发节点变动时同一连接的不同数据包可能会发送到不同主机上导致网络导致的网络重排问题。 比如第一个包转发到节点 A然后处理第二个包时添加或故障了一个节点按照新的节点数进行负载均衡计算可能第二个数据包就被分到节点 B 了节点 B 很明显是不能正确处理这个数据包的。 对客户端来说就是这次请求直接失败了。 解决该弊端的方法没有太理想的解决办法只能尽量采取一些优化手段
BGP路由器配置使用更稳定的ECMP哈希算法。比如“弹性ECMP”或“弹性LAG”。使用这样的算法极大地减少了后端节点更改时受影响的连接。将你的服务部署固定到特定的节点上尽量少的增删节点。在流量“低谷期”进行服务部署的变更。将每个逻辑服务拆分为两个具有不同IP的Kubernetes服务并借助DNS优雅地将用户流量从一个服务迁移到另一个服务。在客户端添加透明的重试逻辑以优雅地从突然的断开中恢复。如果客户端是如移动应用或富单页Web应用这类应用这种方法尤其有效。将你的服务置于入口控制器ingress controller之后。入口控制器本身可以使用MetalLB来接收流量但在BGP和你的服务之间有一个有状态的层意味着你可以更改服务而不必担心。你只需要在更改入口控制器本身的部署时小心例如当增加更多的NGINX Pod来扩展规模时。接受偶尔会有连接重置的爆发。对于低可用性的内部服务而言这可能是可接受的现状。
部署 MetalLB
官方提供了好几种安装方式yaml、helm、operator 等这里使用 yaml 方式安装。
如果kube-proxy使用的是IPVS模式在v1.14.2版本之后需要启用strict ARP mode。
rootmaster1:~# kubectl edit configmap -n kube-system kube-proxy
...ipvs:excludeCIDRs: nullminSyncPeriod: 0sscheduler: strictARP: true # 启用strictARPsyncPeriod: 0stcpFinTimeout: 0stcpTimeout: 0sudpTimeout: 0skind: KubeProxyConfigurationlogging:flushFrequency: 0options:json:infoBufferSize: 0verbosity: 0metricsBindAddress: mode: ipvs # kube-proxy模式默认为iptablesnodePortAddresses: nulloomScoreAdj: null
...# 重启kube-proxy生效
kubectl rollout restart daemonset/kube-proxy -n kube-system说明 kube-proxy默认使用的是iptables转发模式在大规模集群中建议改为ipvs。如果当前转发模式是ipvs启用严格的 ARP。 1. 创建 MetalLB 命名空间
kubectl create namespace metallb-system2. 使用Manifest安装MetalLB
MetalLB 提供了一组清单文件来部署所需的组使用如下命令部署
curl https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml -O
kubectl apply -f metallb-native.yaml查询官网文档获取最新的安装命令。
3. 验证安装
rootmaster1:~# kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-56bb48dcd4-pp4w4 1/1 Running 2 (60m ago) 47h
speaker-4kfhv 1/1 Running 1 (60m ago) 43h
speaker-5b5sq 1/1 Running 7 (60m ago) 47h
speaker-wctd6 1/1 Running 7 (60m ago) 47h4. 配置 MetalLB
MetalLB 支持两种操作模式Layer 2 模式和 BGP 模式。因为 BGP 对路由器有要求POC测试时建议使用 Layer2 模式。
Layer2模式配置
Layer 2 模式是最简单的配置方式在许多情况下你不需要任何特定协议的配置只需要 IP 地址。
Layer 2 模式不需要将 IP 绑定到你的工作节点的网络接口上。它通过直接响应本地网络上的 ARP 请求向客户端提供机器的 MAC 地址来工作。
Layer2模式配置首先创建一个IPAddressPool资源对象:
rootmaster1:~/metallb# cat ip-pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: ip-poolnamespace: metallb-system
spec:addresses:- 192.168.0.240-192.168.0.250 #分配给LB的IP池备注 IP地址池与集群IP位于同一个网段。多个实例IP地址池可以共存,并且可以分配IPV4和IPV6地址。 应用创建资源
kubectl apply -f ip-pool.yaml创建一个广播声明关联上面的 IP 池对象:
rootmaster1:~/metallb# cat advertise.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: l2advernamespace: metallb-system
spec:ipAddressPools:- ip-pool应用创建资源
kubectl apply -f advertise.yaml说明 如果不设置关联到 IPAdressPoolL2Advertisement 默认会关联所有可用的 IPAdressPool。 BGP模式配置
本文使用Layer2模式测试后续补充BGP模式的POC验证。关于使用配置可以参考https://metallb.universe.tf/configuration/#bgp-configuration
高级配置
Metal LB支持一些高级配置用于特殊的需求场景详见官方文档 区分不同的IP地址池:https://metallb.universe.tf/configuration/_advanced_ipaddresspool_configuration/#controlling-automatic-address-allocation 将IP地址池分配给指定的命名空间和服务https://metallb.universe.tf/configuration/_advanced_ipaddresspool_configuration/#reduce-scope-of-address-allocation-to-specific-namespace-and-service
Layer2模式demo应用示例
1. 创建一个示例应用
为了验证 MetalLB 的配置是否正确你可以创建一个简单的 Nginx 服务。
创建一个 nginx-deployment.yaml 文件内容如下
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentlabels:app: nginx
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80应用创建资源
kubectl apply -f nginx-deployment.yaml2. 暴露 Nginx 服务
创建一个 nginx-service.yaml 文件内容如下
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80type: LoadBalancer应用此服务
kubectl apply -f nginx-service.yaml3. 验证服务
检查服务的外部 IP 地址是否已分配
kubectl get svc nginx-service你应该会看到类似以下的输出
rootmaster1:~/metallb# kubectl get svc nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service LoadBalancer 10.101.212.243 192.168.0.240 80:30981/TCP 2d16h在浏览器中访问 http://EXTERNAL-IP例如 http://192.168.0.240应该可以看到 Nginx 的默认页面。
或者使用curl测试
rootmaster1:~/metallb# curl http://192.168.0.240
!DOCTYPE html
html
head
titleWelcome to nginx!/title
style
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
/style
/head
body
h1Welcome to nginx!/h1
pIf you see this page, the nginx web server is successfully installed and
working. Further configuration is required./ppFor online documentation and support please refer to
a hrefhttp://nginx.org/nginx.org/a.br/
Commercial support is available at
a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p
/body
/html总结
1. MetalLB工作流程
MetalLB 做的工作可以分为两个部分 地址分配当创建 LoadBalancer Service 时MetalLB 会为其分配 IP 地址。这个 IP 地址是从预先配置的 IP 地址库获取的。当 Service 删除后已分配的 IP 地址会重新回到地址库。使用Controller实现地址分配以 Deployment方式运行用于监听 Service 的变更分配/回收 IP 地址。 对外广播分配了 IP 地址之后需要让集群外的网络知道这个地址的存在。由Speaker实现地址对外广播以 DaemonSet 方式运行对外广播 Service 的 IP 地址。MetalLB 使用了标准的TCP/IP协议实现ARP、NDP 或者 BGP。
在 Layer 2 模式使用 ARPipv4/NDPipv6 协议在 BPG 模式自然是使用 BGP 协议。 ARPAddress Resolution Protocol是根据IP地址获取物理地址的一个TCP/IP协议。 NDPneighbor Discovery protocolICMPv6的子协议是IPV6协议体系中一个重要的基础协议NDP替代了IPV4中的ARP。定义了使用ICMPv6报文实现地址解析跟踪邻居状态重复地址检测路由器发现以及重定向等功能。 具体的工作流如下 Controller 负责监听 Service 变化并分配或回收 IP。 当 Service 配置为 LoadBalancer 模式时从 IP 池分配给到相应的 IP 地址并对该 IP 的生命周期进行管理。 创建 Service 时或者从非 LoadBalancer 类型修改为 LoadBalancer 类型时从 IP 池选择一个 IP 并分配删除 Service 或者从 LoadBalancer 类型修改为非 LoadBalancer 类型时回收该 IP 到 IP 池 Speaker 则会依据选择的协议进行相应的广播或应答实现 IP 地址的通信响应 当业务流量通过 TCP/UDP 协议到达指定的 Node 时由 Node 上面运行的 Kube-Proxy 组件对流量进行处理并分发到对应服务的 Pod 上面。 如果是 Layer2 模式 Speaker 就会响应 ARPipv4/NDPipv6请求。如果是 BGP 模式 Speaker 则发送 BGP 广播将路由规则同步给 peer。
2. 两种模式的优缺点
Layer2 模式
优点通用性好适用于任何网络环境不需要特殊的硬件。缺点单节点瓶颈和故障转移慢
Layer2 模式是一种基础、通用的实现能用而且易于使用没有任何限制但是局限性比较大。
BGP 模式
优点使用 BGP 可以在多节点间负载均衡没有单节点瓶颈同时故障转移很快。缺点 需要支持 BGP 路由协议的软路由或者硬件 路由器设备。
参考资料
MetalLB, bare metal load-balancer for KubernetesMetal LB installation裸机 Kubernetes 集群负载均衡器: MetalLB 简明教程 - (lixueduan.com)