日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/8/23 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在 Kubernetes 集群中使用 MetalLB 作为 Load Balancer(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者 | 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?服務上。

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]上。

安裝 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.30、192.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?上:

而去虛擬機(節點)查看網卡(這里只能看到系統綁定的 IP):

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 這里有可能會再跳去另一臺主機。

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/

往期推薦

為什么大家都在抵制用定時任務實現「關閉超時訂單」功能?

如果被問到分布式鎖,應該怎樣回答?

別再用 Redis List 實現消息隊列了,Stream 專為隊列而生

Java 底層知識:什么是?“橋接方法”??

點分享

點收藏

點點贊

點在看

總結

以上是生活随笔為你收集整理的在 Kubernetes 集群中使用 MetalLB 作为 Load Balancer(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。