MetalLB
MetalLB , 通过K8S原生的方式提供LB类型的Service支持,开箱即用。

MetalLB在Kubernetes内运行,监控服务对象的变化,一旦察觉有新的LoadBalancer服务运行,并且没有可申请的负载均衡器之后,就会完成两部分的工作:

  • 地址分配

用户需要在配置中提供一个地址池,MetalLB将会在其中选取地址分配给该服务。

  • 地址广播

根据不同配置,MetalLB会以二层(ARP/NDP)或者BGP的方式进行地址的广播。

  • 支持范围
Calico: 部分支持Canel: 支持Flannel: 支持Kube-router: 部分支持Romana: 支持Weave Net: 部分支持

工作模式
Layer2模式
MetalLB在这种模式下,只需要一段跟K8S管理网相同网段的地址即可。

MetalLB会从K8S节点中选一个Leader节点,在这个节点上面响应LB地址段的ARP请求,从而使上层路由把发往LB的流量都发到Leader节点。

缺点也很明显,所有对LB的请求都会发往Leader节点。如果当前Service下面的Pod分布在不同节点,那么这个流量还会从Leader发往相应的节点。

不过用在实验环境里这个模式不需要路由器支持BGP。

图片来源:https://zhuanlan.zhihu.com/p/103717169

BGP模式
跟L2模式的区别就是能够通过BGP协议正确分布流量了,不再需要一个Leader节点。

这种模式需要路由器支持接收MetalLB的BGP广播,从而把请求分布到正确的节点上。

缺点就是需要上层路由器支持BGP。而且因为BGP单Session的限制,如果Calico也是使用的BGP模式,就会有冲突从而导致MetalLB无法正常工作。

图片来源:https://zhuanlan.zhihu.com/p/103717169

部署MetalLB
如果kube-proxy启用了IPVS,需要设置strictARP: true。

[root@K8S-PROD-M1 ~]# kubectl edit configmap -n kube-system kube-proxy...    ipvs:      excludeCIDRs: null      minSyncPeriod: 5s      scheduler: wrr      strictARP: true  #将false设置成true      syncPeriod: 5s      tcpFinTimeout: 0s      tcpTimeout: 0s      udpTimeout: 0s    kind: KubeProxyConfiguration    metricsBindAddress: ""    mode: ipvs...

或者使用下面的方法:

# see what changes would be made, returns nonzero returncode if differentkubectl get configmap kube-proxy -n kube-system -o yaml | \sed -e "s/strictARP: false/strictARP: true/" | \kubectl diff -f - -n kube-system# actually apply the changes, returns nonzero returncode on errors onlykubectl get configmap kube-proxy -n kube-system -o yaml | \sed -e "s/strictARP: false/strictARP: true/" | \kubectl apply -f - -n kube-system

部署MetalLB

  • 获取镜像

[root@K8S-PROD-M1 ~]# docker pull metallb/controller:v0.9.3
[root@K8S-PROD-M1 ~]# docker tag metallb/controller:v0.9.3 harbor.cluster.local/library/metallb/controller:v0.9.3
[root@K8S-PROD-M1 ~]# docker push harbor.cluster.local/library/metallb/controller:v0.9.3

* 获取部署文件

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml

然后修改metal.yaml中Deployment的镜像地址为私有镜像地址。* 执行部署

On first install only

[root@K8S-PROD-M1 metallb]# kubectl apply -f metallb-namespace.yaml
[root@K8S-PROD-M1 metallb]# kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
[root@K8S-PROD-M1 metallb]# kubectl apply -f metallb.yaml

**配置MetalLB**创建一个Configmap文件,为MetalLB设置网址范围以及协议相关的选择和配置,这里以一个简单的二层配置为例:LB地址段是192.168.122.100-192.168.122.200,跟K8S节点的管理网是同一个/24地址段。

[root@K8S-PROD-M1 metallb]# cat > config.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:

  • name: default
    protocol: layer2
    addresses:
    • 192.168.122.100-192.168.122.200
      EOF
创建ConfigMap:[root@K8S-PROD-M1 metallb]# kubectl apply -f config.yaml该ConfigMap一旦创建,IP地址池信息将被缓存至MetalLB Controller, 如果修改了IP地址池,则需要重新创建MetalLB Controller Pod。**配置更新过程**

[root@K8S-PROD-M1 metallb]# kubectl -n metallb-system logs -f pod/controller-6c578774c8-7xnjb
...
{"caller":"main.go:63","event":"endUpdate","msg":"end of service update","service":"kubernetes-dashboard/kubernetes-dashboard","ts":"2020-09-24T03:21:19.959638677Z"}
{"caller":"main.go:126","event":"stateSynced","msg":"controller synced, can allocate IPs now","ts":"2020-09-24T03:21:19.95968369Z"}
...

**测试MetalLB****创建SVC**

piVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:

  • name: nginx
    image: harbor.cluster.local/library/nginx:latest
    ports:
    • name: http
      containerPort: 80

apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:

  • name: http
    port: 80
    protocol: TCP
    targetPort: 80
    type: LoadBalancer

deploy-lbsvc-demo.yaml

[root@K8S-PROD-M1 metallb]# kubectl apply -f deploy-lbsvc-demo.yaml

查看SVC

[root@K8S-PROD-M1 metallb]# kubectl get svcNAME         TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)        AGEkubernetes   ClusterIP      10.96.0.1       <none>            443/TCP        23dnginx        LoadBalancer   10.106.22.150   192.168.122.100   80:31852/TCP   2m30ssvc-demo-1   ClusterIP      10.98.47.47     <none>            80/TCP         5m10ssvc-demo-2   ClusterIP      10.109.97.203   <none>            8080/TCP       47h

查看日志

[root@K8S-PROD-M1 metallb]# kubectl -n metallb-system logs -f pod/controller-6c578774c8-7xnjb...{"caller":"main.go:49","event":"startUpdate","msg":"start of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.415605635Z"}{"caller":"service.go:114","event":"ipAllocated","ip":"192.168.122.100","msg":"IP address assigned by controller","service":"default/nginx","ts":"2020-09-24T06:24:46.41577988Z"}{"caller":"main.go:96","event":"serviceUpdated","msg":"updated service object","service":"default/nginx","ts":"2020-09-24T06:24:46.53081167Z"}{"caller":"main.go:98","event":"endUpdate","msg":"end of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.530878232Z"}{"caller":"main.go:49","event":"startUpdate","msg":"start of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.530912503Z"}{"caller":"main.go:75","event":"noChange","msg":"service converged, no change","service":"default/nginx","ts":"2020-09-24T06:24:46.531027842Z"}{"caller":"main.go:76","event":"endUpdate","msg":"end of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.531200567Z"}...

访问SVC

  • NAT配置

iptables -t nat -A PREROUTING -m tcp -p tcp -d 192.168.191.32 --dport 31852 -j DNAT --to-destination 192.168.122.100:80

* 访问Web UI浏览器中访问:http://192.168.191.32:31852即可访问nginx首页,或者:

[root@server ~]# curl http://192.168.122.100/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
......

**高级功能****多个Service共用一个IP**创建Service的时候加上一个annotation:metallb.universe.tf/allow-shared-ip: <some_key>,那么使用相同Key的Service会共用同一个IP。然共享IP的前提是这些Service都使用不同的Port。
©著作权归作者所有:来自51CTO博客作者mob604756e9d3bc的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. K8S v1.18.x 部署-Kubeadm方式-4:部署负载均衡
  2. K8S v1.18.x 部署-Kubeadm方式-3:部署工具
  3. CentOS 7部署OpenStack--准备基础环境
  4. httpd,tomcat,tomcat-connector下载地址
  5. CentOS 7部署OpenStack--部署Newtron(计算节点)
  6. IPFS矿池集群方案详解
  7. IPFS挖矿硬盘满了会怎样?
  8. Nginx隐藏式跳转
  9. Kafka 集群部署

随机推荐

  1. Emacs中的Python 2和3都是如此
  2. Python测试函数和类 笨方法学习Python
  3. python将回车作为输入内容
  4. 读取python中的unicode文件,该文件以与pyt
  5. NMF算法简介及python实现(gradient desce
  6. 凡哥带你玩转OpenCV-预备知识
  7. Impala实践之六:使用Rest Api
  8. 【python之路45】tornado的用法 (三)
  9. 建模分析之机器学习算法(附python&R代码)
  10. Python新式类和经典类的区别