Kubernetes(简称K8s)中部署openELB的原因主要有以下几点:
1. 提供高性能和高可用性的负载均衡服务
- 高性能:openELB支持大规模并发请求,能够处理高流量负载,确保应用程序在高负载下仍能稳定运行。
- 高可用性:通过多副本部署,openELB能够提供高可用性的负载均衡服务,减少单点故障的风险。
2. 适配多种环境
- 裸金属服务器:在裸机Kubernetes集群中,云服务提供商提供的负载均衡服务通常不可用。openELB允许用户在裸金属服务器、边缘以及虚拟化环境中创建LoadBalancer类型的Service,从而暴露服务并提供与云上负载均衡器相同的用户体验。
- 灵活性:openELB支持多种后端类型(如NodePort、ClusterIP、ExternalName)和多种负载均衡算法(如轮询、最少连接、随机等),满足不同应用的需求。
3. 易于集成和扩展
- 与Kubernetes集成:openELB易于与Kubernetes集群集成,通过简单的配置即可实现负载均衡功能。
- 自动扩展:openELB支持自动扩展,能够根据流量变化动态调整负载均衡器的配置,确保系统性能。
4. 丰富的功能和模式
- BGP模式:建议使用BGP模式,因为它允许创建一个没有故障转移中断和带宽瓶颈的高可用性系统。但需要注意的是,BGP模式要求路由器支持BGP和等价多路径(ECMP)路由。
- 二层网络模式:在路由器不支持BGP或ECMP的情况下,可以使用二层网络模式来实现类似的功能。但需要注意,二层模式需要基础环境允许匿名ARP/NDP数据包。
5. 社区支持和文档完善
- 开源社区:openELB是一个开源项目,拥有活跃的社区支持,用户可以通过社区获取帮助、分享经验并参与项目的发展。
- 详细文档:openELB提供了详细的文档和指南,帮助用户了解如何安装、配置和使用openELB,降低使用门槛。
综上所述,在K8s中部署openELB可以为用户提供高性能、高可用性的负载均衡服务,同时适配多种环境、易于集成和扩展,并具有丰富的功能和模式可供选择。这些优势使得openELB成为K8s集群中负载均衡解决方案的优选之一。
部署OpenELB
使用helm部署OpenELB
- 通过SSH登录Kubernetes集群,执行以下命令:
helm repo add openelb https://openelb.github.io/openelb
helm repo update
helm install openelb openelb/openelb -n openelb-system --create-namespace
- 执行以下命令查看openelb-controller和openelb-speaker的状态是否为READY : 1/1和STATUS : Running 。如果是,说明OpenELB安装成功。
[root@xm-nano-k8s-master-113-103 ~]# kubectl get po -n openelb-system
NAME READY STATUS RESTARTS AGE
openelb-admission-create-fv8jb 0/1 Completed 0 41s
openelb-admission-patch-887qh 0/1 Completed 0 41s
openelb-0-1723017022-controller-557dbc85b9-6xpch 1/1 Running 0 15m
openelb-0-1723017022-speaker-9qwkm 1/1 Running 0 14m
openelb-0-1723017022-speaker-tr2nm 1/1 Running 0 15m
VIP 模式下使用 OpenELB
前提条件
- 准备一个已安装OpenELB的Kubernetes集群。所有 Kubernetes 集群节点必须位于同一二层网络(同一路由器下)。
- 所有Kubernetes 集群节点必须只有一张网卡。 VIP模式目前不支持多网卡的Kubernetes集群节点。
- 需要准备一台客户端机器,用于验证OpenELB在二层模式下是否正常工作。客户端计算机需要与 Kubernetes 集群节点位于同一网络上。
- kube-proxy配置strictARP=true
kube-proxy配置strictARP=true
1、非RKE部署的K8s集群:配置首先,需要为kube-proxy启动strictARP,以便Kubernetes集群中的所有网卡停止响应其他网卡的ARP请求,而由OpenELB来处理ARP请求。
kubectl edit configmap kube-proxy -n kube-system
......
ipvs:
strictARP: true
......
然后重启kube-proxy组件,命令如下:
kubectl rollout restart daemonset kube-proxy -n kube-system
2、RKE部署的K8s集群。kube-proxy是使用容器启动,没有kube-proxy的configmap文件,只能通过rancher的RKE模板进行修改,追加对应的参数。并将模板应用在已创建的集群中
kubeproxy:
extra_args:
ipvs-strict-arp: 'true'
proxy-mode: ipvs
通过docker logs kube-proxy-container_id 查看配置生效 --proxy-mode="ipvs" 和--ipvs-strict-arp="true"
本文档以以下设备为例:
Device Name | IP Address | MAC Address | Description |
xm-nano-k8s-master-113-103 | 192.168.113.103 | 00:16:3e:54:07:e2 | Kubernetes cluster master |
xm-phy-kvm-113-3 | 192.168.113.3 | 14:18:77:49:9c:39 | Kubernetes cluster worker 1 |
xm-phy-kvm-113-5 | 192.168.113.5 | 14:18:77:40:a8:bf | Kubernetes cluster worker 2 |
windows | 192.168.117.33 | Windows 机器 |
第 1 步:确保 VIP 模式已启用
VIP 模式可以通过命令行参数启用或禁用。使用 VIP 模式时,请确保 VIP 扬声器已正确启用。
运行以下命令编辑 openelb-speaker DaemonSet:
kubectl edit ds -n openelb-system openelb-speaker
将enable-keepalived-vip设置为true和enable-layer2=true保存更改。
openelb-speaker 将自动重启。
containers:
- command:
- openelb-speaker
args:
- --api-hosts=:50051
- --enable-keepalived-vip=true
- --enable-layer2=true #测试在RKE环境中也需要配置该参数
... ...
第2步:创建Eip对象
Eip对象作为OpenELB的IP地址池。
- 运行以下命令为 Eip 对象创建 YAML 文件:
vi vip-eip.yaml
- 将以下信息添加到 YAML 文件中:
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: vip-eip #这里是service中注释value
spec:
address: 192.168.113.151-192.168.113.160
interface: em1 #服务网卡名字,dell物理机em1,虚机eth0注意区分
protocol: vip
spec:address中指定的IP地址必须与Kubernetes集群节点在同一网段。
- Eip YAML配置中的字段详细信息,请参见使用Eip配置IP地址池。
- 运行以下命令创建 Eip 对象:
kubectl apply -f vip-eip.yaml
第 3 步:创建部署
以下使用 luksa/kubia 映像创建两个 Pod 的 Deployment。每个 Pod 向外部请求返回自己的 Pod 名称。
- 运行以下命令为部署创建 YAML 文件:
vi vip-openelb.yaml
- 将以下信息添加到 YAML 文件中:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vip-openelb
spec:
replicas: 2
selector:
matchLabels:
app: vip-openelb
template:
metadata:
labels:
app: vip-openelb
spec:
containers:
- image: luksa/kubia
name: kubia
ports:
- containerPort: 8080
- 运行以下命令来创建部署:
kubectl apply -f vip-openelb.yaml
第 4 步:创建服务
- 运行以下命令为服务创建 YAML 文件:
vi vip-svc.yaml
- 将以下信息添加到 YAML 文件中:
kind: Service
apiVersion: v1
metadata:
name: vip-svc
annotations:
lb.kubesphere.io/v1alpha1: openelb
# For versions below 0.6.0, you also need to specify the protocol
# protocol.openelb.kubesphere.io/v1alpha1: vip
eip.openelb.kubesphere.io/v1alpha2: vip-eip
spec:
selector:
app: vip-openelb
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 8080
externalTrafficPolicy: Cluster
注意事项:
配置 spec:type=LoadBalancer.
The lb.kubesphere.io/v1alpha1: openelb annotation specifies that the Service uses OpenELB.
The protocol.openelb.kubesphere.io/v1alpha1: vip annotation specifies that OpenELB is used in VIP mode. Deprecated after 0.6.0.
The eip.openelb.kubesphere.io/v1alpha2: bgp-eip annotation specifies the Eip object used by OpenELB. If this annotation is not configured, OpenELB automatically selects an available Eip object. Alternatively, you can remove this annotation and use the spec:loadBalancerIP field (e.g., spec:loadBalancerIP: 192.168.0.91) or add the annotation eip.openelb.kubesphere.io/v1alpha1: 192.168.0.91 to assign a specific IP address to the Service. When you set spec:loadBalancerIP of multiple Services to the same value for IP address sharing (the Services are distinguished by different Service ports). In this case, you must set spec:ports:port to different values and spec:externalTrafficPolicy to Cluster for the Services. For more details about IPAM, see openelb ip address assignment
If spec:externalTrafficPolicy is set to Cluster (default value), OpenELB randomly selects a node from all Kubernetes cluster nodes to handle Service requests. Pods on other nodes can also be reached over kube-proxy.
If spec:externalTrafficPolicy is set to Local, OpenELB randomly selects a node that contains a Pod in the Kubernetes cluster to handle Service requests. Only Pods on the selected node can be reached.
sercvice需要添加如下注释:
eip-vip需要根据实际命名规则配置
- 运行以下命令来创建服务:
kubectl apply -f vip-svc.yaml
第5步:在VIP模式下验证OpenELB
下面验证OpenELB是否正常运行。
- 在Kubernetes集群中,执行以下命令获取Service的外部IP地址:
[root@xm-nano-k8s-master-113-103 ~]# kubectl get svc -n saas-yanfa
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-tmp ClusterIP 10.43.122.145 <none> 80/TCP 14h
nginx-tmp-nodeport NodePort 10.43.212.46 <none> 80:30176/TCP 14h
saas-admin ClusterIP 10.43.141.185 <none> 8080/TCP 17h
saas-admin-loadbalancer LoadBalancer 10.43.209.221 192.168.113.151 8081:31716/TCP 17h
vip-svc LoadBalancer 10.43.195.207 192.168.113.152 80:32054/TCP 20h
- 在Kubernetes集群中,执行以下命令获取集群节点的IP地址:
[root@xm-nano-k8s-master-113-103 ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
xm-nano-k8s-master-113-103 Ready controlplane,etcd 5d16h v1.28.11 192.168.113.103 <none> CentOS Linux 7 (Core) 3.10.0-1160.59.1.el7.x86_64 docker://26.1.4
xm-nano-k8s-master-113-104 Ready controlplane,etcd 5d16h v1.28.11 192.168.113.104 <none> CentOS Linux 7 (Core) 3.10.0-1160.119.1.el7.x86_64 docker://26.1.4
xm-nano-k8s-master-113-150 Ready controlplane,etcd 5d16h v1.28.11 192.168.113.150 <none> CentOS Linux 7 (Core) 3.10.0-1160.119.1.el7.x86_64 docker://26.1.4
xm-phy-kvm-113-3 Ready worker 15h v1.28.11 192.168.113.3 <none> CentOS Linux 7 (Core) 3.10.0-1160.71.1.el7.x86_64 docker://26.1.4
xm-phy-kvm-113-5 Ready worker 15h v1.28.11 192.168.113.5 <none> CentOS Linux 7 (Core) 3.10.0-1160.119.1.el7.x86_64 docker://26.1.4
- 在Kubernetes集群中,执行以下命令查看Pod的节点情况:
[root@xm-nano-k8s-master-113-103 ~]# kubectl get pod -o wide -n saas-yanfa
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-tmp-5855b6fd87-2vql4 1/1 Running 0 14h 10.42.10.9 xm-phy-kvm-113-3 <none> <none>
saas-admin-694cc56467-dzp5l 1/1 Running 0 15h 10.42.10.4 xm-phy-kvm-113-3 <none> <none>
vip-openelb-94bf45f87-pb47h 1/1 Running 0 52m 10.42.10.10 xm-phy-kvm-113-3 <none> <none>
在此示例中,Pod 会自动分配到不同的节点。您可以手动将 Pod 分配到不同的节点。
- 在客户端计算机上,运行以下命令来 ping 服务 IP 地址并检查 IP 邻居:
[root@xm-nano-k8s-master-113-103 ~]# ping 192.168.113.152
PING 192.168.113.152 (192.168.113.152) 56(84) bytes of data.
From 192.168.113.152 icmp_seq=1 Destination Port Unreachable
From 192.168.113.152 icmp_seq=2 Destination Port Unreachable
官方文档中可以ping通对应的vip,但实际验证无法ping通,暂时未找到原因。后续继续从网络上的配置入手
[root@xm-nano-k8s-master-113-103 ~]# ping 192.168.113.152
PING 192.168.113.152 (192.168.113.152) 56(84) bytes of data.
From 192.168.113.152 icmp_seq=1 Destination Port Unreachable
From 192.168.113.152 icmp_seq=2 Destination Port Unreachable
在ip neigh命令的输出中,Service IP地址192.168.113.152的MAC地址与worker-p001 192.168.113.3的MAC地址相同。因此,OpenELB已将Service IP地址映射到worker-p001的MAC地址。
- 在客户端计算机上,访问服务:
- 如果服务 YAML 配置中的spec:externalTrafficPolicy设置为Cluster ,则两个 Pod 都可以访问。
[root@xm-nano-k8s-master-113-103 ~]# curl 192.168.113.152
You've hit vip-openelb-94bf45f87-b6wwp
[root@xm-nano-k8s-master-113-103 ~]# curl 192.168.113.152
You've hit vip-openelb-94bf45f87-pb47h
[root@xm-nano-k8s-master-113-103 ~]# curl 192.168.113.152
You've hit vip-openelb-94bf45f87-b6wwp
[root@xm-nano-k8s-master-113-103 ~]# curl 192.168.113.152
You've hit vip-openelb-94bf45f87-pb47h
如果Service YAML 配置中的spec:externalTrafficPolicy设置为Local ,则只能到达 OpenELB 选择的节点上的 Pod。
[root@xm-nano-k8s-master-113-103 ~]# curl 192.168.113.152
You've hit vip-openelb-94bf45f87-pb47h
[root@xm-nano-k8s-master-113-103 ~]# curl 192.168.113.152
You've hit vip-openelb-94bf45f87-pb47h