k8s之基于metallb实现LoadBalancer型Service
一、实验说明
MetalLB
MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议,主要用于暴露 K8s 集群的服务到集群外部访问,MetalLB 可以让我们在 K8s 集群中创建服务类型为 LoadBalancer 的服务,并且无需依赖云厂商提供的LoadBalancer。
它具有两个共同提供此服务的工作负载:地址分配(address allocation)和外部公告(external announcement),对应在 K8s 中部署的 controller 和 speaker。
1、address allocation
地址分配这个功能比较好理解,首先我们需要给 MetalLB 分配一个 IP 段,接着它会根据K8s 的 Service 中的相关配置来给 LoadBalancer 的服务分配 IP,LoadBalancer 的 IP 可以手动指定,也可以让 MetalLB 自动分配。地址分配主要就是由作为 Deployment 部署的 controller 来实现,它负责监听集群中的 Service 状态并且分配 IP。
2、external announcement
外部公告的主要功能就是要把服务类型为 LoadBalancer 的服务的 EXTERNAL-IP 公布到网络中去,确保客户端能够正常访问到这个 IP。MetalLB 对此的实现方式主要有三种:ARP/NDP 和 BGP,其中ARP/NDP 分别对应 IPv4/IPv6 协议的 Layer2 模式,BGP 路由协议则是对应 BGP 模式。外部公告主要通过由DaemonSet 部署的 speaker 来实现,它负责在网络中发布 ARP/NDP 报文或者是和 BGP 路由器建立连接并发布BGP 报文。
MetalLB 有 Layer2 模式和 BGP 模式,任选一种模式进行配置即可。
- Layer2 模式
Layer2 模式下,每个 Service 会有集群中的一个 Node 来负责。服务的入口流量全部经由单个节点,然后该节点的 Kube-Proxy 会把流量再转发给服务的 Pods。
也就是说,该模式下 MetalLB 并没有真正提供负载均衡器。尽管如此,MetalLB 提供了故障转移功能,如果持有 IP 的节点出现故障,则默认 10 秒后即发生故障转移,IP 会被分配给其它健康的节点。
Layer2 模式的优缺点:
Layer2 模式更为通用,不需要用户有额外的设备;
Layer2 模式下存在单点问题,服务的所有入口流量经由单点,其网络带宽可能成为瓶颈;
由于 Layer 2 模式需要 ARP/NDP 客户端配合,当故障转移发生时,MetalLB 会发送 ARP 包来宣告 MAC 地址和 IP 映射关系的变化,地址分配略为繁琐。
- BGP模式
当在第三层工作时,集群中所有机器都和你控制的最接近的路由器建立 BGP 会话,此会话让路由器能学习到如何转发针对 K8S 服务 IP 的数据包。
通过使用 BGP,可以实现真正的跨多节点负载均衡(需要路由器支持 multipath),还可以基于 BGP 的策略机制实现细粒度的流量控制。
具体的负载均衡行为和路由器有关,可保证的共同行为是:每个连接(TCP 或 UDP 会话)的数据包总是路由到同一个节点上。
BGP 模式的优缺点:
不能优雅处理故障转移,当持有服务的节点宕掉后,所有活动连接的客户端将收到 Connection reset by peer ;
BGP 路由器对数据包的源 IP、目的 IP、协议类型进行简单的哈希,并依据哈希值决定发给哪个 K8S 节点。问题是 K8S 节点集是不稳定的,一旦(参与 BGP)的节点宕掉,很大部分的活动连接都会因为 rehash 而坏掉。
BGP 模式问题的缓和措施:
将服务绑定到一部分固定的节点上,降低 rehash 的概率。
在流量低的时段改变服务的部署。
客户端添加透明重试逻辑,当发现连接 TCP 层错误时自动重试。
实验目的
基于metallb实现kubernetes的LoadBalancer型Service。
环境说明
VMware Workstation安装三台虚拟机,安装K8S集群,网络模式NAT模式。
master 11.0.1.131
node01 11.0.1.132
node02 11.0.1.133
root@master:/home/user# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 37d v1.26.3
node01 Ready <none> 37d v1.26.3
node02 Ready <none> 37d v1.26.3
二、安装metallb
1、修改ipvs严格ARP模式
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
2、创建metallb
root@master:/home/user# kubectl apply -f https://mirror.ghproxy.com/https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/etallb-native.yaml
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/addresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
configmap/metallb-excludel2 created
secret/webhook-server-cert created
service/webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created
root@master:/home/user# kubectl get ns
NAME STATUS AGE
default Active 37d
dev Active 18d
kube-node-lease Active 37d
kube-public Active 37d
kube-system Active 37d
metallb-system Active 2m24s
myapp Active 26d
myserver Active 36d
root@master:/home/user# kubectl api-versions
admissionregistration.k8s.io/v1
apiextensions.k8s.io/v1
apiregistration.k8s.io/v1
apps/v1
authentication.k8s.io/v1
authorization.k8s.io/v1
autoscaling/v1
autoscaling/v2
batch/v1
certificates.k8s.io/v1
coordination.k8s.io/v1
crd.projectcalico.org/v1
discovery.k8s.io/v1
events.k8s.io/v1
flowcontrol.apiserver.k8s.io/v1beta2
flowcontrol.apiserver.k8s.io/v1beta3
metallb.io/v1alpha1
metallb.io/v1beta1
metallb.io/v1beta2
networking.k8s.io/v1
node.k8s.io/v1
policy/v1
rbac.authorization.k8s.io/v1
scheduling.k8s.io/v1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
root@master:/home/user# kubectl get pod -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-586bfc6b59-wg286 1/1 Running 0 61s
speaker-bzhpc 1/1 Running 0 60s
speaker-k2s9j 1/1 Running 0 61s
3、创建metallb地址池
metallb的Addres Allocation (地址分配) : 基于用户配置的地址池,为用户创建的LoadBalancer分配IP地址,并配置在节点上。
本实验的地址池选择宿主机的NAT池网段,必须保证网络可达。
root@master:/home/user# cat metallb-ippool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: localip-pool
namespace: metallb-system
spec:
addresses:
- 11.0.1.140-11.0.1.146
autoAssign: true
avoidBuggyIPs: true
root@master:/home/user# kubectl apply -f metallb-ippool.yaml
ipaddresspool.metallb.io/localip-pool created
root@master:/home/user# kubectl get ipaddresspool -n metallb-system
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
localip-pool true true ["11.0.1.140-11.0.1.146"]
4、通过网卡对外通告
External Announcement(对外公告):让集群外部的网络了解新分配的IP地址,MetallB使用ARP、NDP或BGP实现。
root@master:/home/user# cat metallb-l2.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: localip-pool-l2a
namespace: metallb-system
spec:
ipAddressPools:
- localip-pool
interfaces:
- ens33
root@master:/home/user# kubectl apply -f metallb-l2.yaml
l2advertisement.metallb.io/localip-pool-l2a created
root@master:/home/user# kubectl get l2advertisement -n metallb-system
NAME IPADDRESSPOOLS IPADDRESSPOOL SELECTORS INTERFACES
localip-pool-l2a ["localip-pool"] ["ens33"]
三、实现应用的对外发布
1、创建deployment型工作负载的应用
root@master:/home/user# kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=3
deployment.apps/demoapp created
root@master:/home/user# kubectl get pod
NAME READY STATUS RESTARTS AGE
demoapp-75f59c894-2p5wr 1/1 Running 0 101s
demoapp-75f59c894-fx8xh 1/1 Running 0 101s
demoapp-75f59c894-k5stt 1/1 Running 0 101s
2、创建loadbalancer Service对外发布应用
root@master:/home/user# cat services-loadbalancer-demo.yaml
kind: Service
apiVersion: v1
metadata:
name: demoapp-loadbalancer-svc
spec:
type: LoadBalancer
selector:
app: demoapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
root@master:/home/user# kubectl apply -f services-loadbalancer-demo.yaml
service/demoapp-loadbalancer-svc created
root@master:/home/user# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-loadbalancer-svc LoadBalancer 10.200.135.7 11.0.1.140 80:30970/TCP 18s
kubernetes ClusterIP 10.200.0.1 <none> 443/TCP 37d
以上已经为service自动分配外部地址11.0.1.140
四、通过外部IP访问集群
root@master:/home/user# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demoapp-75f59c894-2p5wr 1/1 Running 0 36m 10.100.231.117 node02 <none> <none>
demoapp-75f59c894-fx8xh 1/1 Running 0 36m 10.100.231.119 node02 <none> <none>
demoapp-75f59c894-k5stt 1/1 Running 0 36m 10.100.231.118 node02 <none> <none>
刷新网页可以看到实现了流量的负载均衡,
五、参考
https://blog.csdn.net/weixin_39246554/article/details/129343617
https://zhuanlan.zhihu.com/p/617807098
https://fafucoder.github.io/categories/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)