K8s Lab 把当前仓库文档整理成一个可阅读的网页站点

Repository Reading Site

第四课:Kubernetes 网络、协议分层、VXLAN/IPIP/WireGuard 原理与排障

原因不是网络“命令多”,而是它天然跨很多层: 如果你没有分层模型,就会把所有问题都混在一起,比如: 这些看起来都叫“网络问题”,但它们常常根本不是同一层的问题。 所以这一课的目标,不是让你背更多网络名词,而是先帮你建立一个**能长期用来排障和架构设计的网络脑图**。 --- 1. 什么叫几层网络,为什么要分层 2. Pod IP、Node IP、Servic

Markdown04-第四课-Kubernetes网络与协议原理.md2026年4月9日 17:59

第四课:Kubernetes 网络、协议分层、VXLAN/IPIP/WireGuard 原理与排障

先说一句实话:网络是 Kubernetes 里最容易把人学懵的部分

原因不是网络“命令多”,而是它天然跨很多层:

  • Linux 网卡与路由
  • 容器网络命名空间
  • CNI
  • Pod IP
  • Service 虚拟 IP
  • kube-proxy
  • DNS
  • Ingress
  • overlay 隧道
  • 节点之间的 underlay 网络

如果你没有分层模型,就会把所有问题都混在一起,比如:

  • 服务不通
  • DNS 不通
  • Pod 能 ping 但不能 curl
  • 同节点能通,跨节点不通
  • Pod 访问 Service 通,外部访问不通

这些看起来都叫“网络问题”,但它们常常根本不是同一层的问题。

所以这一课的目标,不是让你背更多网络名词,而是先帮你建立一个能长期用来排障和架构设计的网络脑图


这节课会回答什么

  1. 什么叫几层网络,为什么要分层
  2. Pod IP、Node IP、Service IP、DNS、Ingress 分别属于哪一层
  3. 你的集群现在实际使用了什么网络方案
  4. 什么是 IPIP、VXLAN、WireGuard、BGP,它们分别解决什么问题
  5. Service 的 ClusterIP 为什么能工作
  6. Headless Service 和普通 Service 的区别是什么
  7. iptables 模式的 kube-proxy 到底做了什么
  8. 遇到网络问题时,应该优先用哪些命令排查

先建立一个“够用而不绕”的网络分层模型

你不需要一开始就背完整 OSI 七层的每个术语细节。

对 Kubernetes 工程实践来说,最实用的是先抓住这四层:

  1. 二层 L2:局域网寻址与转发
  2. 三层 L3:IP 和路由
  3. 四层 L4:TCP / UDP 和端口
  4. 七层 L7:HTTP / DNS / TLS / Ingress 这些应用协议

为什么我直接跳过 1、5、6 层?

因为在大多数 Kubernetes 网络排障里,最常用的思考框架就是:

  • 这个问题是 L2/L3 的路径问题?
  • 还是 L4 的端口/连接问题?
  • 还是 L7 的协议、域名、路由问题?

这比死背 OSI 更有工程价值。


L2:二层网络到底在解决什么

二层的核心问题

二层关心的是:

在同一个局域网里,怎么把帧送到正确的网卡。

你可以把它理解成“同一个交换机/同一个广播域内的送货系统”。

典型概念

  • MAC 地址
  • Ethernet 帧
  • ARP
  • bridge

二层最典型的两个问题

1. 我知道对方的 IP,但不知道它的 MAC

这时候通常靠 ARP:

  • “谁是 192.168.1.10?”

2. 这两个对象是否在同一个二层广播域

如果在同一个二层网络里,可以直接二层送达。 如果不在,就必须交给三层路由。

在 Kubernetes 里,二层最容易出现在哪

  • 同节点 Pod 之间
  • Linux bridge / veth 对
  • 某些 overlay 封装场景里模拟二层广播域

L3:三层网络是 Kubernetes 网络的真正主战场

三层的核心问题

三层关心的是:

一个 IP 包怎么从源地址走到目的地址。

这里的核心概念是:

  • IP 地址
  • 子网
  • 路由表
  • 下一跳
  • 路由协议

你要记住的一句话

二层像“同小区送快递”,三层像“跨城市路线规划”。

在 Kubernetes 里,三层几乎无处不在

  • 节点 IP
  • Pod IP
  • Service IP
  • 节点之间的路由
  • overlay 隧道
  • CNI 的跨节点转发

Kubernetes 网络问题,绝大多数最终都会落回三层判断。


L4:四层解决的是端口与连接语义

四层最重要的两个协议

  • TCP
  • UDP

TCP 的特点

  • 面向连接
  • 可靠传输
  • 有重传、顺序、流控
  • 开销更大,但适合 Web、数据库、API

UDP 的特点

  • 无连接
  • 不保证到达、不保证顺序
  • 开销小、延迟低
  • 常用于 DNS、实时音视频、隧道封装

在 Kubernetes 里常见的四层问题

  • 端口没监听
  • Service 端口映射错了
  • UDP 和 TCP 搞混
  • 探针访问的是错误端口

L7:七层是“协议语义”和“业务路由”

七层不是在关心“包怎么走”,而是在关心:

这个请求从业务角度是什么意思?

常见七层协议

  • HTTP / HTTPS
  • DNS
  • gRPC
  • MQTT

在 Kubernetes 里最常见的七层网络对象

  • Ingress
  • Gateway API
  • 反向代理
  • Host / Path 路由
  • TLS 终结

为什么要把 L4 和 L7 分开

因为:

  • Service 更偏 L4
  • Ingress 更偏 L7

这也是为什么 Service 主要按:

  • IP + 端口

来转发,而 Ingress 才会看:

  • 域名
  • URL 路径

把这四层映射到你当前集群

现在开始把抽象分层和你这套真实集群绑起来。

1. 节点工作地址层

你的节点工作地址是:

  • 10.10.0.1
  • 10.10.0.2
  • 10.10.0.3
  • 10.10.0.4
  • 10.10.0.5

这是一层非常关键的三层网络:

  • 通过 WireGuard 建立
  • 作为节点彼此可达的统一工作地址

2. Pod 网络层

你当前 Pod 网段是:

  • 10.244.0.0/16

每个 Pod 都有一个 IP,例如:

  • hello 服务后端 Pod:10.244.119.226
  • hello 服务另一个后端:10.244.147.106
  • net-debug10.244.169.9

3. Service 网络层

你的 Service ClusterIP 网段是:

  • 10.96.0.0/12

例如:

  • Kubernetes API Service:10.96.0.1
  • CoreDNS:10.96.0.10
  • 你的 hello-svc10.98.52.186

4. DNS 服务层

Pod 的 /etc/resolv.conf 里,我们实际看到了:

search learn-k8s.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

这说明:

  • Pod 的 DNS 服务器是 CoreDNS 的 Service IP
  • Pod 在解析短域名时,会自动补齐集群搜索域

你这套集群当前到底用了什么网络方案

这是这节课最关键的现实基础。

我们实际查到了以下事实:

1. kube-proxy 使用 iptables 代理模式

证据:

  • kube-proxy ConfigMap 里 mode: ""
  • kube-proxy 日志明确写着:
Using iptables Proxier

这说明:

  • Service 的 ClusterIP 转发不是靠真正绑定一个虚拟网卡地址
  • 而是靠 Linux 内核里的 iptables nat 规则进行 DNAT

2. Calico 当前是 IPIP,不是 VXLAN

证据链有三条:

calico-node DaemonSet 环境变量

我们实际看到了:

  • CALICO_IPV4POOL_IPIP=Always
  • CALICO_IPV4POOL_VXLAN=Never

IPPool 对象

我们实际看到了:

cidr: 10.244.0.0/16
ipipMode: Always
vxlanMode: Never
natOutgoing: true

节点网络接口与路由

在节点上我们看到了:

  • tunl0
  • 没有任何 vxlan 设备
  • 跨节点 Pod 网段路由通过 tunl0

所以结论非常明确:

你的集群当前使用的是 Calico 的 IP-in-IP(IPIP)模式,不是 VXLAN 模式。

3. 你的集群同时还用了 WireGuard

但注意:

  • WireGuard 不是用来做 Pod Overlay 的主机制
  • 它是用来做节点之间统一工作内网的

这意味着你的集群是一个非常有教学价值的“双层网络”案例:

  1. 节点通信层:WireGuard
  2. Pod 跨节点 overlay 层:Calico IPIP

这套双层网络到底是什么结构

你可以把它想成:

第一层:节点 underlay

Node A (10.10.0.2)  <--WireGuard-->  Node B (10.10.0.5)

这是节点彼此可达的基础工作网络。

第二层:Pod overlay

Pod 10.244.119.226  --IPIP-->  Pod 10.244.147.106

但这个 IPIP 封装后的外层目标地址,不是公网 IP,而是:

  • 10.10.0.5

也就是节点的 WireGuard 地址。

你的真实证据

我们在 us590068728056 节点上实际看到了:

10.244.147.106 via 10.10.0.5 dev tunl0 src 10.244.119.192
10.10.0.5 dev wg0 src 10.10.0.2

这句非常重要。

它说明:

  1. 如果目标是远端 Pod 10.244.147.106
  2. 本机先通过 tunl0 做 IPIP 隧道
  3. IPIP 的对端节点工作地址是 10.10.0.5
  4. 10.10.0.5 这条路本身又通过 wg0

也就是说:

Pod 跨节点流量先走 Calico 的 IPIP overlay,再借助 WireGuard 节点网络作为外层传输路径。

这是一条典型的“overlay 套 underlay”的真实路径。


Pod 到 Pod,同节点和跨节点到底有什么区别

同节点 Pod 通信

如果两个 Pod 在同一节点,通常不需要跨节点隧道。

数据路径更像:

  • Pod 网卡 eth0
  • veth pair
  • 宿主机上的 cali* 接口
  • 本地路由直接送到同节点另一个 Pod

这种路径通常开销较小。

跨节点 Pod 通信

如果两个 Pod 在不同节点,数据包必须跨节点。

在你的集群里,路径更像:

  1. 源 Pod 发送目标为远端 Pod IP 的包
  2. 宿主机路由表发现目标网段在远端节点
  3. 通过 tunl0 做 IPIP 封装
  4. 外层目标是远端节点的 10.10.0.x
  5. 再通过 wg0 发送到远端节点
  6. 远端节点解封装
  7. 再路由到目标 Pod

这就是为什么跨节点流量永远比同节点流量更复杂。


tunl0 是什么,为什么你的节点上都有它

在你的节点上,我们实际看到:

tunl0@NONE       UNKNOWN        10.244.119.192/32

或:

tunl0@NONE       UNKNOWN        10.244.169.0/32

tunl0 的作用

这是 Linux 的 IPIP 隧道接口。

如果 Calico 使用 IPIP,那么跨节点 Pod 流量会借助它进行封装和转发。

为什么它的地址看起来像 Pod 网段里的地址

因为它本来就是 Pod overlay 网络的一部分。

你可以理解为:

  • wg0 代表节点互联 underlay
  • tunl0 代表 Pod 跨节点 overlay

proto bird 说明了什么

在节点路由表里,我们还看到类似:

10.244.147.64/26 via 10.10.0.5 dev tunl0 proto bird onlink
10.244.169.0/26 via 10.10.0.4 dev tunl0 proto bird onlink

bird 是什么

BIRD 是一个 Linux 路由守护进程。

在 Calico 的 BGP 模式里,它负责:

  • 交换路由
  • 把“哪个节点负责哪个 Pod 网段”这件事学到本机路由表

这说明了什么

这说明你的集群网络不只是“靠一堆静态路由魔法跑起来”,而是:

  • Calico 节点代理通过 BGP 路由学习和发布
  • 最终让 Linux 路由表知道远端 Pod 网段该怎么走

注意:BGP 不是封装协议

这一点非常重要。

很多初学者会把:

  • BGP
  • VXLAN
  • IPIP

混成一类。

其实它们角色完全不同:

  • BGP:路由协议,告诉大家“路怎么走”
  • IPIP / VXLAN:封装/隧道方式,决定“包怎么包起来过去”

VXLAN 到底是什么

用户特别点名要讲这个,我们就讲透一点。

VXLAN 的全称

  • Virtual eXtensible LAN

它在做什么

VXLAN 的核心思想是:

在三层 IP 网络之上,模拟一个二层广播域。

更直白地说:

  • 你把一个以太网帧包起来
  • 再塞进 UDP 包
  • 再跑在普通 IP 网络上

所以它常被描述为:

L2 over L3 over UDP

常用端口

  • UDP 4789

VXLAN 的优点

  • 跨三层网络部署方便
  • 云环境里通常更友好
  • 不要求底层网络支持大规模二层扩展
  • 对很多云厂商网络和防火墙更友好,因为它是 UDP

VXLAN 的缺点

  • 有额外头部开销
  • 会降低有效 MTU
  • 调试比纯路由更复杂
  • 对高性能场景会有一定代价

什么时候适合 VXLAN

  • 多子网、跨节点、底层网络不想跑 BGP
  • 云环境里做 overlay 很常见
  • 需要比较“通用”的跨网络封装方案

什么时候 VXLAN 不是最佳选择

  • 你非常在意报文开销和性能
  • 底层网络本身已经能直接路由 Pod 网段
  • 你愿意运行更原生的路由方案

IPIP 到底是什么

IPIP 的全称

  • IP in IP

它在做什么

把一个 IP 包直接封装进另一个 IP 包里。

所以它更像:

L3 over L3

和 VXLAN 最大不同在于:

  • VXLAN 是把二层帧塞进 UDP
  • IPIP 是把三层包塞进三层包

IPIP 的优点

  • 相对简单
  • 头部开销通常比 VXLAN 更小
  • 对纯 IPv4 Pod overlay 场景很直接

IPIP 的缺点

  • 主要用于 IPv4
  • 某些网络设备或防火墙可能不喜欢 IP 协议 4
  • 不具备 VXLAN 那种“模拟二层广播域”的语义

什么时候适合 IPIP

  • Pod 网络本来就是纯三层思路
  • 环境对 IPIP 兼容性没问题
  • 想要比 VXLAN 更轻一些的 L3 overlay

你的集群为什么是 IPIP

因为当前 Calico 明确配置的是:

  • ipipMode: Always
  • vxlanMode: Never

这就是你现在真实集群的选择。


WireGuard 又是什么,和 VXLAN/IPIP 是什么关系

WireGuard 的本质

WireGuard 是:

一个加密的三层 VPN 隧道协议

它通过 UDP 传输,核心目标是:

  • 节点间安全通信
  • 配置简单
  • 性能高

它和 VXLAN/IPIP 的关系

它们不完全是同一维度的东西。

VXLAN / IPIP

更偏:

  • Pod overlay 的封装手段

WireGuard

更偏:

  • 节点间 underlay / 安全互联手段

在你的集群里,它们如何配合

你的集群里:

  • 节点之间先有 WireGuard 内网 10.10.0.0/24
  • Pod 跨节点再走 Calico IPIP

所以这里不是“二选一”,而是“上下两层同时存在”。

WireGuard 的优点

  • 加密
  • 实现简单
  • 性能不错
  • 很适合跨公网、跨机房的节点互联

WireGuard 的限制

  • 不是 Kubernetes Service 负载均衡方案
  • 不是 DNS 方案
  • 不是 Ingress 方案
  • 不是直接替代 kube-proxy 的方案
  • 需要考虑 MTU 和密钥管理

BGP 是什么,为什么它和 VXLAN/IPIP 不是一回事

BGP 的角色

Border Gateway Protocol,本质是:

路由信息怎么传播。

它解决的是:

  • 哪个网段从哪里可达

不是:

  • 包怎么封装

用一个最简单的类比

  • BGP:像导航系统告诉你“去上海走哪条高速”
  • IPIP / VXLAN:像你决定“开轿车去还是坐高铁去”

一个解决路线发布,一个解决封装方式。

在 Calico 里它经常怎么用

Calico 常见有几种思路:

  1. 纯路由/BGP
  2. BGP + IPIP
  3. VXLAN

你的集群现在更像:

  • bird 负责路由学习
  • tunl0 负责 IPIP 隧道

Pod 里的 DNS 是怎么工作的

我们在 net-debug Pod 里实际看到了:

search learn-k8s.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

这三行分别意味着什么

nameserver 10.96.0.10

Pod 的 DNS 请求发给 CoreDNS Service。

也就是:

  • Pod 想解析域名
  • 实际访问的目标是 10.96.0.10:53

如果你写短域名,例如:

hello-svc

系统会尝试补成:

  • hello-svc.learn-k8s.svc.cluster.local
  • hello-svc.svc.cluster.local
  • hello-svc.cluster.local

ndots:5

意思是:

  • 如果名字里的点数少于 5,优先当“相对域名”并结合 search 域尝试

这就是为什么在 Pod 里经常可以直接写:

  • hello-svc
  • kubernetes.default

而不必总写完整 FQDN。


普通 Service 和 Headless Service 的 DNS 区别

我们实际创建了两个 Service:

  • hello-svc:普通 ClusterIP Service
  • hello-headlessclusterIP: None

它们对应同一组后端 Pod。

普通 Service 的 DNS 结果

在 Pod 里执行:

nslookup hello-svc.learn-k8s.svc.cluster.local

实际返回:

Address: 10.98.52.186

这说明:

  • 普通 Service 的 DNS 返回的是 ClusterIP

客户端拿到的是虚拟服务入口。

Headless Service 的 DNS 结果

在 Pod 里执行:

nslookup hello-headless.learn-k8s.svc.cluster.local

实际返回:

10.244.119.226
10.244.147.106

这说明:

  • Headless Service 不提供单个虚拟 IP
  • DNS 直接把后端 Pod IP 返回给客户端

这两者的使用场景差别

普通 Service

适合:

  • 无状态服务
  • 希望统一入口和服务端负载均衡

Headless Service

适合:

  • StatefulSet
  • 需要直接发现每个 Pod
  • 客户端自己做负载均衡
  • 数据库集群、消息队列、分片服务

Headless 的限制

  • 没有统一虚拟 IP
  • 客户端必须处理多地址
  • 不适合所有应用直接替换普通 Service

Service ClusterIP 为什么能工作

这是 Kubernetes 网络里最经典的问题。

你的 hello-svc 的 ClusterIP 是:

  • 10.98.52.186

这个 IP 真有网卡绑定吗

通常没有。

它不是“谁真的拥有了这个 IP”,而是:

节点上的 kube-proxy 通过 iptables 规则拦截目标为这个 IP 的流量,然后做 DNAT 转发。

你的真实证据

在节点 107.148.164.118 上我们实际看到了:

-A KUBE-SERVICES -d 10.98.52.186/32 ... -j KUBE-SVC-DDRHELRYSZTKW5IS

这说明:

  • 所有发往 10.98.52.186:80 的包
  • 会先进入 KUBE-SERVICES
  • 再跳到属于 hello-svc 的专属链

再往下一跳看

我们继续看到:

-A KUBE-SVC-DDRHELRYSZTKW5IS ... -> 10.244.119.226:80 -j KUBE-SEP-UKGRKZPH3AYMGFRZ
-A KUBE-SVC-DDRHELRYSZTKW5IS ... -> 10.244.147.106:80 -j KUBE-SEP-UO4ZJSZILKR3WCEO

这说明:

  • KUBE-SVC 链在做后端选择
  • 它知道有两个 endpoint

而具体 endpoint 链里我们看到:

-A KUBE-SEP-UKGRKZPH3AYMGFRZ ... -j DNAT --to-destination 10.244.119.226:80
-A KUBE-SEP-UO4ZJSZILKR3WCEO ... -j DNAT --to-destination 10.244.147.106:80

这就是核心原理

ClusterIP 能工作,不是因为它真的挂在某个网卡上,而是因为内核 NAT 规则把目标地址改写成了真实 Pod IP。

这也是为什么 Service 是虚拟 IP。


KUBE-MARK-MASQ 又是什么

在规则里你还看到了:

! -s 10.244.0.0/16 -d 10.98.52.186/32 ... -j KUBE-MARK-MASQ

它在干什么

这是 kube-proxy 的一部分 SNAT / MASQUERADE 处理逻辑。

大意是:

  • 如果流量不是从 Pod 网段里来的
  • 访问这个 Service 时可能需要做源地址伪装

为什么需要它

因为转发后的返回路径必须正确。

如果不做合适的 SNAT/MASQ,返回包可能走错路,导致连接不对称。

这是 Linux NAT 场景里的经典问题。


kube-proxy 的三种常见模式有什么区别

虽然你的集群实际使用的是 iptables,但专家视角必须知道另外两种。

1. iptables 模式

你的集群当前就是这个。

原理

  • 写入大量 nat / filter 规则
  • 靠内核 iptables 匹配并做 DNAT

优点

  • 普及度高
  • 行为成熟
  • 默认可用

缺点

  • Service 多了以后规则会越来越多
  • 规则调试相对麻烦
  • 大规模下性能和可维护性会受影响

2. IPVS 模式

原理

  • 用 Linux IPVS 做四层负载均衡

优点

  • 性能更好
  • 调度算法更多

缺点

  • 额外内核模块和运维复杂度
  • 现代 Kubernetes 中已不是所有场景的首推方向

3. nftables 模式

原理

  • 用更现代的 nftables 机制替代 iptables

优点

  • 新一代规则框架
  • 某些场景更整洁

缺点

  • 生态与经验积累还没像 iptables 那么普及

从 Pod 视角看网络:net-debug 这个实验有什么价值

我们让 net-debug Pod 跑在:

  • hk652699382121

它的 IP 是:

  • 10.244.169.9

这很有意思,因为:

  • hello-svc 的两个后端分别在别的节点上
  • 所以这个 Pod 访问 Service 时,很大概率要跨节点

在 Pod 里我们看到的路由

default via 169.254.1.1 dev eth0

这说明:

  • Pod 自己不是一个小路由器
  • Pod 只知道把流量交给默认网关
  • 具体怎么跨节点、怎么封装、怎么 DNAT,主要由宿主机网络栈和 CNI 处理

这个认知很重要

以后你进 Pod 里排查网络时,要知道:

  • Pod 看到的是自己的命名空间视角
  • 很多关键 NAT/路由发生在宿主机网络命名空间

所以:

  • Pod 视角看 DNS、端口、应用层连接
  • 节点视角看路由、NAT、隧道

两者要结合。


TCP 和 UDP 到底怎么选

既然我们讲到了四层,这一块也必须说清。

TCP

适合:

  • HTTP / HTTPS
  • gRPC
  • MySQL / PostgreSQL
  • Redis
  • 大多数 API 调用

优点:

  • 可靠
  • 有顺序
  • 自动重传

缺点:

  • 更重
  • 延迟和握手成本更高

UDP

适合:

  • DNS
  • 流媒体
  • 实时语音视频
  • 某些隧道协议

优点:

  • 延迟低

缺点:

  • 不保证到达
  • 不保证顺序

在你的集群里最典型的 UDP 场景

  • CoreDNS 的 53/UDP
  • WireGuard 的 UDP 隧道

这两个都非常典型。


你的集群里,DNS 为什么同时有 53/TCP 和 53/UDP

我们看到 kube-dns Service 暴露:

  • 53/UDP
  • 53/TCP
  • 9153/TCP

为什么 DNS 不是只有 UDP

很多人以为:

  • DNS = UDP

这不完整。

实际情况是:

  • 小请求常用 UDP
  • 超大响应、某些重试或区域传输场景会用 TCP

所以 CoreDNS 同时提供 TCP/UDP 53 很正常。

9153/TCP 又是什么

这是 metrics 端口,供监控采集。


你当前集群为什么不是 VXLAN,而是 IPIP,这意味着什么

意味着路径更偏 L3 overlay

因为 IPIP 是:

  • IP 包套 IP 包

而不是 VXLAN 那种:

  • 以太帧套 UDP

意味着没有 vxlan 设备

我们节点上也确实没看到任何 vxlan 接口。

意味着某些网络环境下可能有兼容性要求

因为 IPIP 依赖的是 IP 协议 4,不是常规 TCP/UDP 端口。

某些云网络、防火墙、运营商环境可能会限制这类协议。

意味着 MTU 要更加小心

你的集群还叠加了 WireGuard。

每多一层封装,就多一层头部开销。

如果 MTU 没调好,可能出现:

  • 大包碎片化
  • 某些请求偶发超时
  • TLS 握手怪异失败

这就是为什么网络 overlay 一定要关注 MTU。


为什么说封装不是免费的

这是很多平台工程师后面才慢慢意识到的事情。

原理

每一次隧道封装,都会加外层头部。

例如:

  • IPIP 会加外层 IP 头
  • VXLAN 会加 UDP + VXLAN + 外层 IP 头
  • WireGuard 也会增加加密封装头

代价

  • 实际 payload 变小
  • 有效 MTU 下降
  • CPU 要做更多处理
  • 排障复杂度提高

在你的集群里尤其值得注意

因为你不是单层 overlay,而是:

  • Pod overlay:IPIP
  • 节点 underlay:WireGuard

所以这套网络设计非常适合教学,但在生产里就需要特别关注:

  • MTU
  • 吞吐
  • 延迟
  • 跨地域链路质量

什么时候适合 BGP,什么时候适合 VXLAN,什么时候适合 IPIP

这不是绝对标准,而是工程取舍。

纯 BGP / 直路由思路

适合:

  • 数据中心网络可控
  • 底层网络团队能配合
  • 追求更原生路由、减少 overlay 开销

限制:

  • 网络要求高
  • 运维复杂度更高

IPIP

适合:

  • 纯三层 Pod 网络
  • IPv4 环境
  • 想比 VXLAN 轻一些

限制:

  • 某些环境对 IP protocol 4 兼容性不好
  • 不适合需要 L2 语义的场景

VXLAN

适合:

  • 多子网云环境
  • 不想深度依赖底层 BGP
  • 更通用的 overlay 部署

限制:

  • 额外头部更大
  • 性能和 MTU 代价更明显

WireGuard

适合:

  • 节点跨公网/跨机房安全互联
  • 需要加密 underlay

限制:

  • 它不是 Service 负载均衡
  • 不是直接替代 kube-proxy
  • 仍需和 CNI、Service 模型配合

Kubernetes 网络里最常见的 5 类对象,分别解决什么问题

1. Pod

最小网络终点。

有自己的 IP。

2. Service

给一组 Pod 提供稳定入口。

普通 Service 返回 ClusterIP。

3. Endpoints / EndpointSlice

保存真正的后端 Pod IP 列表。

4. CoreDNS

把 Service 名称、Pod 名称解析成 IP。

5. Ingress / Gateway

解决外部七层入口和 Host/Path 路由。


网络排障时最值得先拿出来的命令

你特别要求“调试命令”,这里我按层次给你一个真正实用的工具箱。

一、先看 K8s 对象层

kubectl get svc,endpoints,endpointslices -A

用途:

  • 看服务入口和后端是否一致

如果 Service 不通,先看 Endpoints,是最重要的习惯之一。

kubectl get pods -o wide

用途:

  • 看 Pod IP、所在节点、状态

kubectl describe pod <name>

用途:

  • 看探针、事件、重启、网络相关异常

二、进 Pod 看 DNS 和应用层连接

kubectl exec <pod> -- cat /etc/resolv.conf

用途:

  • 看 Pod 当前用哪个 DNS
  • 看 search domain

kubectl exec <pod> -- nslookup <name>

用途:

  • 验证 CoreDNS 解析是否正常

kubectl exec <pod> -- wget -qO- http://service

或:

kubectl exec <pod> -- curl -v http://service

用途:

  • 验证 L7 访问是否成功

kubectl exec <pod> -- ping <ip>

用途:

  • 快速看三层 reachability

注意:

  • ping 通不代表 TCP 一定通
  • 有些镜像里根本没 ping

三、看节点网络事实

ip -br a

用途:

  • 快速看网卡与地址

在你的集群里,它能直接让你看到:

  • wg0
  • tunl0
  • cali*

ip route

用途:

  • 看目标网段怎么走

ip route get <IP>

用途:

  • 精准看“去这个目的地址时,内核会选哪条路”

在你的集群里,这条命令直接证明了:

  • 去远端 Pod 会走 tunl0
  • 去远端节点工作地址会走 wg0

ss -lntup

用途:

  • 看本机哪些 TCP/UDP 端口在监听

适合排查:

  • kubelet
  • node exporter
  • ingress controller
  • 本地服务没起

四、看 kube-proxy 和 NAT

iptables-save -t nat | grep <ClusterIP>

用途:

  • 看某个 Service IP 是否被 kube-proxy 写进 NAT 规则

这是理解 ClusterIP 的硬证据。

kubectl -n kube-system logs ds/kube-proxy

用途:

  • 看 kube-proxy 当前模式、异常日志

五、看 CNI 和跨节点路径

kubectl -n kube-system logs ds/calico-node

用途:

  • 看 Calico 节点代理是否健康

用途:

  • 判断当前是否使用 VXLAN 设备

在你的集群里,这个结果为空,反过来证明你不是 VXLAN 模式。

用途:

  • 看 IPIP 隧道接口是否存在

tcpdump -ni any host <IP>

用途:

  • 抓包看包到底有没有到、是从哪个接口走的

这是网络排障终极工具之一,但前提是你已经先用对象层和路由层把范围缩小。


网络排障时,先按这条路径判断

1. DNS 解析是否正常

检查:

  • /etc/resolv.conf
  • nslookup

2. Service 是否有后端

检查:

  • kubectl get svc,endpoints

3. Pod 本身是否 Ready

检查:

  • kubectl get pods
  • kubectl describe pod

4. 节点 NAT 规则是否存在

检查:

  • iptables-save -t nat
  • kube-proxy 日志

5. 跨节点路由和隧道是否正常

检查:

  • ip route
  • ip route get
  • calico-node 日志
  • 必要时抓包

如果你按这个顺序走,网络问题就不会被你查成一团乱麻。


这节课里最关键的 10 个现实结论

  1. 你的集群节点工作网是 WireGuard 10.10.0.0/24
  2. Pod 网段是 10.244.0.0/16
  3. Service 网段是 10.96.0.0/12
  4. CoreDNS Service 是 10.96.0.10
  5. hello-svc 的 ClusterIP 是 10.98.52.186
  6. kube-proxy 当前使用 iptables 代理模式
  7. Calico 当前是 IPIP=AlwaysVXLAN=Never
  8. 节点上有 tunl0,没有 vxlan 设备
  9. 跨节点 Pod 路由通过 tunl0 指向远端 10.10.0.x
  10. Headless Service 的 DNS 返回 Pod IP,而普通 Service 返回 ClusterIP

这些不是课本定义,而是你当前真实集群的事实。


你现在必须能回答的 15 个问题

  1. 为什么网络问题必须分层看?
  2. 二层、三层、四层、七层分别在解决什么问题?
  3. Pod IP、Node IP、Service IP 分别是什么?
  4. 为什么 ClusterIP 不一定绑定在真实网卡上?
  5. kube-proxy 在 iptables 模式下做了什么?
  6. KUBE-SVC 链和 KUBE-SEP 链分别表示什么?
  7. 什么是 DNAT?
  8. 普通 Service 和 Headless Service 的 DNS 返回值为什么不同?
  9. CoreDNS 在 Pod 里体现在哪?
  10. ndots:5 会影响什么?
  11. VXLAN 和 IPIP 的本质区别是什么?
  12. BGP 为什么不是封装协议?
  13. WireGuard 在你这套集群里解决的是什么问题?
  14. 为什么 overlay 封装会带来 MTU 和性能代价?
  15. Service 不通时,为什么优先看 Endpoints?

下一课预告

你现在已经有了:

  • 控制面主链路
  • 调度
  • Service / DNS / CNI / overlay 的基础网络模型

下一步最自然的主题是:

配置管理和安全边界如何进入这条链路。

也就是:

  • ConfigMap / Secret
  • ServiceAccount
  • RBAC
  • Pod Security
  • 网络策略 NetworkPolicy

如果你愿意,我下一课会继续按你当前真实集群来讲:

  • NetworkPolicy 为什么默认不生效
  • Calico 是怎么实现网络隔离的
  • 为什么“能 ping 通”和“被策略允许”不是一回事

第四课总结

这节课最重要的结论只有一句:

Kubernetes 网络不是某一个组件的功能,而是节点网络、Pod 网络、Service 转发、DNS 解析和应用协议分层协作后的结果。

而你这套集群又非常有代表性,因为它同时展示了:

  • WireGuard 节点互联
  • Calico IPIP Pod overlay
  • kube-proxy iptables Service 转发
  • CoreDNS 服务发现

把这几个层次真正分清楚,网络就不再是“玄学”,而是可以拆开分析、逐层定位的工程系统。