树莓派部署 Kubernetes:通过 UDM Pro 实现 BGP 负载均衡!

描述

 

最近,我将家庭实验室的架构核心切换为一组树莓派。

尽管在树莓派上运行的 Kubernetes 发行版众多,但在资源受限的设备上运行 Kubernetes 时,控制平面的开销是一个常见挑战。使用 Cloudfleet 等允许远程本地节点的托管 Kubernetes 服务,可以卸载这一责任。这种方法让树莓派能够将其资源专门用于运行工作负载,而不是消耗 CPU 和内存来处理控制平面任务。Cloudfleet 提供了一个免费的集群,最多支持 24 个 CPU,这可以覆盖我的两台树莓派 5,总共 16 个核心的设置。

在我之前的尝试中,在我的环境中有效实现 Kubernetes 负载均衡会面临一些挑战。与云平台不同,云平台上的负载均衡是现成的服务,本地部署则需要更多的手动网络配置。当创建类型为 LoadBalancer 的 Kubernetes 服务时,需要建立一个虚拟 IP(VIP)并使其在网络上可访问。虽然像 MetalLB 这样的项目可以通过让节点使用 L2 广播(例如 ARP 请求)来宣布 VIP,但这种方法通常将 VIP 的可用性限制在任何给定时间只能由单个节点使用,这并不符合我的期望。

L2 广播的一个更健壮的替代方案是 BGP(边界网关协议)。使用 BGP,你的 Kubernetes 集群可以直接向路由器广播 LoadBalancer VIP。这允许路由器将流量分配到为负载均衡服务提供服务的多个节点上,提供更好的冗余和可扩展性潜力。此外,使用 BGP,你还可以广播 Pod IP,使你的内部 Pod 网络在局域网中可用。

我在网络中使用的是 UniFi 堆栈,直到最近,UniFi Dream Machine Pro(UDM Pro)还缺乏原生 BGP 支持。然而,这一功能现在已经可用,使得基于 BGP 的负载均衡解决方案成为可能。

在这篇文章中,我将引导你完成如何将树莓派集成到 Cloudfleet 管理的 Kubernetes 集群中,并配置 UDM Pro 的 BGP 网络,以实现无缝的服务暴露。

 

设置 Kubernetes 集群

使用 Cloudfleet 创建 Kubernetes 集群非常简单。首先,你需要通过访问 Cloudfleet 控制台进行注册。

注册并创建组织后,下一步是创建 Kubernetes 集群。有关安装 Cloudfleet CLI 和创建集群的详细说明,请参阅官方 Cloudfleet 入门指南。

 

该指南将引导你完成创建空集群和设置 Cloudfleet CLI 的必要步骤,你需要使用该 CLI 来添加树莓派节点。

创建集群后,你将收到一个 CLUSTER_ID。请保留此 ID,因为你需要它来添加树莓派节点。

将树莓派节点添加到 Cloudfleet 集群

将树莓派集成到 Cloudfleet 集群中涉及为树莓派准备正确的操作系统,然后使用 Cloudfleet CLI 将它们作为自管理节点添加。

1.Cloudfleet 要求自管理节点运行 Ubuntu 24.04 LTS。将 Ubuntu 24.04 安装到树莓派的 microSD 卡上的最简单方法是使用官方树莓派成像器。

 

2.在你的计算机上下载并安装树莓派成像器。

3.将 microSD 卡插入计算机。

4.打开树莓派成像器。

5.点击“CHOOSE DEVICE”(选择设备)并选择你的树莓派型号(例如树莓派 5)。

6.点击“CHOOSE OS”(选择操作系统)。导航到“Other general-purpose OS”(其他通用操作系统)->“Ubuntu”。

7.选择“Ubuntu Server 24.04 LTS (64-bit)”(通常建议为无头 Kubernetes 节点使用服务器版)。

8.点击“CHOOSE STORAGE”(选择存储)并选择你的 microSD 卡。

9.强烈建议点击齿轮图标以预配置设置,如主机名、启用 SSH(并设置密码或授权密钥)以及设置用户帐户。这简化了无头设置。

10.点击“NEXT”(下一步),然后点击“YES”(是)以确认并开始写入镜像。

11.写入完成后,将 microSD 卡插入树莓派,通过以太网将其连接到网络,并接通电源。确保它有一个 IP 地址,并且 SSH 访问正常。

操作系统准备好后,在你的机器上(已安装 Cloudfleet CLI 并已登录),对要添加到集群的每个树莓派执行以下命令:

  •  

cloudfleet clusters add-self-managed-node CLUSTER_ID --host RPI_IP --ssh-username SSH_USERNAME --region my-home --zone my-home

将 CLUSTER_ID 替换为你在上一节中创建的集群的 ID。

将 RPI_IP 替换为树莓派在你本地网络上的 IP 地址。

将 SSH_USERNAME 替换为你为树莓派上的 SSH 访问配置的用户名。

--region my-home 和 --zone my-home 标志将为你的节点分配这些标签。这些标签是任意的,但对于组织节点很有用,并且可以在 Kubernetes 配置中使用,如我们稍后的 BGP 设置。

然后,Cloudfleet CLI 将通过 SSH 连接到你的树莓派,安装必要的软件,并将其加入到你的托管 Kubernetes 集群中。一段时间后,树莓派应显示为 Cloudfleet 仪表板和通过 kubectl get nodes(在配置 kubectl 指向你的 Cloudfleet 集群后,你可以通过点击 Cloudfleet 控制台上的“Connect to cluster”(连接到集群)按钮了解如何操作)中的就绪节点。

部署第一个工作负载

在进行 BGP 设置并查看 LoadBalancer 服务的实际效果之前,为了测试我们的新集群,让我们部署一个简单的 Nginx 应用程序。

创建一个名为 nginx-deployment.yaml 的文件,内容如下:

  •  
  •  
  •  
  •  

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-deployment  labels:    app: nginxspec:  replicas: 2 # Running two replicas for demonstration  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:latest # Using the latest Nginx image        ports:        - containerPort: 80---apiVersion: v1kind: Servicemetadata:  name: nginx-servicespec:  selector:    app: nginx  ports:    - protocol: TCP      port: 80       # Port accessible on the LoadBalancer IP      targetPort: 80 # Port on the Nginx pods  type: LoadBalancer # This is key for BGP to pick it up

将此部署应用到你的集群:

  •  

kubectl apply -f nginx-deployment.yaml

一段时间后,Kubernetes 将创建部署和服务。

你可以检查服务的状态:

  •  

kubectl get svc nginx-service

查找 EXTERNAL-IP 字段。它将保持 PENDING 状态,因为没有负载均衡功能会接收此服务并为其创建 VIP。这是我们将在下一节中解决的问题。

为本地负载均衡设置 BGP

Cloudfleet 使用 Cilium 作为其 CNI(容器网络接口),它提供了 BGP 广播功能。有关 Cloudfleet 网络架构的更多详细信息,请参阅此处。

https://cloudfleet.ai/docs/networking/architecture/

有关使用 BGP 进行本地负载均衡的指南,请参阅此处。

https://cloudfleet.ai/docs/networking/on-premises-load-balancing-with-bgp/

1. Cilium BGP 配置

首先,我们需要为集群配置 BGP。这涉及创建几个 Kubernetes 自定义资源:

a) CiliumLoadBalancerIPPool:这定义了 Cilium 可以分配给 LoadBalancer 服务的 IP 地址池。这些 IP 应该是 UDM Pro 可路由的子网的一部分,并专门用于此目的。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

apiVersion: "cilium.io/v2alpha1"kind: CiliumLoadBalancerIPPoolmetadata:  name: "pool"spec:  blocks:    - start: 172.16.199.2 # Ensure this range is available on your network and reserved for K8s      stop: 172.16.199.254

如果你要广播的 CIDR 不是 UDM PRO 中任何现有网络的一部分,你应该创建一个覆盖此 CIDR 的网络。否则,UDM PRO 将不会将流量路由到这些 IP。

b) CiliumBGPAdvertisement:此资源指定 Cilium 应通过 BGP 广播哪些路由,例如分配给 LoadBalancer 服务的 IP 和 Pod CIDR。

  •  
  •  

apiVersion: "cilium.io/v2alpha1"kind: CiliumBGPAdvertisementmetadata:  name: services  labels:    advertise: bgp # This label is used to select this advertisementspec:  advertisements:    - advertisementType: PodCIDR    - advertisementType: Service      service:        addresses:          - LoadBalancerIP        selector:          # This selector aims to advertise all LoadBalancer services.          # It matches services having any label by checking for a key not matching 'never-used-value'.          matchExpressions:            - { key: somekey, operator: NotIn, values: [ 'never-used-value' ] }

通过添加 PodCIDR,我还在向内部网络广播 Pod IP,但这完全是可选的。

c) CiliumBGPPeerConfig:这定义了常见的 BGP 对等配置。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

apiVersion: cilium.io/v2alpha1kind: CiliumBGPPeerConfigmetadata:  name: unifi # Named 'unifi' as it peers with the UDM Prospec:  gracefulRestart: # Enabling graceful restart for smoother updates    enabled: true    restartTimeSeconds: 15  families:    - afi: ipv4      safi: unicast      advertisements:        matchLabels: # Selects the 'services' CiliumBGPAdvertisement via its label          advertise: "bgp"

d) CiliumBGPClusterConfig:此主要配置在 Cilium 代理(节点)上建立 BGP 实例。它定义了 Kubernetes 集群的本地 ASN 和 BGP 对等细节(你的 UDM Pro)。请注意,nodeSelector 现在与添加节点时指定的区域和区域匹配。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

apiVersion: cilium.io/v2alpha1kind: CiliumBGPClusterConfigmetadata:  name: unifispec:  nodeSelector: # Ensures this BGP config applies to the specified RPi nodes    matchLabels:      topology.kubernetes.io/region: my-home      topology.kubernetes.io/zone: my-home  bgpInstances:    - name: "cloudfleet-bgp" # Name of this BGP instance      localASN: 65001 # ASN for the K8s cluster's BGP      peers:        - name: unifi # Name of the peer (UDM Pro)          peerASN: 65000 # ASN of the UDM Pro          peerAddress: "172.16.10.1" # IP address of your UDM Pro on the relevant LAN          peerConfigRef:            name: unifi # References the CiliumBGPPeerConfig defined above

将这些 YAML 文件应用到你的 Kubernetes 集群(kubectl apply -f .yaml)。然后,Cilium 的 BGP 组件将尝试与指定的对等(172.16.10.1)建立 BGP 会话。不要忘记为你的设置修改 UDM Pro 的 IP 地址!

2. UDM Pro BGP 配置

接下来,必须在你的 UDM Pro 上配置 BGP。UniFi OS 包含 FRRouting 以实现此类功能。他们的官方指南可以在此处找到。

我使用的 FRRouting 配置如下。你在 UDM PRO 的 Web 界面上上传此文件。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

! -*- bgp -*-!hostname $UDMP_HOSTNAMEpassword zebrafrr defaults traditionallog file stdout!router bgp 65000  # UDM Pro's ASN (must match peerASN in CiliumBGPClusterConfig) bgp ebgp-requires-policy # Standard practice for eBGP bgp router-id 172.16.10.1 # UDM Pro's BGP router ID (its LAN IP) maximum-paths 2 # Optional: allow multiple paths ! neighbor cilium peer-group # Using a peer-group for organization neighbor cilium remote-as 65001 # ASN of the Cilium BGP (must match localASN in CiliumBGPClusterConfig) neighbor cilium activate neighbor cilium soft-reconfiguration inbound # Allows policy changes without session reset ! ! Define Raspberry Pi node IPs as BGP neighbors ! These are the nodes running the Cilium BGP speaker neighbor 172.16.10.241 peer-group cilium # IP of RPi 1 neighbor 172.16.10.242 peer-group cilium # IP of RPi 2 ! address-family ipv4 unicast  redistribute connected # Optional: Advertise UDM Pro's connected routes  neighbor cilium activate  neighbor cilium route-map ALLOW-ALL in # Apply route-map to permit routes  neighbor cilium route-map ALLOW-ALL out  neighbor cilium next-hop-self # Important: UDM advertises itself as the next hop exit-address-family !route-map ALLOW-ALL permit 10 # A simple route-map permitting all routes!line vty!

UDM Pro BGP 关键设置:

router bgp 65000:设置 UDM Pro 的 ASN。这应与 Cilium 的 localASN(65001)不同,以便进行 BGP 对等。

bgp router-id 172.16.10.1:UDM Pro 的路由器 ID,通常是其 LAN IP。

neighbor peer-group cilium:每个可能运行 Cilium BGP 发言人的树莓派节点都被定义为对等。这些应该是你添加到 Cloudfleet 集群的树莓派的 IP。

neighbor cilium remote-as 65001:通知 UDM Pro 这些对等属于 ASN 65001。

neighbor cilium next-hop-self:确保 UDM Pro 广告自身为从 Cilium 学习到的路由的下一跳。

route-map ALLOW-ALL:一个基本的路由图,允许来自/去往 Cilium 对等的所有路由。如果需要,可以对其进行细化以进行更具体的过滤。

在应用 UDM Pro 和 Cilium BGP 配置后,BGP 会话应建立。你可以通过 SSH 登录到 UDM Pro(例如,在 vtysh 中使用 show ip bgp summary)和使用 Cilium CLI 命令(例如,cilium bgp peers)在 Kubernetes 节点上检查 BGP 对等状态。

一旦所有设置都正确完成,现在你可以再次检查 Load Balancer 服务,你会发现现在为其分配了一个 VIP。如果你在本地网络上导航到此 IP,你将访问到你刚刚部署的 NGINX。

如果 NGINX Pod 分布在两个不同的节点上,UDM PRO 将在它们之间进行负载均衡。如果只有一个节点提供 Pod 服务,则流量将仅流向该节点。

结果:高效的家庭实验室设置

通过此配置:

我的树莓派运行 Kubernetes 工作负载,控制平面管理由 Cloudfleet 外部处理。

当在 Kubernetes 中创建 LoadBalancer 服务时,Cilium 会从 172.16.199.x 范围内为其分配一个 IP。

Cilium 通过 BGP 将此 IP(以及可选的 Pod CIDR)广播给我的 UDM Pro。

UDM Pro 学习如何将 172.16.199.x 的流量路由到适当的树莓派节点。

服务可以从我的局域网无缝访问。

你还可以设置 UDM PRO 的端口转发功能,将外部流量路由到此 VIP,以简单地开始从你的家庭实验室提供网站服务。祝实验愉快!

原文地址:
 

https://itnext.io/kubernetes-on-raspberry-pi-and-bgp-load-balancing-with-unifi-dream-machine-pro-d5b94b6cfe99

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分