06_在k8s集群中安装MetalLB实现LoadBalancer

文章目录

  • [0 背景与架构](#0 背景与架构)
    • [0.1 为什么需要MetalLB](#0.1 为什么需要MetalLB)
    • [0.2 环境架构](#0.2 环境架构)
    • [0.3 镜像拉取方案](#0.3 镜像拉取方案)
  • [1 安装前准备](#1 安装前准备)
    • [1.1 检查kube-proxy模式](#1.1 检查kube-proxy模式)
    • [1.2 确认集群状态](#1.2 确认集群状态)
  • [2 安装MetalLB](#2 安装MetalLB)
    • [2.1 应用官方Manifest](#2.1 应用官方Manifest)
    • [2.2 处理镜像拉取问题](#2.2 处理镜像拉取问题)
    • [2.3 验证安装](#2.3 验证安装)
  • [3 配置IP地址池](#3 配置IP地址池)
    • [3.1 创建IPAddressPool](#3.1 创建IPAddressPool)
    • [3.2 创建L2Advertisement](#3.2 创建L2Advertisement)
    • [3.3 验证配置](#3.3 验证配置)
  • [4 Mac宿主机用 Safari 浏览器就行](#4 Mac宿主机用 Safari 浏览器就行)
  • [5 测试LoadBalancer Service](#5 测试LoadBalancer Service)
    • [5.1 创建svc](#5.1 创建svc)
    • [5.2 验证EXTERNAL-IP](#5.2 验证EXTERNAL-IP)
    • [5.3 从宿主机访问](#5.3 从宿主机访问)
  • [6 常见问题与解决](#6 常见问题与解决)
    • [6.1 镜像拉取失败](#6.1 镜像拉取失败)
  • [7 总结](#7 总结)
  • 感谢阅读

0 背景与架构

0.1 为什么需要MetalLB

在 《02_在多个RockyLinux10虚拟机上安装k8s集群》 搭建的三节点集群中,如果我们创建一个 type: LoadBalancer 的 Service,它的 EXTERNAL-IP 会一直显示 <pending>:

bash 复制代码
[root@rockylinux10-1 ~]# kubectl get svc
NAME       				TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        			  AGE
kiada-loadbalancer-svc  LoadBalancer   10.1.147.173    <pending>     80:30080/TCP,443:30443/TCP   30s

原因是 Kubernetes 本身并不提供裸金属环境的负载均衡器实现,它自带的 Network LB 都是调用云平台(GCP、AWS、Azure)的接口。如果不在受支持的 IaaS 平台上,LoadBalancer 类型的 Service 就会永远处于 pending 状态。

MetalLB 正是为了解决这个问题而生的------它为裸金属 Kubernetes 集群提供了 LoadBalancer 的实现,使用标准路由协议来对外暴露服务。

0.2 环境架构

IP 虚拟机名称 角色 说明
192.168.56.101 rockylinux10-1 control-plane k8s master 节点
192.168.56.102 rockylinux10-2 worker k8s worker 节点
192.168.56.103 rockylinux10-3 worker k8s worker 节点

0.3 镜像拉取方案

由于国内网络限制,我们采用以下镜像源:

原始仓库 替换地址 用途
docker.io docker.m.daocloud.io DaoCloud 镜像加速
quay.io quay.m.daocloud.io DaoCloud 的 quay 镜像代理

1 安装前准备

1.1 检查kube-proxy模式

MetalLB 的 L2 模式需要确认 kube-proxy 的运行模式。只有在 IPVS 模式 下才需要启用 strictARP,而 iptables 模式(默认)则不需要。

执行以下命令查看当前模式:

bash 复制代码
kubectl get cm kube-proxy -n kube-system -o yaml | grep mode

如果输出为 mode: "",表示使用默认的 iptables 模式,无需任何额外配置,直接继续安装即可。

说明 :只有在输出为 mode: "ipvs" 时,才需要执行 sed -e "s/strictARP: false/strictARP: true/" 并重启 kube-proxy。iptables 模式下 strictARP 参数不生效,也不需要修改。

如果输出为 mode: "ipvs",执行以下命令启用 strict ARP:

bash 复制代码
kubectl get configmap kube-proxy -n kube-system -o yaml | \
  sed -e "s/strictARP: false/strictARP: true/" | \
  kubectl apply -f - -n kube-system

之后重启 kube-proxy Pod:

bash 复制代码
kubectl rollout restart daemonset kube-proxy -n kube-system

1.2 确认集群状态

bash 复制代码
kubectl get nodes
kubectl get pods -n kube-system

确保所有节点为 Ready,控制平面 Pod 正常运行。

2 安装MetalLB

2.1 应用官方Manifest

MetalLB 提供了多种 Manifest,对于 L2 模式,使用 metallb-native 版本即可:

bash 复制代码
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.16.1/config/manifests/metallb-native.yaml

如果该地址因网络问题无法访问,可以先将文件下载到本地再应用:

bash 复制代码
# 在可以访问外网的机器上下载
curl -L -o metallb-native.yaml https://raw.githubusercontent.com/metallb/metallb/v0.16.1/config/manifests/metallb-native.yaml

# 传输到 master 节点
scp metallb-native.yaml root@192.168.56.101:/root/

# 在 master 上应用
kubectl apply -f /root/metallb-native.yaml

2.2 处理镜像拉取问题

安装后查看 Pod 状态:

bash 复制代码
kubectl get pods -n metallb-system

如果出现 ImagePullBackOff,执行以下命令查看使用的镜像:

bash 复制代码
kubectl describe pod -n metallb-system <pod-name> | grep -E "Image:|Failed"

MetalLB 的镜像通常来自 quay.io/metallb/,可以将 quay.io 替换为 quay.m.daocloud.io。修改方式是在 Manifest 中全局替换镜像地址,或者手动拉取并打标签。

2.3 验证安装

bash 复制代码
kubectl get pods -n metallb-system

期望输出:

复制代码
NAME                          READY   STATUS    RESTARTS   AGE
controller-7d8f9c6b8b-xxxxx   1/1     Running   0          2m
speaker-xxxxx                 1/1     Running   0          2m
speaker-yyyyy                 1/1     Running   0          2m
speaker-zzzzz                 1/1     Running   0          2m

controller 是集群范围的控制器,负责 IP 地址分配;speaker 是 DaemonSet,负责通过协议(L2 或 BGP)让服务可达。

3 配置IP地址池

3.1 创建IPAddressPool

MetalLB 需要知道可以为 Service 分配哪些 IP。地址范围必须与你的 VirtualBox Host-Only 网络在同一网段,且不能与节点 IP、DHCP 地址池重叠。

创建文件 ip-pool.yaml:

yaml 复制代码
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.56.240-192.168.56.250

应用:

bash 复制代码
kubectl apply -f ip-pool.yaml

3.2 创建L2Advertisement

L2 模式是最简单的配置方式,只需将 IPAddressPool 与 L2Advertisement 关联即可:

创建文件 l2-advertisement.yaml:

yaml 复制代码
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: first-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - first-pool

应用:

bash 复制代码
kubectl apply -f l2-advertisement.yaml

3.3 验证配置

bash 复制代码
kubectl get ipaddresspool -n metallb-system
kubectl get l2advertisement -n metallb-system

4 Mac宿主机用 Safari 浏览器就行

如果宿主机是 mac 电脑,那么直接用 safari 浏览器访问 k8s 的 service 的 ip 吧。Chrome 浏览器可能无法访问 k8s 的 svc

5 测试LoadBalancer Service

参照 k8s in action 这本书的第11章的 11.2.2 Exposing a service through an external load balancer 小节所说

5.1 创建svc

创建文件 svc.kiada.loadbalancer.yaml:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: kiada-loadbalancer-svc
spec:
  type: LoadBalancer
  selector:
    app: kiada
  ports:
    - name: http
      port: 80
      targetPort: 8080
      nodePort: 30080
      protocol: TCP
    - name: https
      port: 443
      targetPort: 8443
      nodePort: 30443
      protocol: TCP

应用:

bash 复制代码
kubectl apply -f svc.kiada.loadbalancer.yaml

5.2 验证EXTERNAL-IP

bash 复制代码
kubectl get svc

期望输出:

复制代码
NAME                     TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                      AGE
kiada-loadbalancer-svc   LoadBalancer   10.1.147.173   192.168.56.240   80:30080/TCP,443:30443/TCP   9h

EXTERNAL-IP 从 <pending> 变为 192.168.56.240,说明 MetalLB 已成功分配 IP。

5.3 从宿主机访问

如果宿主机是 Mac ,那么就在 Safari 浏览器访问 http://192.168.56.240,应该能看到 Kiada 的页面。Chrome 浏览器是不行的,访问不了。

6 常见问题与解决

6.1 镜像拉取失败

现象 :MetalLB Pod 处于 ImagePullBackOff。

解决 :将 quay.io 替换为 quay.m.daocloud.io,或手动拉取镜像并打标签:

bash 复制代码
sudo ctr -n k8s.io images pull quay.m.daocloud.io/metallb/controller:v0.16.1
sudo ctr -n k8s.io images tag quay.m.daocloud.io/metallb/controller:v0.16.1 quay.io/metallb/controller:v0.16.1

7 总结

通过本文,我们完成了以下工作:

  1. 理解了 MetalLB 的用途:为裸金属 Kubernetes 集群提供 LoadBalancer 类型的 Service 实现
  2. 确认了 kube-proxy 模式:iptables 模式下无需配置 strictARP
  3. 安装了 MetalLB:通过官方 Manifest 部署了 controller 和 speaker
  4. 配置了 IP 地址池和 L2Advertisement:为负载均衡 Service 提供可分配的 IP 范围
  5. 测试了 LoadBalancer Service :验证了 EXTERNAL-IP 从 pending 变为实际 IP

感谢阅读

相关推荐
troy12816 小时前
阿里云 vs 谷歌云:Kubernetes 部署深度对比分析
阿里云·kubernetes·云计算
谢亮_vipxieliang19 小时前
容器排障实战手册:从日志到内核的分层排障
docker·云原生·容器·eureka
wzq11_6661 天前
Kubernetes集群——Pod篇
云原生·容器·kubernetes
wzq11_6661 天前
Kubernetes集群——命令篇
云原生·容器·kubernetes
小白的码BUG之路1 天前
Docker -- 构建ruoyi-gateway镜像
docker·容器·gateway
小白的码BUG之路1 天前
Docker -- 构建ruoyi-system镜像
运维·docker·容器
LRL_1 天前
【云原生】Oracle Linux 9.6 离线(Air-Gapped)环境下安装 Longhorn 及其底层依赖(iSCSI/NFS)完全指南
linux·云原生·oracle
小白的码BUG之路1 天前
Docker -- 构建redis镜像
运维·docker·容器
江湖有缘1 天前
Docker实战 | 使用Docker部署EspoCRM开源客户关系管理平台
docker·容器·开源