Kubernetes metallb LoadBalancer
一、metallb簡介
基本介紹
MetalLB是使用標(biāo)準(zhǔn)路由協(xié)議的裸機(jī)Kubernetes集群的負(fù)載均衡器實(shí)現(xiàn)。
Kubernetes沒有為裸機(jī)集群提供網(wǎng)絡(luò)負(fù)載平衡器的實(shí)現(xiàn)(服務(wù)類型為LoadBalancer)。Kubernetes附帶的Network LB的實(shí)現(xiàn)都是調(diào)用各種IaaS平臺(tái)(GCP,AWS,Azure等)的粘合代碼。如果您不在支持的IaaS平臺(tái)(GCP,AWS,Azure等)上運(yùn)行,則LoadBalancers在創(chuàng)建時(shí)將無限期保持“待處理”狀態(tài)。
裸機(jī)集群運(yùn)營商只剩下兩個(gè)較小的工具,即“ NodePort”和“ externalIPs”服務(wù),可將用戶流量引入其集群。這兩個(gè)選項(xiàng)在生產(chǎn)用途上都有很大的缺點(diǎn),這使裸金屬集群成為Kubernetes生態(tài)系統(tǒng)中的二等公民。
MetalLB旨在通過提供與標(biāo)準(zhǔn)網(wǎng)絡(luò)設(shè)備集成的Network LB實(shí)現(xiàn)來解決這種不平衡問題,從而使裸機(jī)群集上的外部服務(wù)也盡可能“正常運(yùn)行”。
條件
MetalLB需要以下功能才能運(yùn)行:
1、一個(gè)Kubernetes集群,運(yùn)行Kubernetes 1.13.0或更高版本,還沒有網(wǎng)絡(luò)負(fù)載平衡功能。
2、 群集的網(wǎng)絡(luò)配置可以與MetalLB共存。
3、MetalLB目前只支持IPv4地址。
根據(jù)操作模式,您可能需要一個(gè)或多個(gè)能夠說BGP的路由器 。
Metallb基本原理
Metallb 會(huì)在 Kubernetes 內(nèi)運(yùn)行,監(jiān)控服務(wù)對(duì)象的變化,一旦察覺有新的LoadBalancer 服務(wù)運(yùn)行,并且沒有可申請的負(fù)載均衡器之后,
就會(huì)完成兩部分的工作:
1.地址分配
用戶需要在配置中提供一個(gè)地址池,Metallb 將會(huì)在其中選取地址分配給服務(wù)。
2.地址廣播
根據(jù)不同配置,Metallb 會(huì)以二層(ARP/NDP)或者 BGP 的方式進(jìn)行地址的廣播。
基本原理圖

二、metallb安裝
項(xiàng)目文檔、源代碼地址
官方部署metallb文檔:
https://metallb.universe.tf/installation/
官方項(xiàng)目開源地址:
https://github.com/google/metallb
本人項(xiàng)目:
https://gitee.com/sunney/kubernetes/tree/master/metallb
安裝
Metallb 支持 Helm 和 YAML 兩種安裝方法,這里我們使用YAML更簡單:
wget https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml
kubectl apply -f metallb.yaml
如果githubusercontent下載不了,直接到https://github.com/google/metallb找到對(duì)應(yīng)的文件。
查看運(yùn)行的pod
kubectl get pod -n metallb-system -o wide
metalLB包含兩個(gè)部分: a cluster-wide controller, and a per-machine protocol speaker.
[centos@k8s-master ~]$ kubectl get pod -n metallb-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
controller-7cc9c87cfb-n25kc 1/1 Running 1 166m 10.244.1.39 k8s-node1 <none> <none>
speaker-cbhcg 1/1 Running 1 166m 192.168.92.56 k8s-master <none> <none>
speaker-l6vv2 1/1 Running 1 166m 192.168.92.58 k8s-node2 <none> <none>
speaker-pxscm 1/1 Running 1 166m 192.168.92.57 k8s-node1 <none> <none>
[centos@k8s-master ~]$
查看其它信息
包含了 “controller” deployment,和 the “speaker” DaemonSet.
[centos@k8s-master ~]$ kubectl get daemonset -n metallb-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
speaker 3 3 3 3 3 <none> 13h
[centos@k8s-master ~]$ kubectl get deployment -n metallb-system
NAME READY UP-TO-DATE AVAILABLE AGE
controller 1/1 1 1 13h
[centos@k8s-master ~]$
目前還沒有宣布任何內(nèi)容,因?yàn)槲覀儧]有提供ConfigMap,也沒有提供負(fù)載均衡地址的服務(wù)。
接下來我們要生成一個(gè) Configmap 文件,為 Metallb 設(shè)置網(wǎng)址范圍以及協(xié)議相關(guān)的選擇和配置,這里以一個(gè)簡單的二層配置為例。
創(chuàng)建config.yaml提供IP池
wget https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/example-layer2-config.yaml
修改ip地址池和集群節(jié)點(diǎn)網(wǎng)段相同
[centos@k8s-master ~]$ vim example-layer2-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.92.200-192.168.92.210
注意:這里的 IP 地址范圍需要跟集群實(shí)際情況相對(duì)應(yīng)。
執(zhí)行yaml文件
kubectl apply -f example-layer2-config.yaml
創(chuàng)建后端應(yīng)用和服務(wù)測
$ wget https://raw.githubusercontent.com/google/metallb/master/manifests/tutorial-2.yaml
$ kubectl apply -f tutorial-2.yaml
查看yaml文件配置,包含了一個(gè)deployment和一個(gè)LoadBalancer類型的service,默認(rèn)即可。
[centos@k8s-master ~]$ vim tutorial-2.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
查看service分配的EXTERNAL-IP
[centos@k8s-master ~]$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d15h
nginx LoadBalancer 10.101.112.1 192.168.92.201 80:31274/TCP 123m
[centos@k8s-master ~]$
集群內(nèi)訪問該IP地址
[centos@k8s-master ~]$ curl 192.168.92.201
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
......
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[centos@k8s-master ~]$
ping該ip地址,發(fā)現(xiàn)從pod所在節(jié)點(diǎn)192.168.92.57發(fā)起的請求:
[centos@k8s-master ~]$ ping 192.168.92.201
PING 192.168.92.201 (192.168.92.201) 56(84) bytes of data.
From 192.168.92.57: icmp_seq=2 Redirect Host(New nexthop: 192.168.92.201)
From 192.168.92.57: icmp_seq=3 Redirect Host(New nexthop: 192.168.92.201)
From 192.168.92.57: icmp_seq=4 Redirect Host(New nexthop: 192.168.92.201)
從集群外訪問該IP地址:

此IP地址在集群外無法ping通,但可以訪問80端口:
命令行終端執(zhí)行telnet 192.168.92.201 80測試成功。
到這里metallb loadbalancer部署完成,你可以定義kubernetes dashboard,granafa dashboard等各種應(yīng)用服務(wù),以loadbalancer的方式直接訪問,不是一般的方便。