这几天在使用MetalLB做集群的负载均衡方案,准备写几篇博客记录一下,主要有三篇:

MetalLB基本内容

MetalLB源码分析

MetalLB实现负载均衡方案(开多个LB IP)

下面进入第一篇:MetalLB基本介绍

一、service

servcie背景

Kubernetes中一个应用服务会有一个或多个实例,每个实例(Pod)的IP地址由网络插件动态随机分配(Pod重启后IP地址会改变)。为屏蔽这些后端实例的动态变化和对多实例的负载均衡,引入了 Service这个资源对象。

Type类型

根据创建 Service 的 type 类型不同,主要分为几下几种:

ClusterIP:通过为 Kubernetes 的 Service 分配一个集群内部可访问的固定虚拟IP(Cluster IP),实现集群内的访问;

NodePort:将 service 的 port 映射到集群内每个节点的相同一个端口,实现通过 nodeIP:nodePort 从集群外访问服务;

LoadBalance:向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的 nodePort),实现从集群外通过 LB 访问服务;

Port

Service 中主要涉及三种 Port:

port 表示 service 暴露在 clusterIP 上的端口,clusterIP:Port 是提供给集群内部访问 kubernetes 服务的入口;

NodePort:提供给从集群外部访问 kubernetes 服务的入口;

TargetPort:容器port,targetPort 是 pod 上的端口,从 port 和 nodePort 上到来的数据最终经过 kube-proxy 流入到后端 pod 的 targetPort 上进入容器。

port 和 nodePort 都是 service 的端口,前者暴露给从集群内访问服务,后者暴露给从集群外访问服务。从这两个端口到来的数据都需要经过反向代理 kube-proxy 流入后端具体 pod 的 targetPort,从而进入到 pod 上的容器内。

IP

** 使用 Service 服务会涉及到几种 IP:**

Cluster IP:虚拟地址,由 kube-proxy 使用 iptables 规则重新定向到其本地端口,再均衡到后端Pod。当 kube-proxy 发现一个新的 service 后,它会在本地节点打开一个任意端口,创建相应的iptables 规则,重定向服务的 clusterIP 和 port 到这个新建的端口,开始接受到达这个服务的连接。

Pod IP:每个 Pod 启动时,会自动创建一个镜像为 gcr.io/google_containers/pause 的容器,Pod内部其他容器的网络模式使用container模式,指定为 pause 容器的ID(network_mode: “container:pause 容器ID”),使得 Pod 内所有容器共享 pause 容器的网络,与外部的通信经由此容器代理,pause容器的 IP 也可以称为Pod IP。

Node IP: 将服务作为一个应用程序内部的层次,使的服务可以从集群外部访问,指定 service 的spec.type=NodePort,通过 nodeip:nodeport 从集群外访问服务。

工作方式

定义服务的时候通过 selector 指定服务对应的 pods,根据 pods 的地址创建出 endpoints 作为服务后端;Endpoints Controller 会 watch Service 以及 pod 的变化,维护对应的 Endpoint 信息。kube-proxy根据 Service 和 Endpoint 来维护本地的路由规则。当 Endpoint 发生变化,即 Service 以及关联的pod发生变化,kube-proxy 都会在每个节点上更新 iptables,实现一层负载均衡。

二、MetalLB

基本介绍

Kubernetes 没有为裸机集群提供网络负载平衡器的实现(服务类型为 LoadBalancer)。Kubernetes 附带的 Network LB 的实现都是调用各种 IaaS 平台(GCP,AWS,Azure等)的粘合代码。如果不在支持IaaS 平台(GCP,AWS,Azure等)上运行,则 LoadBalancers 在创建时将无限期保持“待处理”状态。

MetalLB是 Kubernetes 集群中关于LoadBalancer的一个具体实现,主要用于暴露k8s集群的服务到集群外部访问。由两个共同提供此服务的工作负载(workload):地址分配和外部公告;对应的就是在 k8s中部署的 controller 和 speaker。

地址分配(address allocation)

需要给 MetalLB 分配一段 IP,接着它会根据 service 中的相关配置来给LoadBalancer的服务分配IP,LoadBalancer的IP可以手动指定,也可以让MetalLB自动分配;同时还可以在 MetalLB 的configmap中配置多个 IP 段,并且单独设置每个 IP 段是否开启自动分配。

地址分配(address allocation)主要就是由作为 deployment 部署的 controller 来实现,它负责监听集群中的 service 状态并且分配 IP。

外部公告(external announcement)

外部公告的主要功能就是要把服务类型为LoadBalancer的服务的IP公布到网络中去,确保客户端能够正常访问到这个 IP 。MetalLB 对此的实现方式主要有三种:ARP/NDP和BGP;其中 ARP/NDP 分别对应IPv4/IPv6 协议的 Layer2 模式,BGP路由协议则是对应 BGP 模式。

外部公告主要就是由作为daemonset部署的speaker来实现,它负责在网络中发布 ARP/NDP 报文或者是和 BGP 路由器建立连接并发布 BGP 报文。

工作原理

Metallb 包含两个组件,Controller 和 Speaker,Controller 为 Deployment 部署方式,而 Speaker 则采用 Daemonset 方式部署到集群内部各个Node节点。

具体的工作原理如下图所示,Controller 负责监听 Service 变化,当 Service 配置为 LoadBalancer 模式时,从 IP 池分配给到相应的 IP 地址并对该 IP 的生命周期进行管理。Speaker 则会依据选择的协议进行相应的广播或应答,实现 IP 地址的通信响应。当业务流量通过 TCP/UDP 协议到达指定的 Node 时,由Node 上面运行的 Kube-Proxy 组件对流量进行处理,并分发到对应服务的 Pod 上面。

kubernetes 服务负载不均 kubernetes 负载均衡方案_kubernetes

下一篇会进行源码分析,尽情期待。

2022.09.24
BenDingCoding