K8S Service的LoadBalancer解决方案之OpenELB
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
目录
一.负载均衡器OpenELB
1.什么是OpenELB
OpenELB是一个开源的云原生负载均衡器实现,可以在基于裸金属服务器,边缘以及虚拟化的Kubernetes环境中使用LoadBalancer类型的Service对外暴露服务。
OpenELB项目最初由kubeSphere社区发起,目前已作为CNCF沙箱项目加入CNCF基金会,由OpeELB开源社区维护与支持。
OpenELB之前叫 PorterLB,是为物理机(Bare-metal)、边缘(Edge)和私有化环境设计的负载均衡器插件,可作为 Kubernetes、K3s、KubeSphere的LB插件对集群外暴露LoadBalancer类型的服务。
与MetalLB(2017年底开源)类似,OpenELB也拥有三种主要工作模式,即Layer2,BGP,VIP模式。OpenELB的BGP模式目前不支持IPv6,无论是Layer2模式还是GBP模式,核心思路都是通过某种方式将特定VIP的流量引到K8S集群中,然后通过kube-proxy将流量转发到后面的特定服务。
OpenELB使用的前提条件是k8s 1.15+,若用helm部署则建议使用3版本。
官网链接:
https://openelb.io/
https://openelb.io/docs/getting-started/installation/install-openelb-on-kubernetes/#prerequisites
2.Layer2模式

Layer2模式需要我们的K8S集群基础环境支持发送anonymouse ARP/DNP packets。因为OpenELB是针对裸金属服务器设计的,因此如果是在云环境中部署,需要注意是否满足条件。
如上图所示:
- 1.客户端机器访问Service的LoadBalancer类型,其VIP为192.168.0.91(和K8S的物理节点同网段),后端有两个Pod;
- 2.安装在Kubernetes集群中的OpenELB随机选择一个节点来处理Service请求,当局域网中出现ARP request数据包来查询192.168.0.91的MAC地址的时候,OpenELB会进行回应(使用worker 1的MAC地址),此时路由器将Service的VIP 192.168.0.91和worker 1的MAC地址绑定,之后所有的请求到192.168.0.91的数据包会转发到worker1上;
- 3.Service流量到达worker 1后,work 1上的kube-proxy将流量转发到后端的两个Pod进行负载均衡,将这些Pod不一定在worker 1上;
- 4.如果worker 1出现故障,OpenELB会重新向路由器发送ARP/NDP数据包,将Server IP地址映射到worker 2的MAC地址,Service流量切换到wroker 2上;
- 5.主备切换工程并不是瞬间完成的,中间会产生一定时间的服务中断;
- 6.如果集群中已经部署了多个OpenELB副本,OpenELB使用k8s的leader选举特性算法来进行选主,从而确保只有一个副本相应ARP/DNP请求;
参考链接:
https://openelb.io/docs/concepts/layer-2-mode/
3.BGP模式

如上图所示,解释说明如下:
- 1.有一个类型为LoadBalancer的Service,其VIP为172.22.0.2(和K8S的节点不同网段),后端有两个Pod(分别为pod1和pod2);
- 2.安装在Kubernetes集群的OpenELB与BGP路由器建立BGP连接,并将去往172.22.0.2的路由发布到BGP路由器,在配置得当的情况下,路由器上面的路由表可以看到172.22.0.2这个VIP的吓一条有多个节点(均为K8S的宿主机节点);
- 3.当外部客户端机器尝试访问Service时,BGP路由器根据从OpenELB获取的路由,在master,work1和worker2节点之间进行流量负载均衡。Service流量到达一个节点后,该节点上的kube-proxy将流量转发到后端的两个pod进行负载均衡,这些pod不一定在该节点上;
参考链接:
https://openelb.io/docs/concepts/bgp-mode/
4.VIP模式

如上图所示,解释说明如下:
- 1.Kubernetes集群中部署了一个由两个Pod支持的服务,并分配了一个IP地址192.168.0.91(Service IP地址与群集节点IP地址位于同一网段上)用于外部访问;
- 2.OpenELB使用Keepalived来维护服务IP地址。Keepalived作为Pod安装在Kubernetes集群的每个节点上,Keepaliveds副本由DaemonSet管理;
- 3.Keepalived副本之间进行协商,并选择一个领导者(本例中为worker 1)来处理服务请求。之后,Keepalived在worker 1的NIC上设置服务IP地址,并将服务IP地址映射到worker 1。专用网络中的所有设备都可以通过ARP协议获得此映射。
- 4.当外部客户端机器尝试访问服务时,路由器根据服务IP地址和worker 1的MAC地址之间的映射将服务流量转发给worker 1。在Service流量到达worker 1后,kube-proxy可以进一步将流量转发到其他节点进行负载平衡(Pod 1和Pod 2都可以通过kube-prroxy到达)。
- 5.如果worker 1失败,剩余的Keepalived副本将重新选择一个leader(例如worker 2)来处理服务请求,服务流量将切换到worker 2。
参考链接:
https://openelb.io/docs/concepts/vip-mode/
5.注意事项
部署Layer2模式需要把K8S集群中的ipvs配置打开strictARP,开启之后K8S集群中的kube-proxy会停止响应kube-ipvs0网卡之外的其他网卡的ARP请求,而有OpenELB接手处理。
strict ARP开启之后相当于把将arp_ignore设置为1并将arp_announce设置为2启用严格的ARP,这个原理和LVS中的DR模式对RS的配置一样。
二.OpenELB部署
1.部署OpenELB
0.卸载metallb组件【如果安装我以前笔部署过metallb的小伙伴可以先卸载,没有安装过的小伙伴直接跳过即可】
[root@master241 ~]# kubectl delete -f metallb-ip-pool.yaml
[root@master241 ~]# kubectl delete -f metallb-native.yaml
1.部署稳定版的OpenELB
[root@master241 ~]# wget https://raw.githubusercontent.com/openelb/openelb/release-0.6/deploy/openelb.yaml
[root@master241 ~]# kubectl apply -f openelb.yaml
2.查看OpenELB的安装情况
[root@master241 ~]# kubectl get po -n openelb-system
NAME READY STATUS RESTARTS AGE
openelb-admission-create-hs562 0/1 Completed 0 18s
openelb-admission-patch-wh8kv 0/1 Completed 0 17s
openelb-controller-5b9669d5cc-zlvkm 1/1 Running 0 18s
openelb-speaker-62wwt 1/1 Running 0 18s
openelb-speaker-kcmbv 1/1 Running 0 18s
openelb-speaker-nm6tt 1/1 Running 0 18s
[root@master241 ~]#
[root@master241 ~]#
参考链接:
https://openelb.io/docs/getting-started/installation/install-openelb-on-kubernetes/
2.修改kube-proxy的configMap
1.修改cm资源的配置
[root@master241 ~]# kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
sed -e 's#mode: ""#mode: "ipvs"#' | \
kubectl apply -f - -n kube-system
2.重启kube-proxy服务使之生效cm配置
[root@master241 ~]# kubectl -n kube-system rollout restart daemonset kube-proxy
daemonset.apps/kube-proxy restarted
[root@master241 ~]#
3.创建Eip地址池
参考链接;
https://openelb.io/docs/getting-started/configuration/configure-ip-address-pools-using-eip/
1.编写资源清单
[root@master241 ~]# cat layer2-eip.yaml
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: layer2-eip
spec:
address: 10.0.0.200-10.0.0.230
interface: eth0
protocol: layer2
[root@master241 ~]#
2.创建资源
[root@master241 ~]# kubectl apply -f layer2-eip.yaml
eip.network.kubesphere.io/layer2-eip created
[root@master241 ~]#
3.查看资源详细信息
[root@master241 ~]# kubectl get eip
NAME CIDR USAGE TOTAL
layer2-eip 10.0.0.200-10.0.0.230 31
[root@master241 ~]#
三.OpenELB基础使用
1.编写资源清单
参考链接:
https://openelb.io/docs/getting-started/usage/use-openelb-in-layer-2-mode/#step-5-create-a-service
[root@master241 OpenELB]# cat 01-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-xiuxian
spec:
replicas: 1
selector:
matchLabels:
apps: web01
template:
metadata:
labels:
apps: web01
auther: yinzhengjie
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
ports:
- containerPort: 80
name: web01
---
apiVersion: v1
kind: Service
metadata:
name: svc-xiuxian
annotations:
# 指定负载均衡器为OpenELB
lb.kubesphere.io/v1alpha1: openelb
# For versions below 0.6.0, you also need to specify the protocol
# protocol.openelb.kubesphere.io/v1alpha1: layer2
eip.openelb.kubesphere.io/v1alpha2: layer2-eip
spec:
ports:
- port: 80
selector:
apps: web01
type: LoadBalancer
# 有效值为: Local和Cluster(默认值)
# Cluster:
# OpenELB从所有Kubernetes集群节点中随机选择一个节点来处理服务请求。其他节点上的Pod也可以通过kube-proxy访问。
# Local:
# OpenELB随机选择Kubernetes集群中包含Pod的节点来处理服务请求。只能访问所选节点上的Pod。
externalTrafficPolicy: Cluster
[root@master241 OpenELB]#
2.创建测试服务
1.创建资源
[root@master241 OpenELB]# kubectl apply -f 01-deploy-svc.yaml
deployment.apps/deploy-xiuxian created
service/svc-xiuxian created
[root@master241 OpenELB]#
[root@master241 OpenELB]# kubectl get svc svc-xiuxian
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-xiuxian LoadBalancer 10.202.187.129 10.0.0.200 80:30746/TCP 4s
[root@master241 OpenELB]#
[root@master241 ~]# kubectl get eip # 不难发现, 目前已经用来一个IP地址,总共有31个IP地址哟~
NAME CIDR USAGE TOTAL
layer2-eip 10.0.0.200-10.0.0.230 1 31
[root@master241 ~]#
2.访问测试
[root@master241 OpenELB]# curl 10.0.0.200
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>yinzhengjie apps v1</title>
<style>
div img {
width: 900px;
height: 600px;
margin: 0;
}
</style>
</head>
<body>
<h1 style="color: green">凡人修仙传 v1 </h1>
<div>
<img src="1.jpg">
<div>
</body>
</html>
[root@master241 OpenELB]#
3.后记
个人对于OpenELB和MetalLB的使用,我还是比较倾向于MetalLB,毕竟我是MetalLB的老用户~
不过OpenELB是后起之秀也要不断关注变化,也是作为MetalLB的可替代方案,提前咱们做的技术调研。
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/18962461,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。

浙公网安备 33010602011771号