在私有云中部署 Kubernetes,很多人都会遇到这样一个问题:
如何为集群中的服务提供一个"稳定、高可用、统一"的对外出口?
在公有云中,我们可以依赖云厂商的负载均衡(LoadBalancer),但在私有云环境下,这种"即插即用"的体验往往不存在。本文将介绍如何使用 MetalLB + Traefik 搭建一个 私有云中的高可用 Ingress 出口解决方案 ,配合绑定 EIP(公网 IP) ,实现统一接入、统一出口的目标。
一、问题背景:私有云出入口困境
在私有云或裸机环境中,Kubernetes 的 LoadBalancer
类型 Service 默认不可用,因为它依赖云厂商的 LB 实现。
很多人选择:
- 使用 NodePort 手动映射端口
- 或者在边界节点上用 Nginx / HAProxy 暴露服务
但这些方式存在明显问题:
- 端口管理混乱:每个服务都要维护不同端口
- 公网 IP 浪费或缺失:多个服务需要多个 IP?
- 缺乏统一入口:业务团队难以自助暴露服务
于是,我们希望:
在私有云环境下,实现像云厂商一样的 LoadBalancer 效果,配合 Ingress 统一出入口,用一个 EIP 为所有服务提供统一公网访问能力。
二、整体架构方案:MetalLB + Traefik + EIP
🌐 方案目标:
- 为集群提供一个稳定公网 IP(EIP)
- 使用 IngressClass 将所有流量统一交由 Traefik 管理
- 支持 HTTPS、认证、中间件等高级特性
- 简洁、高效、便于维护和扩展
🧱 架构图:

三、实战部署步骤
1. 安装 MetalLB
MetalLB 是专为私有云设计的负载均衡器插件,支持 L2 和 BGP 模式。
✅ 安装:
bash
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml
✅ 配置 IP 地址池(包含你预先绑定的公网 IP):
yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: public-ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.100/32 # 示例IP,建议使用你绑定的公网IP
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2adv
namespace: metallb-system
spec:
ipAddressPools:
- public-ip-pool
⚠️ 若使用的是真实公网 IP,请确保网络层允许 ARP 广播,并绑定到部署节点。
2. 部署 Traefik IngressController
推荐使用 Helm 部署,便于自定义配置。
bash
git clone https://github.com/traefik/traefik-helm-chart
vim /values/value.yaml
配置文件示例:
yaml
# value.yaml
ingressRoute:
dashboard:
enabled: false
ports:
web:
port: 8000
nodePort: 31800
websecure:
port: 8443
nodePort: 31443
service:
enabled: true
type: NodePort
logs:
general:
level: DEBUG
创建命名空间并安装
bash
kubectl create ns traefik
helm install -n traefik traefik ./traefik -f values/value.yaml
✅ 创建 Dashboard IngressRoute:
yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: dashboard
namespace: traefik
spec:
entryPoints:
- web
routes:
- match: (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
kind: Rule
services:
- name: api@internal
kind: TraefikService
部署后,可通过 kubectl get svc -n traefik
验证 EXTERNAL-IP 是否为你配置的公网 IP。
访问:http://your-ip:[nodeport]/dashboard/
3. 暴露服务(Ingress 示例)
以一个示例服务为例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
namespace: default
annotations:
kubernetes.io/ingress.class: traefik-public
spec:
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 80
配置好 DNS 后,即可通过公网 IP 访问 https://demo.example.com
。
四、方案优势与扩展
✅ 一公网 IP 统一出口
避免为每个服务申请公网端口或公网 IP,资源集中管理。
✅ 高度可扩展
Traefik 支持中间件链、重定向、认证、限流、WAF 插件等,可轻松拓展功能。
✅ 云原生对接友好
IngressClass 标准化,便于 CI/CD 系统动态生成 ingress 资源。
✅ 私有云资源充分利用
MetalLB 不依赖外部厂商,完全可控、可落地、适合裸金属场景。
五、实战踩坑 & Tips
-
MetalLB 无法绑定公网 IP?
- 检查你的物理网络是否允许 ARP 广播
- 确保公网 IP 已正确绑定到宿主机/交换机
-
服务未能暴露?
- 查看 Traefik 日志,常见问题为证书问题或路径规则错误
- 确认 Ingress 资源绑定了正确的 ingressClass
-
证书签发建议结合 cert-manager
- 自动化 HTTPS,提升安全性和用户体验
六、总结
这套基于 MetalLB + Traefik Ingress 的出入口架构,在私有云场景下极具实用价值。
- 轻量、易用、原生支持 Kubernetes
- 高度可扩展,适配未来云原生演进
- 满足"一个公网 IP 统一出口"的核心诉求
如果你正困扰于私有云中的服务对外访问问题,不妨尝试这一套方案,让你的集群具备像云上一样的公网能力。