Kubernetes Service 访问 Pod 的完整流程
## 🚀 **通过 Kubernetes Service 访问 Pod 的完整流程(发包 + 回包)**
👉 本流程涵盖:
✅ **通过 ClusterIP 访问**
✅ **通过 NodePort 访问**
✅ **通过 LoadBalancer 访问**
✅ 涉及完整的 iptables 规则、Flannel VXLAN 封装和解析
---
## 🌟 **Kubernetes Service 访问模式总览**
| 访问模式 | 描述 | 典型端口 | 涉及封装 |
|----------|-------|----------|----------|
| **ClusterIP** | 通过 Service IP 访问 | 通过集群内部 IP | 不封装 |
| **NodePort** | 通过节点 IP + 端口访问 | 外部访问节点的端口 | VXLAN(跨节点) |
| **LoadBalancer** | 通过外部 IP 访问 | 负载均衡器 → NodePort | VXLAN(跨节点) |
---
## ✅ **1. ClusterIP 访问完整路径**
👉 **ClusterIP 只在集群内部可见**
👉 通过 iptables 的 `KUBE-SERVICES` 和 `KUBE-MARK-MASQ` 规则进行转发
---
### 🚀 **发包路径(ClusterIP)**
```text
[Kubernetes Pod A]
│
▼
【raw 表】 → PREROUTING 链 → 连接跟踪初始化(conntrack)
│
▼
【mangle 表】 → PREROUTING 链 → 标记和修改
│
▼
【nat 表】 → PREROUTING 链 → 通过 KUBE-SERVICES 转发到 Pod
│
▼
【filter 表】 → INPUT 链 → 规则匹配
│
▼
[目标 Pod B] → # Pod B 接收数据包
```
---
### 🚀 **回包路径(ClusterIP)**
```text
[目标 Pod B]
│
▼
【mangle 表】 → OUTPUT 链 → 标记和修改
│
▼
【nat 表】 → POSTROUTING 链 → SNAT
│
▼
[物理机路由表] → 直接路由回源 Pod
│
▼
[Kubernetes Pod A] → # Pod A 接收回包
```
---
### 🏆 **完整 iptables 规则(ClusterIP)**
👉 **1. 在 `nat` 表的 `PREROUTING` 链中创建 Service 规则**
```bash
iptables -t nat -A KUBE-SERVICES -d 10.96.0.10/32 -p tcp --dport 80 -j KUBE-MARK-MASQ
iptables -t nat -A KUBE-SERVICES -d 10.96.0.10/32 -p tcp --dport 80 -j DNAT --to-destination 10.244.1.5:80
```
👉 **2. 在 `nat` 表的 `POSTROUTING` 链中为回包创建 SNAT**
```bash
iptables -t nat -A POSTROUTING -p tcp --sport 80 -j MASQUERADE
```
---
## ✅ **2. NodePort 访问完整路径**
👉 **NodePort 通过节点 IP + 映射端口访问**
👉 **流量会被路由到目标 Pod**
👉 需要通过 VXLAN 进行封装(如果跨节点)
---
### 🚀 **发包路径(NodePort)**
```text
[外部客户端]
│
▼
【raw 表】 → PREROUTING 链 → 连接跟踪初始化
│
▼
【mangle 表】 → PREROUTING 链 → 标记和修改
│
▼
【nat 表】 → PREROUTING 链 → KUBE-SERVICES 映射到 Pod
│
▼
【filter 表】 → FORWARD 链 → 规则匹配
│
▼
[目标 Pod B] → # Pod B 接收数据包
```
---
### 🚀 **回包路径(NodePort)**
```text
[目标 Pod B]
│
▼
【mangle 表】 → OUTPUT 链 → 标记和修改
│
▼
【nat 表】 → POSTROUTING 链 → SNAT + VXLAN 封装
│
▼
[flannel0(VXLAN 隧道)] → 封装
│
▼
[物理机路由表] → 发送回客户端
│
▼
[外部客户端] → # 接收回包
```
---
### 🏆 **完整 iptables 规则(NodePort)**
👉 **1. 在 `nat` 表中为 NodePort 设置规则**
```bash
iptables -t nat -A KUBE-SERVICES -d 192.168.1.100 -p tcp --dport 30080 -j KUBE-MARK-MASQ
iptables -t nat -A KUBE-SERVICES -d 192.168.1.100 -p tcp --dport 30080 -j DNAT --to-destination 10.244.1.5:80
```
👉 **2. 在 `nat` 表中为回包设置 SNAT(跨节点需要 MASQUERADE)**
```bash
iptables -t nat -A POSTROUTING -o flannel.1 -p tcp --sport 80 -j MASQUERADE
```
---
## ✅ **3. LoadBalancer 访问完整路径**
👉 **LoadBalancer 通过外部负载均衡器创建 IP**
👉 **流量通过 NodePort 机制转发到目标 Pod**
---
### 🚀 **发包路径(LoadBalancer)**
```text
[外部客户端]
│
▼
[负载均衡器]
│
▼
[NodePort]
│
▼
[目标 Pod B] → # Pod B 接收数据包
```
---
### 🚀 **回包路径(LoadBalancer)**
```text
[目标 Pod B]
│
▼
【nat 表】 → POSTROUTING 链 → SNAT
│
▼
[物理机路由表] → 发送回负载均衡器
│
▼
[外部客户端] → # 接收回包
```
---
### 🏆 **完整 iptables 规则(LoadBalancer)**
👉 **1. 在 `nat` 表中设置 LoadBalancer IP**
```bash
iptables -t nat -A KUBE-SERVICES -d 192.168.1.200 -p tcp --dport 80 -j KUBE-MARK-MASQ
iptables -t nat -A KUBE-SERVICES -d 192.168.1.200 -p tcp --dport 80 -j DNAT --to-destination 10.244.1.5:80
```
👉 **2. 在 `nat` 表中设置 SNAT**
```bash
iptables -t nat -A POSTROUTING -o flannel.1 -p tcp --sport 80 -j MASQUERADE
```
---
## 🎯 **完整通信链路总结**
| 访问类型 | 访问路径 | SNAT 方式 | 连接跟踪 | 规则链 |
|----------|-----------|------------|------------|------------|
| ClusterIP | Pod → Pod | ❌ | ✅ | PREROUTING → INPUT |
| NodePort | 客户端 → Pod | ✅(MASQUERADE) | ✅ | PREROUTING → FORWARD |
| LoadBalancer | 客户端 → 负载均衡器 → Pod | ✅(MASQUERADE) | ✅ | PREROUTING → FORWARD |
---
## 🚀 **完整通信链路,搞定所有 Service 场景!** 😎
https://luckymrwang.github.io/2021/02/20/探究K8S-Service内部iptables路由规则/
https://www.processon.com/view/63dd115310f396072768f871
https://zhuanlan.zhihu.com/p/559421839
https://www.ljh.cool/39959.html
https://www.danielhu.cn/k8s-network-flannel/
浙公网安备 33010602011771号