1、简介
PureLB LoadBalancer 控制器由两个与 k8s API 服务器交互的组件组成。这两个组件是:
-
分配器。 分配器监视服务 API 的 LoadBalancer 服务事件并分配 IP 地址
-
LB节点代理。 lbnodeagent 在公开服务的数据包可以传输的所有节点上运行,它监视服务更改并配置网络行为
-
Kube代理。KubeProxy 很重要,但不是 PureLB 的一部分。KubeProxy 监视服务更改并添加 lbnodeagent 使用的相同地址来配置集群内的通信
-
PureLB有Layer2模式和ECMP模式两种部署方案
2、架构图
- Allocator:用来监听API中的LoadBalancer类型服务,并且负责分配IP。
- LBnodeagent: 作为daemonset部署到每个可以暴露请求并吸引流量的节点上,并且负责监听服务的状态变化同时负责把VIP添加到本地网卡或者是虚拟网卡
- KubeProxy:k8s的内置组件,并非是PureLB的一部分,但是PureLB依赖其进行正常工作,当对VIP的请求达到某个具体的节点之后,需要由kube-proxy来负责将其转发到对应的pod
3、准备工作
- PureLB 使用 Memberlist 的库来提供比标准 k8s 超时所需的更快的本地网络地址故障转移,因此需要放行的端口 7934 UDP/TCP,否则会出现脑裂
- 将kubeproxy的转发模式设置为ipvs模式,同时将arp模式设置为严格模式
kubeproxy配置:
--proxy-mode IPVS
--ipvs-strict-arp
- 系统配置
cat <<EOF | sudo tee /etc/sysctl.d/k8s_arp.conf
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
EOF
sudo sysctl --system
4、部署Layer2模式
helm repo add purelb https://gitlab.com/api/v4/projects/20400619/packages/helm/stable
helm install --create-namespace -n purelb purelb purelb/purelb
验证安装:
kubectl get pod -n purelb
NAME READY STATUS RESTARTS AGE
allocator-658dbff56f-579df 1/1 Running 0 21h
lbnodeagent-xdljm 1/1 Running 0 21h
lbnodeagent-xwjfx 1/1 Running 0 21h
5、初始化配置
PureLB 配置简单,使用自定义资源。单个 LBNodeAgent CR 启用默认覆盖,并根据需要配置尽可能多的 ServiceGroup CR 配置外部 IP 地址范围。
kubectl api-resources --api-group=purelb.io
NAME SHORTNAMES APIVERSION NAMESPACED KIND
lbnodeagents lbna,lbnas purelb.io/v1 true LBNodeAgent
servicegroups sg,sgs purelb.io/v1 true ServiceGroup
LBNodeAgent
安装过程将创建 lbnodeagent.purelb.io/default。在大多数情况下,这些默认值是合适的。
kubectl describe -n purelb lbnodeagent.purelb.io/default
Name: default
Namespace: purelb
Kind: LBNodeAgent
Spec:
Local:
extlbint: kube-lb0
localint: default
注意上面的Spec:Local:字段中的Extlbint和Localint
- Extlbint字段指定的是PureLB使用的虚拟网卡名称,默认为kube-lb0,如果修改为自定义名称,记得同时修改bird中的配置
- Localint字段指定的是用来实际通信的物理网卡,默认情况下会使用正则表达式来匹配,当然也可以自定义,如果集群节点是单网卡机器基本无需修改
创建服务组:
servicegroups默认情况下并没有创建,需要我们进行手动配置,注意purellb是支持ipv6的,配置方式和ipv4一致,只是这里没有需求就没有单独配置v6pool。
apiVersion: purelb.io/v1
kind: ServiceGroup
metadata:
name: default
namespace: purelb
spec:
local:
v4pool:
aggregation: /32
pool: 192.168.96.193-192.168.96.206
subnet: 192.168.96.193/28
说明:
- 聚合的主要目的是改变路由分配地址的方式。更改聚合器会影响前缀添加到路由表的时间。
更改服务组:
更改服务组不会影响已创建的服务。修改后的服务组只会影响随后创建的服务。这是有意的:服务地址更改应该在每个服务的基础上启动,而不是通过服务组中的地址范围更改来更改所有关联服务的外部地址。要迁移服务地址,请添加一个额外的服务,该服务将从更改的池中分配一个地址,一旦流量耗尽,请删除释放地址的原始服务。
6、部署测试
kubectl create svc loadbalancer nginx --tcp=80
kubectl get svc | grep nginx
nginx LoadBalancer 10.96.0.25 192.168.96.193 80:32235/TCP 3d5h
测试结果:
curl -I 192.168.96.193
HTTP/1.1 200 OK
Server: nginx/1.23.1
Date: Sat, 06 Aug 2022 14:23:18 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 19 Jul 2022 15:23:19 GMT
Connection: keep-alive
ETag: "62d6cc67-267"
Accept-Ranges: bytes
需要改进的地方:
上面获取nginx的LB地址的时候,默认也生成了nodeport的端口,这个目前对我们来说是没有使用到的,所以可以去掉,具体操作如下:
PureLB支持allocateLoadBalancerNodePorts特性,可以通过设置allocateLoadBalancerNodePorts: false来关闭自动为LoadBalancer服务分配nodeport这个功能。
修改nginx的svc
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
allocateLoadBalancerNodePorts: false
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
测试结果:
kubectl get svc | grep nginx
nginx LoadBalancer 10.96.0.25 192.168.96.193 80/TCP 3d5h
自定义loadBalancerIP:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
allocateLoadBalancerNodePorts: false
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerIP: 192.168.96.206
测试结果:
kubectl get svc | grep nginx
nginx LoadBalancer 10.96.0.25 192.168.96.206 80/TCP 3d5h
评论区