LoadBalancer
loadbalancer是服务暴露到因特网的标准形式,和nodeport一样我们只需在创建service是指定type为loadbalancer即可,接着Service 的通过status.loadBalancer
字段将需要创建的负载均衡器信息发布供负载均衡服务创建。不过loadbalancer是云服务商”专属“,像腾讯云CLB、阿里云SLB,这样在创建service时会自动帮我们创建一个负载均衡器。
如果要在本地创建一个负载均衡器如何实现呢?
MetalLB,一个CNCF沙箱项目,使用标准路由协议(ARP/BGP),实现裸机K8s集群的负载均衡器。
MetalLB简介
MetalLB 是为裸机Kubernetes集群实现的负载均衡器,使用标准路由协议ARP或BGP。Metallb 支持两种模式:
- Layer2:Layer2模式必须为裸金属服务器或者支持arp广播的网络,由于云的特殊arp机制,云平台无法支持Layer2模式
- BGP:bgp模式和Calico组网方式无法共存,需采用其它组网方式才能使用BGP模式
官方网站:https://metallb.universe.tf
项目地址:https://github.com/metallb/metallb
部署完ingress-nginx后,默认ingress-nginx-controller service类型为LoadBalancer,此时EXTERNAL-IP是pending状态
[root@master01 nginx-ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 172.18.65.6 <pending> 80:32217/TCP,443:30735/TCP 84m
ingress-nginx-controller-admission ClusterIP 172.18.162.225 <none> 443/TCP 84m
部署MetalLB
- 修改kube-proxy
# 修改mode和strictARP值,并校对
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system
# 执行修改操作
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
#查看修改结果
kubectl edit configmap -n kube-system kube-proxy
- 部署
wget https://github.com/metallb/metallb/archive/refs/tags/v0.12.1.tar.gz
tar vzxf v0.12.1.tar.gz
cd metallb-0.12.1/manifests/
kubectl apply -f namespace.yaml
kubectl apply -f metallb.yaml
- 查看状态
[root@cka-1 manifests]# kubectl -n metallb-system get pods
NAME READY STATUS RESTARTS AGE
metallb-system controller-7476b58756-6l779 1/1 Running 0 84m
metallb-system speaker-d67qr 1/1 Running 0 84m
metallb-system speaker-f5x5l 1/1 Running 0 84m
metallb-system/controller
deployment。用于处理IP分配的控制器。
metallb-system/speaker
daemonset。集群中每个节点启动一个协议服务守护进程。
配置Layer2模式
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: my-ip-space
protocol: layer2
addresses:
- 10.20.13.15-10.20.13.20 #与宿主机同一网段
查看ingress-nginx service
[root@cka-1 manifests]# kubectl -n ingress-nginx get svc
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
ingress-nginx ingress-nginx-controller LoadBalancer 10.109.134.0 10.20.13.15 80:30926/TCP,443:30424/TCP 21h
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.98.231.139 <none> 443/TCP
Metallb在Layer2模式下,会从k8s节点中选一个Leader节点,在这个节点上面响应LB地址段的ARP请求,从而使上层路由把发往LB的流量都发到Leader节点。
缺点也很明显,所有对LB的请求都会发往Leader节点。如果当前Service下面的Pod分布在不同节点,那么这个流量还会从Leader发往相应的节点。
部署测试应用
kubectl create deploy echoserver --image=cilium/echoserver --replicas=2
部署service
kubectl expose deployment echoserver --port=80
ingress-nginx策略
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-echoserver-test
spec:
rules:
- host: echoserver.test # 域名
http:
paths:
- path: / # 代理目录
pathType: Prefix #path类型,下面
backend:
service:
name: echoserver # 对应service名称
port:
number: 80 # service 端口
ingressClassName: nginx # 指定选择的 Ingress Controller
kubectl apply -f ingress-echoserver-test.yaml
测试
[root@master01 nginx-ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-echoserver-test nginx echoserver.test 10.20.13.15 80 96m
curl -H "Host: echoserver.test" http://10.20.13.15
Hostname: echoserver-8585bfb456-8brrb