您的位置:首页 >聚焦 >

本地集群使用OpenELB实现Load Balancer

2022-04-13 07:48:46    来源:程序员客栈

为了方便测试,最近准备为 Ingress 控制器配置一个 LoadBalaner 类型的 Service,由于我这是本地私有环境,所以需要部署一个支持该服务类型的负载均衡器,在社区中目前最流行的应该是 MetalLB 这个项目,现在也属于 CNCF 沙箱项目,该项目在 2017 年底发起,经过 4 年的发展已经在社区被广泛采用,但是我这边在测试使用过程中一直表现不稳定,经常需要重启控制器才能生效。所以将目光转向了最近国内青云开源的另外一个负载均衡器 OpenELB。

OpenELB 之前叫 PorterLB,是为物理机(Bare-metal)、边缘(Edge)和私有化环境设计的负载均衡器插件,可作为 Kubernetes、K3s、KubeSphere 的 LB 插件对集群外暴露 LoadBalancer 类型的服务,现阶段是 CNCF 沙箱项目,核心功能包括:

基于 BGP 与 Layer 2 模式的负载均衡基于路由器 ECMP 的负载均衡IP 地址池管理使用 CRD 进行 BGP 配置与 MetaLB 对比

OpenELB 作为后起之秀,采用了更加 Kubernetes-native 的实现方式,可以直接通过 CRD 进行配置管理,下面是关于 OpenELB 与 MetaLB 的简单对比。

云原生架构

在 OpenELB 中,不管是地址管理,还是 BGP 配置管理,你都可以使用 CRD 来配置。对于习惯了 Kubectl 的用户而言, OpenELB 十分友好,在 MetalLB 中,需通过 ConfigMap 来配置,感知它们的状态需要通过查看监控或者日志。

灵活的地址管理

OpenELB 通过 EIP 这个自定义资源对象来管理地址,它定义子资源 Status 来存储地址分配状态,这样就不会存在分配地址时各副本发生冲突的情况。

使用 gobgp 发布路由

不同于 MetalLB 自己实现 BGP 协议, OpenELB 采用标准的 gobgp 来发布路由,这样做的好处如下:

开发成本低,且有 gobgp 社区支持可以利用 gobgp 丰富特性通过 BgpConf/BgpPeer CRD 动态配置 gobgp,用户无需重启 OpenELB 即可动态加载最新的配置信息gobgp 作为 lib 使用时, 社区提供了基于 protobuf 的 API,OpenELB 在实现 BgpConf/BgpPeer CRD 时也是参照该 API,并保持兼容OpenELB 也提供 status 用于查看 BGP neighbor 配置,状态信息丰富

架构简单,资源占用少

OpenELB 目前只用部署 Deployment 即可,通过多副本实现高可用,部分副本崩溃后并不会影响已建立的正常连接。

BGP 模式下, Deployment 不同副本都会与路由器建立连接用于发布等价路由,所以正常情况下我们部署两个副本即可。在 Layer 2 模式下,不同副本之间通过 Kubernetes 提供的 Leader Election 机制选举 Leader,进而应答 ARP/NDP。

安装

在 Kubernetes 集群中,您只需要安装一次 OpenELB。安装完成后,集群中会安装一个 openelb-manager Deployment,其中包含一个 openelb-manager Pod。openelb-manager Pod 为整个 Kubernetes 集群实现了 OpenELB 的功能。安装完成后,可以扩展openelb-manager Deployment,将多个OpenELB副本(openelb-manager Pods)分配给多个集群节点,保证高可用。有关详细信息,请参阅配置多个 OpenELB 副本。

要安装使用 OpenELB 非常简单,直接使用下面的命令即可一键安装:

#注意如果不能获取k8s.gcr.io镜像,需要替换其中的镜像☸➜kubectlapply-fhttps://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml

上面的资源清单会部署一个名为 openelb-manager的 Deployment 资源对象,openelb-manager 的 Pod 为整个 Kubernetes 集群实现了 OpenELB 的功能,为保证高可用,可以将该控制器扩展为两个副本。第一次安装的时候还会为 admission webhook 配置 https 证书,安装完成后查看 Pod 的状态是否正常:

☸➜kubectlgetpods-nopenelb-systemNAMEREADYSTATUSRESTARTSAGEopenelb-admission-create--1-cf8570/1Completed058mopenelb-admission-patch--1-dhgrq0/1Completed258mopenelb-manager-848495684-nppkr1/1Running1(35mago)48mopenelb-manager-848495684-svn7z1/1Running1(35mago)48m☸➜kubectlgetvalidatingwebhookconfigurationNAMEWEBHOOKSAGEopenelb-admission162m☸➜kubectlgetmutatingwebhookconfigurationsNAMEWEBHOOKSAGEopenelb-admission162m

此外还会安装几个相关的 CRD 用户 OpenELB 配置:

☸➜kubectlgetcrd|grepkubespherebgpconfs.network.kubesphere.io2022-04-10T08:01:18Zbgppeers.network.kubesphere.io2022-04-10T08:01:18Zeips.network.kubesphere.io2022-04-10T08:01:18Z

配置

接下来我们来演示下如何使用 layer2 模式的 OpenELB,首先需要保证所有 Kubernetes 集群节点必须在同一个二层网络(在同一个路由器下),我测试的环境一共3个节点,节点信息如下所示:

☸➜kubectlgetnodes-owideNAMESTATUSROLESAGEVERSIONINTERNAL-IPEXTERNAL-IPOS-IMAGEKERNEL-VERSIONCONTAINER-RUNTIMEmaster1Readycontrol-plane,master15dv1.22.8192.168.0.111CentOSLinux7(Core)3.10.0-1160.25.1.el7.x86_64containerd://1.5.5node1Ready15dv1.22.8192.168.0.110CentOSLinux7(Core)3.10.0-1160.25.1.el7.x86_64containerd://1.5.5node2Ready15dv1.22.8192.168.0.109CentOSLinux7(Core)3.10.0-1160.25.1.el7.x86_64containerd://1.5.5

3个节点IP地址分别为 192.168.0.109、192.168.0.110、192.168.0.111。

首先需要为 kube-proxy 启用 strictARP,以便 Kubernetes 集群中的所有网卡停止响应其他网卡的 ARP 请求,而由 OpenELB 处理 ARP 请求。

☸➜kubectleditconfigmapkube-proxy-nkube-system......ipvs:strictARP:true......

然后执行下面的命令重启 kube-proxy 组件即可:

☸➜kubectlrolloutrestartdaemonsetkube-proxy-nkube-system

如果安装 OpenELB 的节点有多个网卡,则需要指定 OpenELB 在二层模式下使用的网卡,如果节点只有一个网卡,则可以跳过此步骤,假设安装了 OpenELB 的 master1 节点有两个网卡(eth0 192.168.0.2 和 ens33 192.168.0.111),并且 eth0 192.168.0.2 将用于 OpenELB,那么需要为 master1 节点添加一个 annotation 来指定网卡:

☸➜kubectlannotatenodesmaster1layer2.openelb.kubesphere.io/v1alpha1="192.168.0.2"

接下来就可以创建一个 Eip 对象来充当 OpenELB 的 IP 地址池了,创建一个如下所示的资源对象:

apiVersion:network.kubesphere.io/v1alpha2kind:Eipmetadata:name:eip-poolspec:address:192.168.0.100-192.168.0.108protocol:layer2disable:falseinterface:ens33

这里我们通过 address属性指定了 IP 地址池,可以填写一个或多个 IP 地址(要注意不同 Eip 对象中的 IP 段不能重叠),将被 OpenELB 使用,值格式可以是:

IP地址,例如 192.168.0.100IP地址/子网掩码,例如 192.168.0.0/24IP地址1-IP地址2,例如192.168.0.91-192.168.0.100

protocol属性用来指定 Eip 对象用于哪种 OpenELB 模式,可以配置为 layer2 或 bgp,默认为 bgp 模式,我们这里想使用 layer2 模式,所以需要显示指定interface是用来指定 OpenELB 监听 ARP 或 NDP 请求的网卡,该字段仅在协议设置为 layer2 时有效,我这里的环境是 ens33 网卡disable表示是否禁用 Eip 对象

创建完成 Eip 对象后可以通过 Status 来查看该 IP 池的具体状态:

☸➜kubectlgeteipNAMECIDRUSAGETOTALeip-pool192.168.0.100-192.168.0.10809☸➜kubectlgeteipeip-pool-oyamlapiVersion:network.kubesphere.io/v1alpha2kind:Eipmetadata:finalizers:-finalizer.ipam.kubesphere.io/v1alpha1name:eip-poolspec:address:192.168.0.100-192.168.0.108interface:ens33protocol:layer2status:firstIP:192.168.0.100lastIP:192.168.0.108poolSize:9ready:truev4:true

到这里 LB 的地址池就准备好了,接下来我们创建一个简单的服务,通过 LB 来进行暴露,如下所示:

#openelb-nginx.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:nginxspec:selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:-name:nginximage:nginxports:-containerPort:80

这里部署一个简单的 nginx 服务:

☸➜kubectlapply-fopenelb-nginx.yaml☸➜kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEnginx-7848d4b86f-zmm8l1/1Running042s

然后创建一个 LoadBalancer类型的 Service 来暴露我们的 nginx 服务,如下所示:

#openelb-nginx-svc.yamlapiVersion:v1kind:Servicemetadata:name:nginxannotations:lb.kubesphere.io/v1alpha1:openelbprotocol.openelb.kubesphere.io/v1alpha1:layer2eip.openelb.kubesphere.io/v1alpha2:eip-poolspec:selector:app:nginxtype:LoadBalancerports:-name:httpport:80targetPort:80

注意这里我们为 Service 添加了几个 annotations 注解:

lb.kubesphere.io/v1alpha1: openelb用来指定该 Service 使用 OpenELBprotocol.openelb.kubesphere.io/v1alpha1: layer2表示指定 OpenELB 用于 Layer2 模式eip.openelb.kubesphere.io/v1alpha2: eip-pool用来指定了 OpenELB 使用的 Eip 对象,如果未配置此注解,OpenELB 会自动使用与协议匹配的第一个可用 Eip 对象,此外也可以删除此注解并添加 spec:loadBalancerIP字段(例如 spec:loadBalancerIP: 192.168.0.108)以将特定 IP 地址分配给 Service。

同样直接创建上面的 Service:

☸➜kubectlapply-fopenelb-nginx-svc.yamlservice/nginxcreated☸➜kubectlgetsvcnginxNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEnginxLoadBalancer10.100.126.91192.168.0.10180:31555/TCP4s

创建完成后可以看到 Service 服务被分配了一个 EXTERNAL-IP,然后我们就可以通过该地址来访问上面的 nginx 服务了:

☸➜curl192.168.0.101Welcometonginx!

Welcometonginx!

Ifyouseethispage,thenginxwebserverissuccessfullyinstalledandworking.Furtherconfigurationisrequired.

Foronlinedocumentationandsupportpleaserefertonginx.org.
Commercialsupportisavailableatnginx.com.

Thankyouforusingnginx.

此外 OpenElb 还支持 BGP 模式以及集群多路由的场景,更新使用方法可以查看官方文档 https://openelb.github.io/docs/ 了解更多相关信息。

参考文档https://openelb.github.io/docs/https://kubesphere.io/zh/blogs/openelb-joins-cncf-sandbox-project/https://mp.weixin.qq.com/s/uFwYaPE7cVolLWxYHcgZdQ

关键词: 首先需要 地址分配 负载均衡

相关阅读