OpenELB
OpenELB是一个开源的负载均衡器,功能和metalLB类似
OpenELB主要两种工作模式: Layer2和BGP模式.目前OpenELB的BGP不支持ipv6
OpenELB核心思想就是通过某种方式将特定的VIP的流量引导k8s集群中,然后通过Kube-proxy将流量转发到后面的特定服务.
1. OpenELB介绍
1.1 Layer2 模式
整个访问过程需要k8s集群基础环境支持发送anonymous ARP/NDP packets.OpenELB是针对裸金属设计的,因此云环境下需要注意是否能够满足条件.
- 图中有一个类型为 LoadBalancer 的 Service,其 VIP 为 192.168.31.210(和 k8s 的节点相同网段),后端有两个 pod(分别为 pod1 和 pod2)
- 安装在 Kubernetes 集群中的 OpenELB 随机选择一个节点(图中为 worker 1)来处理 Service 请求。当局域网中出现 arp request 数据包来查询 192.168.0.91 的 mac 地址的时候,OpenELB 会进行回应(使用 worker 1 的 MAC 地址),此时路由器(也可能是交换机)将 Service 的 VIP 192.168.31.210 和 worker 1 的 MAC 地址绑定,之后所有请求到 192.168.31.210 的数据包都会被转发到 worker1 上
- Service 流量到达 worker 1 后, worker 1 上的 kube-proxy 将流量转发到后端的两个 pod 进行负载均衡,这些 pod 不一定在 work1 上
- 如果worker1出现故障,那么就会把Service IP映射到worker 2上去.由于主备切换不是瞬间完成的,具体切换时间不明.
1.2 BGP模式
OpenELB 的 BGP 模式使用的是gobgp实现的 BGP 协议,通过使用 BGP 协议和路由器建立 BGP 连接并实现 ECMP 负载均衡,从而实现高可用的 LoadBalancer。
- 图中有一个类型为 LoadBalancer 的 Service,其 VIP 为 172.22.0.2(和 k8s 的节点不同网段),后端有两个 pod(分别为 pod1 和 pod2)
- 安装在 Kubernetes 集群中的 OpenELB 与 BGP 路由器建立 BGP 连接,并将去往 172.22.0.2 的路由发布到 BGP 路由器,在配置得当的情况下,路由器上面的路由表可以看到 172.22.0.2 这个 VIP 的下一条有多个节点(均为 k8s 的宿主机节点)
- 当外部客户端机器尝试访问 Service 时,BGP 路由器根据从 OpenELB 获取的路由,在 master、worker 1 和 worker 2 节点之间进行流量负载均衡。Service 流量到达一个节点后,该节点上的 kube-proxy 将流量转发到后端的两个 pod 进行负载均衡,这些 pod 不一定在该节点上
1.3 注意事项
配置 ARP 参数
部署 Layer2 模式需要把 k8s 集群中的 ipvs 配置打开strictARP,开启之后 k8s 集群中的 kube-proxy
会停止响应 kube-ipvs0
网卡之外的其他网卡的 arp 请求,而由 MetalLB 接手处理。
strict ARP
开启之后相当于把 将 arp_ignore
设置为 1 并将 arp_announce
设置为 2 启用严格的 ARP,这个原理和 LVS 中的 DR 模式对 RS 的配置一样。
2. OpenELB安装
2.1 安装OpenELB必备条件
- 必须使用k8s集群
- k8s 版本必须高于1.15
- 如果没有k8s集群可以使用kubekey部署.
2.2 安装OpenELB
官网
https://openelb.io/
安装OpenELB
kubectl apply -f https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml
相关资源被创建到openelb-system命名空间下
namespace/openelb-system created
customresourcedefinition.apiextensions.k8s.io/bgpconfs.network.kubesphere.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.network.kubesphere.io created
customresourcedefinition.apiextensions.k8s.io/eips.network.kubesphere.io created
serviceaccount/kube-keepalived-vip created
serviceaccount/openelb-admission created
role.rbac.authorization.k8s.io/leader-election-role created
role.rbac.authorization.k8s.io/openelb-admission created
clusterrole.rbac.authorization.k8s.io/kube-keepalived-vip created
clusterrole.rbac.authorization.k8s.io/openelb-admission created
clusterrole.rbac.authorization.k8s.io/openelb-manager-role created
rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
rolebinding.rbac.authorization.k8s.io/openelb-admission created
clusterrolebinding.rbac.authorization.k8s.io/kube-keepalived-vip created
clusterrolebinding.rbac.authorization.k8s.io/openelb-admission created
clusterrolebinding.rbac.authorization.k8s.io/openelb-manager-rolebinding created
service/openelb-admission created
deployment.apps/openelb-manager created
job.batch/openelb-admission-create created
job.batch/openelb-admission-patch created
mutatingwebhookconfiguration.admissionregistration.k8s.io/openelb-admission created
validatingwebhookconfiguration.admissionregistration.k8s.io/openelb-admission created
查看资源是否被正常创建
root@master-01:/opt/openelb# kubectl get pods -n openelb-system
NAME READY STATUS RESTARTS AGE
openelb-admission-create-sxz6x 0/1 Completed 0 55m
openelb-admission-patch-4z2vh 0/1 Completed 2 55m
openelb-keepalive-vip-8b8bg 1/1 Running 0 52m
openelb-keepalive-vip-8k7rb 1/1 Running 0 52m
openelb-manager-688566cb5d-bgkrl 1/1 Running 0 53m
3 OpenELB配置
3.1 修改kube-proxy模式
运行以下命令,对kube-proxy模式进行修改.默认是iptables
kubectl edit cm -n kube-system kube-proxy
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: true # 默认是false,改为true
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: "ipvs" #默认是空,改为ipvs
保存退出后重启kube-proxy
kubectl rollout restart daemonset -n kube-system kube-proxy
3.2 创建地址池
layer2-eip.yaml
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: layer2-eip
spec:
address: 192.168.31.170-192.168.31.190
interface: eth0
protocol: layer2
创建eip资源
kubectl apply -f layer2-eip.yaml
查看eip资源状态
kubectl get eips.network.kubesphere.io
NAME CIDR USAGE TOTAL
layer2-eip 192.168.31.170-192.168.31.190 21
4. k8s中使用OpenELB
4.1 Deployment
layer-nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: layer-nginx
labels:
app: layer-nginx
spec:
replicas: 3
selector:
matchLabels:
app: layer-nginx
template:
metadata:
labels:
app: layer-nginx
spec:
containers:
- name: layer-nginx
image: nginx:1.14.2
ports:
- containerPort: 80
4.2 Service
layer-nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: layer-nginx-service
annotations:
lb.kubesphere.io/v1alpha1: openelb
protocol.openelb.kubesphere.io/v1alpha1: layer2
eip.openelb.kubesphere.io/v1alpha2: layer2-eip
spec:
selector:
app: layer-nginx
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalTrafficPolicy: Cluster
4.3 访问测试
修改3个容器的index.html
# kubectl exec -it layer-nginx-7d89bf4665-cjffd bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@layer-nginx-7d89bf4665-cjffd:/# echo 1 > /usr/share/nginx/html/index.html
root@layer-nginx-7d89bf4665-cjffd:/# exit
exit
# kubectl exec -it layer-nginx-7d89bf4665-rfk26 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@layer-nginx-7d89bf4665-rfk26:/# echo 2 > /usr/share/nginx/html/index.html
root@layer-nginx-7d89bf4665-rfk26:/# exit
exit
# kubectl exec -it layer-nginx-7d89bf4665-vz82h bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@layer-nginx-7d89bf4665-vz82h:/# echo 3 > /usr/share/nginx/html/index.html
root@layer-nginx-7d89bf4665-vz82h:/# exit
exit
可以看到这里分配了192.168.31.170的external-ip
# kubectl get svc layer-nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
layer-nginx-service LoadBalancer 10.200.127.157 192.168.31.170 80:30972/TCP 79s
# kubectl get eip
NAME CIDR USAGE TOTAL
layer2-eip 192.168.31.170-192.168.31.190 1 21
## 集群内访问测试
# for i in {1..6};do curl 192.168.31.170;done
2
1
3
2
1
3
5. Kubesphere中使用OpenELB
5.1 创建项目
创建工作负载
没有就不挂载
如果没有就直接创建
deployment被创建完成
修改下index.html
5.2 创建Service
lb.kubesphere.io/v1alpha1: openelb
protocol.openelb.kubesphere.io/v1alpha1: layer2
eip.openelb.kubesphere.io/v1alpha2: layer2-eip
访问测试
5.3 应用路由(ingress)
设置路由规则
修改hosts或dns后可以使用域名实现服务访问
192.168.31.210 openelb.intra.com