Kubernetes nginx-ingress LoadBalancer模式

Kubernetes / 2023-02-06

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

  1. 修改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
  1. 部署
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
  1. 查看状态
[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