1. 概述
在 Kubernetes 中,使用 LoadBalancer
类型的 Service 是将应用暴露给外部网络的标准方式。当需要为每个服务分配独立 IP 地址时,首选 LoadBalancer
类型。
在公有云平台上,LoadBalancer
服务会自动创建对应的负载均衡器。但在本地开发工具 Minikube 中,该功能是通过模拟实现的,默认情况下,External IP会显示为 <pending>
。
本文将介绍两种解决 Minikube 中 LoadBalancer
服务 External IP 显示为 pending 的方法。
2. 准备测试环境
为了更好地演示,我们先创建一个测试命名空间和部署一个 Redis Pod。
$ kubectl create ns service-demo
namespace/service-demo created
部署 Redis:
$ kubectl create deploy redis --image=redis:alpine -n service-demo
deployment.apps/redis created
确认 Pod 正常运行:
$ kubectl get pods -n service-demo
NAME READY STATUS RESTARTS AGE
redis-8648874d67-d66wz 1/1 Running 0 35s
准备好资源后,我们开始尝试暴露服务并解决 External IP 显示为 pending 的问题。
3. 使用 Minikube Tunnel 暴露服务
3.1 创建 LoadBalancer 类型 Service
使用 kubectl expose
命令创建一个类型为 LoadBalancer
的 Service:
$ kubectl expose deploy redis --port 6379 --type LoadBalancer -n service-demo
service/redis exposed
查看服务状态:
$ kubectl get service -n service-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis LoadBalancer 10.103.33.106 <pending> 6379:31794/TCP 12s
此时 EXTERNAL-IP
显示为 <pending>
,这是因为 Minikube 默认不会自动分配外部 IP。
3.2 启动 Minikube Tunnel
在新终端中运行以下命令:
$ minikube tunnel
Status:
machine: minikube
pid: 9325
route: 10.96.0.0/12 -> 192.168.49.2
minikube: Running
services: [redis]
errors:
minikube: no errors
router: no errors
loadbalancer emulator: no errors
此时,Minikube 会模拟负载均衡器并分配 IP 地址。
切换回原终端查看服务状态:
$ kubectl get service -n service-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis LoadBalancer 10.103.33.106 10.103.33.106 6379:31794/TCP 53s
✅ External IP 已成功分配。
3.3 验证访问
使用 redis-cli
测试外部访问:
$ redis-cli -h 10.103.33.106 PING
PONG
✅ Redis 成功响应。
3.4 清理资源
回到运行 minikube tunnel
的终端,按下 Ctrl + C
停止隧道。
删除服务:
$ kubectl delete svc redis -n service-demo
service "redis" deleted
4. 使用 MetalLB 暴露服务
4.1 启用 MetalLB 插件
Minikube 支持通过插件启用 MetalLB,这是一个开源的负载均衡实现。
启用插件:
$ minikube addons enable metallb
查看插件状态:
$ minikube addons list
确保 metallb
插件状态为 enabled
。
4.2 配置 MetalLB IP 地址池
获取 Minikube 节点 IP:
$ minikube ip
192.168.49.2
配置 MetalLB 的 IP 地址池:
$ minikube addons configure metallb
-- Enter Load Balancer Start IP: 192.168.49.10
-- Enter Load Balancer End IP: 192.168.49.20
▪ Using image quay.io/metallb/speaker:v0.9.6
▪ Using image quay.io/metallb/controller:v0.9.6
✅ metallb was successfully configured
⚠️ 注意:配置的 IP 地址必须和 Minikube 所在子网匹配。
4.3 创建 LoadBalancer 类型 Service
再次创建 Service:
$ kubectl expose deploy redis --port 6379 --type LoadBalancer -n service-demo
service/redis exposed
查看服务状态:
$ kubectl get service -n service-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis LoadBalancer 10.102.24.187 192.168.49.10 6379:31569/TCP 10s
✅ External IP 成功分配为配置的地址池中的 IP。
4.4 验证访问
$ redis-cli -h 192.168.49.10 PING
PONG
✅ Redis 成功响应。
5. 清理环境
删除整个命名空间即可完成清理:
$ kubectl delete ns service-demo
namespace "service-demo" deleted
⚠️ 注意:这种方式适用于测试环境,生产环境中应避免直接删除命名空间,建议逐个删除资源。
6. 总结
本文介绍了两种解决 Minikube 中 LoadBalancer
类型 Service 外部 IP 显示为 pending 的方法:
✅ 方法一:使用 minikube tunnel
命令模拟负载均衡器,自动分配 IP。
✅ 方法二:启用并配置 metallb
插件,手动指定 IP 地址池。
方法 | 是否需要配置 | 是否支持多服务 | 适用场景 |
---|---|---|---|
minikube tunnel |
否 | 否 | 快速测试单个服务 |
metallb |
是 | 是 | 多服务、更接近生产环境 |
选择哪种方式取决于你的使用场景。如果是临时测试,推荐使用 minikube tunnel
;如果是构建本地开发环境或 CI 流程,建议配置 metallb
。