k8s生产流量走向
客户端 → http://www.baidu.com ↓ [External IP] ← MetalLB 分配 ↓ Ingress Controller(其 Service 为 LoadBalancer) ↓(根据 Host 路由) Service A → Pod A Service B → Pod B
如上图所示:
-
外部流量入口(四层):你部署了 Nginx Ingress Controller,并把它的 Service 类型设为
LoadBalancer。MetalLB 检测到后,会从你的 IP 池里分配一个固定的公网/内网 IP(比如192.168.1.100)给这个 Service。此时,所有外部请求都先打到这个 IP。 -
七层路由(Ingress 规则):Nginx Ingress Controller 接收到请求后,根据你定义的 Ingress 规则(比如
domain: api.example.com),将请求转发给集群内部对应的 Service。 -
内部服务发现(ClusterIP):集群内后端的每一个业务 Service,类型都是 ClusterIP(默认类型)。它们没有分配 MetalLB 的 IP,只在集群内部虚拟网络中可达。
-
Pod 间互访:Pod 与 Pod 之间直接通过 ClusterIP 或 Kubernetes 的内部 DNS(如
service-a.default.svc.cluster.local)进行通信。
🎯 这样设计为什么“节省资源”且“最优”?
你的判断非常准确,主要体现在以下两点:
-
节省稀缺的 IP 地址:如果你有 50 个微服务,不需要 MetalLB 分配 50 个外部 IP,只需要 1 个 IP 给 Ingress Controller。其余 49 个服务都用 ClusterIP(内部虚拟 IP,不占用外部网络资源)。
-
职责分离(解耦):
-
Ingress (L7):专注处理你的 HTTP 域名、SSL 证书、限流、灰度发布。
-
ClusterIP (L4 内部):专注做集群内高效的服务发现和负载均衡(由 kube-proxy 或 Cilium 等 CNI 处理)。
-
非 HTTP 服务:如果未来有 TCP/UDP 服务(如 MySQL、Kafka)需要固定 IP 直连,你再单独给它开一个
LoadBalancer类型的 Service,MetalLB 会再分配另一个独立 IP。
-
⚠️ 唯一需要留意的细节
在你这个架构中,有一个关键点需要确认:Ingress Controller 的 externalTrafficPolicy 设置。
-
如果你追求保留客户端真实 IP,需要将 Ingress Controller 的 Service 设为
externalTrafficPolicy: Local。 -
但这可能导致流量在节点间负载不均衡。如果集群规模大,通常建议搭配 NGINX 的 Proxy Protocol 或使用 MetalLB 的 BGP 模式来解决,这是一个进阶优化点,当前阶段知晓即可。
这是 Ingress Controller(以 Nginx 为例)配套的 Service YAML。它的核心作用就是声明一个 LoadBalancer 类型的服务,让 MetalLB 能够为 Ingress Controller 分配一个固定的外部 IP(比如你提到的 10.10.10.10)。
pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: menhu
namespace: default
spec:
replicas: 2 # 2个副本保证高可用
selector:
matchLabels:
app: menhu
template:
metadata:
labels:
app: menhu
spec:
containers:
- name: menhu-container
image: nginx:latest # 请替换为你自己的业务镜像
ports:
- containerPort: 80
# 模拟一个简单的首页,方便测试
command: ["/bin/sh"]
args: ["-c", "echo 'Hello from menhu backend' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"]
---
apiVersion: v1
kind: Service
metadata:
name: menhu-service # 这个name就是Ingress要引用的
namespace: default
spec:
selector:
app: menhu
ports:
- protocol: TCP
port: 80 # Service监听的端口
targetPort: 80 # Pod容器的端口
type: ClusterIP # 集群内部访问,不占用MetalLB IP
Ingress 路由规则 :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: menhu-ingress
namespace: default
annotations:
# 如果你的 Ingress Controller 是 Nginx,可以加些常用注解(可选)
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # 指定你使用的 Ingress Controller 类名,如果是其他如 traefik 需修改
rules:
- host: www.shuai.com # 【关键】绑定的域名
http:
paths:
- path: / # 匹配所有路径
pathType: Prefix
backend:
service:
name: menhu-service # 对应上面 ClusterIP Service 的名字
port:
number: 80
Ingress Service
完整的 Service YAML
yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller # Service 名称,与 Ingress Controller 部署匹配
namespace: ingress-nginx # 必须与 Ingress Controller 在同一命名空间
spec:
type: LoadBalancer # 【关键】声明为 LoadBalancer 类型,触发 MetalLB 分配 IP
externalTrafficPolicy: Cluster # 流量策略,Cluster 模式保持节点间负载均衡
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
- name: https
port: 443
protocol: TCP
targetPort: 443
selector:
# 这些标签必须与 Ingress Controller Pod 的标签完全匹配
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
将上述内容保存为 ingress-nginx-service.yaml 后,执行 kubectl apply -f ingress-nginx-service.yaml 即可部署。
如何让 MetalLB 分配你指定的 10.10.10.10?
默认情况下,MetalLB 会从你配置的 IP 池中自动分配一个可用 IP。如果你需要固定使用 10.10.10.10,只需在 Service 的 metadata.annotations 中添加一行注解即可:
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
annotations:
metallb.universe.tf/loadBalancerIPs: "10.10.10.10" # 指定 MetalLB 分配的 IP
添加此注解后,MetalLB 会优先尝试分配这个 IP。部署后,你可以通过以下命令验证:
kubectl get svc -n ingress-nginx ingress-nginx-controller
如果一切正常,EXTERNAL-IP 列就会显示 10.10.10.10
总结:
-
MetalLB (L4负载均衡):它的使命很纯粹,就是监听所有
type: LoadBalancer的 Service,并从你预先定义的 IP 池里分配一个外部 IP。它通过 ARP (L2模式) 或 BGP 协议将这个 IP “宣告”到你的网络中,让外部流量能顺利进入集群。可以说,MetalLB 就是你在自建机房的“云负载均衡器”。 -
Ingress Controller (L7路由网关):它是真正的“流量大脑”。它本身是一个运行在集群内的 Pod(如 Nginx Ingress),监听 Ingress 资源的变化。当请求到达 MetalLB 分配的 IP 时,Ingress Controller 会根据
Host(域名) 和Path(路径) 将请求精准地转发到后端的ClusterIPService。 -
ClusterIP Service (集群内服务发现):这是 Kubernetes 默认的 Service 类型。它只为集群内部提供虚拟 IP 和负载均衡,不占用任何外部 IP 资源,是 Ingress Controller 与业务 Pod 之间的桥梁。

浙公网安备 33010602011771号