在 Kubernetes 集群中使用 MetalLB 作为 Load Balancer(上)

db090127dacc99249c51c1838d6fadad.gif

作者 | Addo Zhang

来源 | 云原生指北

TL;DR

网络方面的知识又多又杂,很多又是系统内核的部分。原本自己不是做网络方面的,系统内核知识也薄弱。但恰恰是这些陌生的内容满满的诱惑,加上现在的工作跟网络关联更多了,逮住机会就学习下。

这篇以 Kubernetes LoadBalancer 为起点,使用 MetalLB 去实现集群的负载均衡器,在探究其工作原理的同时了解一些网络的知识。

由于 MetalLB 的内容有点多,一步步来,今天这篇仅介绍其中简单又容易理解的部分。

LoadBalancer 类型 Service

由于 Kubernets 中 Pod 的 IP 地址不固定,重启后 IP 会发生变化,无法作为通信的地址。Kubernets 提供了 Service 来解决这个问题,对外暴露。

Kubernetes 为一组 Pod 提供相同的 DNS 名和虚拟 IP,同时还提供了负载均衡的能力。这里 Pod 的分组通过给 Pod 打标签(Label )来完成,定义 Service 时会声明标签选择器(selector)将 Service 与 这组 Pod 关联起来。

根据使用场景的不同,Service 又分为 4 种类型:ClusterIP、NodePort、LoadBalancer 和 ExternalName,默认是 ClusterIP。这里不一一详细介绍,有兴趣的查看 Service 官方文档[1]。

除了今天的主角 LoadBalancer 外,其他 3 种都是比较常用的类型。LoadBalancer 官方的解释是:

使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

e52ff7073a7eed664e78651430b5c8b8.png
lb-service

看到“云提供商提供”几个字时往往望而却步,有时又需要 LoadBalancer 对外暴露服务做些验证工作(虽然除了 7 层的 Ingress 以外,还可以使用 NodePort 类型的 Service),而 Kubernetes 官方并没有提供实现。比如下面要介绍的 MetalLB[2] 就是个不错的选择。

MetalLB 介绍

MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。

注意: MetalLB 目前还是 beta 阶段。

前文提到 Kubernetes 官方并没有提供 LoadBalancer 的实现。各家云厂商有提供实现,但假如不是运行在这些云环境上,创建的 LoadBalancer Service 会一直处于 Pending 状态(见下文 Demo 部分)。

MetalLB 提供了两个功能:

  • 地址分配:当创建 LoadBalancer Service 时,MetalLB 会为其分配 IP 地址。这个 IP 地址是从预先配置的 IP 地址库获取的。同样,当 Service 删除后,已分配的 IP 地址会重新回到地址库。

  • 对外广播:分配了 IP 地址之后,需要让集群外的网络知道这个地址的存在。MetalLB 使用了标准路由协议实现:ARP、NDP 或者 BGP。

广播的方式有两种,第一种是 Layer 2 模式,使用 ARP(ipv4)/NDP(ipv6) 协议;第二种是 BPG。

今天主要介绍简单的 Layer 2 模式,顾名思义是 OSI 二层的实现。

具体实现原理,看完 Demo 再做分析,等不及的同学请直接跳到最后。

运行时

MetalLB 运行时有两种工作负载:

  • Controler:Deployment,用于监听 Service 的变更,分配/回收 IP 地址。

  • Speaker:DaemonSet,对外广播 Service 的 IP 地址。

Demo

安装之前介绍下网络环境,Kubernetes 使用 K8s 安装在 Proxmox 的虚拟机[3]上。

f4320aa0359a78e5945784c0d02229f8.png

安装 K3s

安装 K3s,这里需要通过 --disable servicelb 禁用 k3s 默认的 servicelb。

参考 K3s 文档[4],默认情况下 K3s 使用 Traefik[5] ingress 控制器 和 Klipper[6] Service 负载均衡器来对外暴露服务。

curl -sfL https://get.k3s.io | sh -s - --disable traefik --disable servicelb --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config

创建工作负载

使用 nginx 镜像,创建两个工作负载:

kubectl create deploy nginx --image nginx:latest --port 80 -n default
kubectl create deploy nginx2 --image nginx:latest --port 80 -n default

同时为两个 Deployment 创建 Service,这里类型选择 LoadBalancer:

kubectl expose deployment nginx --name nginx-lb --port 8080 --target-port 80 --type LoadBalancer -n default
kubectl expose deployment nginx2 --name nginx2-lb --port 8080 --target-port 80 --type LoadBalancer -n default

检查 Service 发现状态都是 Pending 的,这是因为安装 K3s 的时候我们禁用了 LoadBalancer 的实现:

kubectl get svc -n default
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      10.43.0.1       <none>        443/TCP          14m
nginx-lb     LoadBalancer   10.43.108.233   <pending>     8080:31655/TCP   35s
nginx2-lb    LoadBalancer   10.43.26.30     <pending>     8080:31274/TCP   16s

这时就需要 MetalLB 登场了。

安装 MetalLB

使用官方提供 manifest 来安装,目前最新的版本是 0.12.1。此外,还可以其他安装方式供选择,比如 Helm[7]、Kustomize[8] 或者 MetalLB Operator[9]

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yamlkubectl get po -n metallb-system
NAME                          READY   STATUS    RESTARTS   AGE
speaker-98t5t                 1/1     Running   0          22s
controller-66445f859d-gt9tn   1/1     Running   0          22s

此时再检查 LoadBalancer Service 的状态仍然是 Pending 的,嗯?因为,MetalLB 要为 Service 分配 IP 地址,但 IP 地址不是凭空来的,而是需要预先提供一个地址库。

这里我们使用 Layer 2 模式,通过 Configmap 为其提供一个 IP 段:

apiVersion: v1
kind: ConfigMap
metadata:namespace: metallb-systemname: config
data:config: |address-pools:- name: defaultprotocol: layer2addresses:- 192.168.1.30-192.168.1.49

此时再查看 Service 的状态,可以看到 MetalLB 为两个 Service 分配了 IP 地址 192.168.1.30192.168.1.31

kubectl get svc -n default
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
kubernetes   ClusterIP      10.43.0.1       <none>         443/TCP          28m
nginx-lb     LoadBalancer   10.43.201.249   192.168.1.30   8080:30089/TCP   14m
nginx2-lb    LoadBalancer   10.43.152.236   192.168.1.31   8080:31878/TCP   14m

可以请求测试下:

curl -I 192.168.1.30:8080
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Wed, 02 Mar 2022 15:31:15 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 25 Jan 2022 15:03:52 GMT
Connection: keep-alive
ETag: "61f01158-267"
Accept-Ranges: bytescurl -I 192.168.1.31:8080
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Wed, 02 Mar 2022 15:31:18 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 25 Jan 2022 15:03:52 GMT
Connection: keep-alive
ETag: "61f01158-267"
Accept-Ranges: bytes

macOS 本地使用 arp -a 查看 ARP 表可以找到这两个 IP 及 mac 地址,可以看出两个 IP 都绑定在同一个网卡上,此外还有虚拟机的 IP 地址。也就是说 3 个 IP 绑定在该虚拟机的 en0 上:

9f573320528c271842088b8a775ccab8.png

而去虚拟机(节点)查看网卡(这里只能看到系统绑定的 IP):

3151ddec13418e238e8c4fc7c0e0a38a.png

Layer 2 工作原理

Layer 2 中的 Speaker 工作负载是 DeamonSet 类型,在每台节点上都调度一个 Pod。首先,几个 Pod 会先进行选举,选举出 Leader。Leader 获取所有 LoadBalancer 类型的 Service,将已分配的 IP 地址绑定到当前主机到网卡上。也就是说,所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上。

当外部主机有请求要发往集群内的某个 Service,需要先确定目标主机网卡的 mac 地址(至于为什么,参考维基百科[10])。这是通过发送 ARP 请求,Leader 节点的会以其 mac 地址作为响应。外部主机会在本地 ARP 表中缓存下来,下次会直接从 ARP 表中获取。

请求到达节点后,节点再通过 kube-proxy 将请求负载均衡目标 Pod。所以说,假如Service 是多 Pod 这里有可能会再跳去另一台主机。

c38af7ee01c2bfaade746d1cfc2ed8f7.png
sequence

优缺点

优点很明显,实现起来简单(相对于另一种 BGP 模式下路由器要支持 BPG)。就像笔者的环境一样,只要保证 IP 地址库与集群是同一个网段即可。

当然缺点更加明显了,Leader 节点的带宽会成为瓶颈;与此同时,可用性欠佳,故障转移需要 10 秒钟的时间(每个 speaker 进程有个 10s 的循环[11])。

参考链接:

Service 官方文档: 

https://kubernetes.io/zh/docs/concepts/services-networking/service/#publishing-services-service-types 

MetalLB: https://metallb.universe.tf

Proxmox 的虚拟机: 

https://atbug.com/deploy-vm-on-proxmox-with-terraform/

K3s 文档: 

https://rancher.com/docs/k3s/latest/en/networking/

Traefik: https://rancher.com/docs/k3s/latest/en/networking/

Klipper: https://metallb.universe.tf/configuration/k3s/

Helm: https://metallb.universe.tf/installation/#installation-with-helm

Kustomize: 

https://metallb.universe.tf/installation/#installation-with-kustomize

MetalLB Operator: https://metallb.universe.tf/installation/#using-the-metallb-operator

维基百科: 

https://zh.wikipedia.org/wiki/%E5%9C%B0%E5%9D%80%E8%A7%A3%E6%9E%90%E5%8D%8F%E8%AE%AE

每个 speaker 进程有个 10s 的循环:

https://github.com/metallb/metallb/blob/main/internal/layer2/announcer.go#L51

地址解析协议: 

https://zh.wikipedia.org/wiki/%E5%9C%B0%E5%9D%80%E8%A7%A3%E6%9E%90%E5%8D%8F%E8%AE%AE

MetalLB 概念: 

https://metallb.universe.tf/concepts/

756d183306757f0f32d67672b486636c.gif

2e0977321d2d12690f116b498a92a9e1.png

往期推荐

为什么大家都在抵制用定时任务实现「关闭超时订单」功能?

如果被问到分布式锁,应该怎样回答?

别再用 Redis List 实现消息队列了,Stream 专为队列而生

Java 底层知识:什么是 “桥接方法” ?

9df05c9376cc3e14534a813fbab03aef.gif

点分享

a2a3cf14f66359e921618f2b5a12d572.gif

点收藏

ecd9088a121c2a2fbb9f5723910d4171.gif

点点赞

372669aa8fc4abd0a452bfd6e131fc73.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512198.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java程序员情人节_盘点程序员情人节的表白,前端程序员最浪漫,后端不服来战...

今天是 2 月 14 日情人节&#xff0c;我看公众号后台有好多人在回复关键字&#xff1a;情人节表白代码。我想&#xff0c;我作为大家的校长&#xff0c;必须给大家送一波福利代码啊!我是真没想到&#xff0c;竟然很多程序员都想用代码表白&#xff0c;还整的挺浪漫的&#xff0…

GRPC: 如何实现分布式日志跟踪?

简介&#xff1a; 本文将介绍如何在 gRPC 分布式场景中&#xff0c;实现 API 的日志跟踪。 介绍 本文将介绍如何在 gRPC 分布式场景中&#xff0c;实现 API 的日志追踪。 什么是 API 日志追踪&#xff1f; 一个 API 请求会跨多个微服务&#xff0c;我们希望通过一个唯一的 ID…

一文搞懂物联网Modbus通讯协议

简介&#xff1a; 一般来说&#xff0c;常见的物联网通讯协议众多&#xff0c;如蓝牙、Zigbee、WiFi、ModBus、PROFINET、EtherCAT、蜂窝等。而在众多的物联网通讯协议中&#xff0c;Modbus是当前非常流行的一种通讯协议。它一种串行通信协议&#xff0c;是Modicon公司于1979年…

快看世界技术VP安尝思:从漫画到视频,如何用技术赋能创作

供稿 | 快看世界 2月25日&#xff0c;在火山引擎举办的视频云科技原力峰会上&#xff0c;快看世界技术VP安尝思受邀参加&#xff0c;并发表主题为《如何搭建轻量高效的视频技术体系》的演讲。 安尝思表示&#xff0c;快看视频内容的革命性变化来自于漫剧的推出&#xff0c;在过…

2021云栖大会丨阿里云发布第四代神龙架构,提供业界首个大规模弹性RDMA加速能力

简介&#xff1a; 10月20日&#xff0c;2021年杭州栖大云会上&#xff0c;阿里云发布第四代神龙架构&#xff0c;升级至全新的eRMDA网络架构&#xff0c;是业界首个大规模弹性RDMA加速能力。 10月20日&#xff0c;2021年杭州栖大云会上&#xff0c;阿里云发布第四代神龙架构。…

Rambus推出面向下一代数据中心的PCIe 6.0控制器

新闻摘要&#xff1a; 将先进的人工智能/机器学习、存储和网络应用的性能提升至64 GT/s优化了功耗、面积和延迟&#xff0c;全方位实现PCIe 6.0特性集成IDE引擎提供最先进的数据安全Rambus PCIe 6.0控制器框图 作为业界领先的芯片和IP核供应商&#xff0c;致力于使数据传输更…

阿里云混合云Apsara Stack 2.0发布 加速政企数智创新

简介&#xff1a; 2021年10月21日&#xff0c;杭州 – 今日&#xff0c;阿里云于云栖大会正式发布Apsara Stack 2.0&#xff0c;从面向单一私有云场景&#xff0c;升级为服务大型集团云&行业云场景。新一代Apsara Stack不仅可以为政企定制稳定、安全、开放、智能的数字底座…

ArrayList源码浅析

简介&#xff1a; ArrayList作为我们开发中最常用的集合&#xff0c;作为极高频次使用的类&#xff0c;我们不妨阅读源码一谈究竟。 前言 ArrayList作为我们开发中最常用的集合&#xff0c;作为极高频次使用的类&#xff0c;我们不妨阅读源码一谈究竟。 介绍 ArrayList继承…

阿里云边缘云ENS再升级 四大场景应用加速产业数字化落地

简介&#xff1a; 云栖大会 | 于10月21日上午举办的边缘云应用升级与技术创新论坛中&#xff0c;阿里云边缘云ENS产品全面升级&#xff0c;从边缘云产品、技术、行业应用等维度全面阐述阿里云在边缘计算领域的技术积累、产品&解决方案沉淀、商业实践。 一年一度科技圈盛事…

在 Kubernetes 集群中使用 MetalLB 作为 LoadBalancer(下)

作者 | Addo Zhang来源 | 云原生指北在上一篇《在 Kubernetes 集群中使用 MetalLB 作为 LoadBalancer&#xff08;上&#xff09;》中&#xff0c;我们使用 MetalLB 的 Layer2 模式作为 LoadBalancer 的实现&#xff0c;将 Kubernetes 集群中的服务暴露到集群外。还记得我们在 …

聚焦2021云栖大会,边缘云专场畅谈技术应用创新

简介&#xff1a; 本届大会以“前沿 探索 想象力”为主题&#xff0c;与业界同仁、合作伙伴共同打造一场数字时代的云上相聚。其中&#xff0c;边缘计算技术领域因5G快速发展而备受关注&#xff0c;阿里云边缘云专场吸引了数百位参会嘉宾驻足。 于10月21日上午举办的“边缘云应…

技术干货 | 闲鱼:一个优秀的 Push 平台,需要经历怎样的前世今生

简介&#xff1a; mPaaS 消息推送服务&#xff0c;快速集成多家厂商 Push 通道&#xff0c;有效提高用户留存率&#xff0c;提升用户体验。 编者荐语&#xff1a; 点击这里&#xff0c;了解 mPaaS 消息推送服务&#xff0c;快速集成多家厂商 Push 通道&#xff0c;有效提高用户…

「深入浅出」主流前端框架更新批处理方式

作者 | &#x1f47d;来源 | 前端Sharing背景在不同的技术框架背景下&#xff0c;处理更新的手段各不相同&#xff0c;今天我们来探讨一下&#xff0c;主流的前端框架批量处理的方式&#xff0c;和其内部的实现原理。通过今天的学习&#xff0c;你将收获这些内容&#xff1a;主…

钉钉宜搭3.0发布!易连接、酷数据、更安全

简介&#xff1a; 10月20日&#xff0c;在2021云栖大会低代码分论坛上&#xff0c;阿里巴巴资深技术专家叶周全&#xff08;花名骁勇&#xff09;发布钉钉宜搭3.0版本。 10月20日&#xff0c;在2021云栖大会低代码分论坛上&#xff0c;阿里巴巴资深技术专家叶周全&#xff08;…

基层数字化治理困境如何破局?

简介&#xff1a; 10月20日&#xff0c;2021云栖大会低代码分论坛如约举行。在这场低代码行业的盛会上&#xff0c;兰溪市大数据发展中心党组书记、主任芦建洪分享的内容获得了在场观众的热烈反响&#xff0c;兰溪市使用钉钉宜搭低代码破解基层数字化治理困境的成功经验也为全国…

形式化验证工具TLA+:程序员视角的入门之道

简介&#xff1a; 女娲是飞天分布式系统中提供分布式协同的基础服务&#xff0c;支撑着阿里云的计算、网络、存储等几乎所有云产品。在女娲分布式协同服务中&#xff0c;一致性引擎是核心基础模块&#xff0c;支持了Paxos&#xff0c;Raft&#xff0c;EPaxos等多种一致性协议&a…

性能突出的 Redis 是咋使用 epoll 的?

作者 | 闪客来源 | 低并发编程我是个 redis 服务&#xff0c;我马上就要启动了因为我的主人正在控制台输入&#xff1a;./redis-server宏观上看下我的流程突然&#xff0c;主人按下了回车键&#xff0c;不得了了。shell 程序把我的程序加载到了内存&#xff0c;开始执行我的 ma…

阿里云重磅发布业务中台产品 BizWorks,中台发展进入下一个阶段

简介&#xff1a; 业务中台产品BizWorks重磅发布&#xff0c;这可以看作是阿里云在 “做厚中台” 战略上继 “云钉一体”之后的又一个新动作&#xff01; 10 月 19 日&#xff0c;2021 云栖大会正式开幕&#xff0c;连续举办多年的云栖大会俨然已经成为了国内科技产业展示前沿…

java32位怎么用eclipse_无法在Windows 7 32位上打开eclipse

我正在使用Eclipse Indigo(eclipse-jee-indigo-SR2-win32) . 当我双击eclipse.exe时&#xff0c;会出现以下对话框&#xff1a;日志文件的内容如下&#xff1a;!SESSION 2013-05-27 17:55:26.853 -----------------------------------------------eclipse.buildIdM20120208-080…

云栖发布|企业级互联网架构全新升级 ,助力数字创新

简介&#xff1a; 云原生产品家族全面升级&#xff0c;让业务技术团队有了更多选择&#xff0c;通过简单、丰富、开放和低成本的 PaaS 服务&#xff0c;帮助企业客户更简单、更高效的进行在云上创新&#xff0c;搭建更符合业务需要和团队情况的技术体系。 作者&#xff5c;白玙…