概念
kubernetes 本身并没有实现 load balancer。
对于 cloud 用户,可以使用云服务商提供的 provider。
对于 bare metal 的用户来说,可以使用 MetalLB。
MetalLB有两个核心特性:地址分配和对外公告
地址分配:
MetalLB 会为用户的 load balancer 类型 service 分配 IP 地址,该 IP 地址不是凭空产生的,需要用户预先分配。
对外公告:
MetalLB 为服务分配了外部 IP 地址后,需要让集群外的网络知道该 IP 的存在。 MetalLB 使用标准路由协议来实现这一点:ARP、NDP 或 BGP。
Layer 2 模式(ARP/NDP)
Layer 2 模式下,每个 service 会有集群中的一个 node 来负责。当服务客户端发起 ARP/NDP(用于 IPv4 的 ARP,用于 IPv6 的 NDP)解析的时候,对应的 node 会响应该 ARP/NDP 请求,该 service 的流量都会指向该 node,看上去该 node 上有多个地址。
Layer 2 模式并不是真正的负载均衡,因为流量都会先经过一个 node 后,再通过 kube-proxy 转给多个 end points。如果该 node 故障,MetalLB会迁移 IP 到另一个 node,并重新发送 ARP 告知客户端迁移。现代操作系统基本都能正确处理 ARP,因此 failover 不会产生太大问题。
Layer 2 模式更为通用,不需要用户有额外的设备,但由于 Layer 2 模式使用 ARP/NDP,地址池分配需要跟客户端在同一子网,地址分配略为繁琐。
BGP 模式
BGP 模式下,集群中所有 node 都会跟上联路由器建立 BGP 连接,并且会告知路由器应该如何转发 service 的流量。
BGP 模式是真正的 load balancer。
预配置
启用严格的 ARP 模式
如果您在 IPVS 模式下使用 kube-proxy,从 Kubernetes v1.14.2 开始,您必须启用严格的 ARP 模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # 方法1 kubectl edit configmap -n kube-system kube-proxy # # 修改为 true strictARP: true #
# 方法2 # 对比配置差异 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
|
所有节点配置 IP 地址
Layer 2 模式,需要给所有 node 节点配置对应网段的 IP 地址,否则 ARP 无法通信
安装
YAML 安装
1 2 3 4 5 6 7 8
| kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml wget https://raw.githubusercontent.com/metallb/metallb/main/manifests/example-layer2-config.yaml -O metallb-config.yaml vi metallb-config.yaml # - 192.168.1.240/28 # 或者 192.168.1.240-192.168.1.250 # kubectl apply -f metallb-config.yaml
|
HELM 安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| # 配置代理 export {http,https,ftp}_proxy="http://192.168.3.254:1081" # 添加仓库 helm repo add metallb https://metallb.github.io/metallb # 搜索版本 helm search repo metallb # 下载指定版本 helm pull metallb/metallb --version 0.10.2 tar zxvf metallb-0.10.2.tgz cd metallb cp values.yaml values-override.yaml # 修改配置 vi values-override.yaml # configInline: address-pools: - name: default protocol: layer2 addresses: - 192.168.1.240/28 # # 安装部署 helm install --create-namespace --namespace cmp-metallb metallb -f values-override.yaml .
|
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| vi nginx-lb.yaml # apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.20-alpine ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx spec: type: LoadBalancer selector: app: nginx ports: - name: http protocol: TCP port: 80 targetPort: 80 # kubectl apply -f nginx-lb.yaml kubectl get svc
# 测试 curl http://10.0.3.1
|