AI 协助说明: 本页由 Codex 协助核验和修复站内链接;正文的技术事实和适用范围未因本次修改而改变,仍以文中来源及当前官方文档为准。
定位:这是一张选型速记,而不是数据包追踪教程。需要理解对象字段时看 Service 详解,需要逐跳定位请求时看 网络全景 和 Service 转发链路。
先分层,再选择#
下面四类问题经常同时出现,但它们不能互相替代:
| 决策层 | 要解决的问题 | 典型选项 |
|---|---|---|
| 服务入口 | 怎样稳定访问一组会变化的 Pod | ClusterIP、NodePort、LoadBalancer、ExternalName、Headless Service |
| Service 数据面 | VIP / NodePort 怎样选择 Endpoint | kube-proxy 的 iptables / nftables,或 CNI eBPF 实现 |
| Pod 跨节点网络 | 一个 Pod IP 怎样到达另一节点的 Pod IP | 原生三层路由、BGP、IPIP、VXLAN |
| 容器运行时 | 某个 Pod 以什么隔离与运行方式启动 | 默认 runc,或通过 RuntimeClass 选择 Kata、gVisor 等已配置 handler |
Service 是稳定入口;它不决定跨节点如何转发。
IPIP / VXLAN 是跨节点传输方式;它们不负责 Service 后端选择。
RuntimeClass 是运行时选择;它不安装运行时,也不决定网络插件。1. 选择 Service 入口#
| 目标 | 首选 | 关键边界 |
|---|---|---|
| 集群内访问一组 Pod | ClusterIP + DNS | 默认选择;客户端访问的是虚拟入口,不是单个 Pod IP。 |
| 简单或临时的集群外访问 | NodePort | 需要自行保障节点地址、防火墙与安全组可达。 |
| 云上四层正式入口 | LoadBalancer | 后端究竟经 NodePort 还是直连 Pod,取决于云控制器实现。 |
| 将集群内名称映射给外部域名 | ExternalName | 仅返回 DNS CNAME;没有代理、ClusterIP 或 EndpointSlice。要验证 HTTP Host 和 TLS SNI。 |
| StatefulSet / 客户端自行发现副本 | Headless Service | clusterIP: None,DNS 返回后端地址而不是单个 VIP。 |
| HTTP 路由、TLS、域名入口 | Ingress 或 Gateway + 后端 Service | 入口资源不是 Service 的替代品;仍需 Service 指向后端。 |
选择后先验证两件事:Service selector 是否命中目标 Pod,以及 EndpointSlice 是否含有期望的 Ready 后端。port、targetPort 和 nodePort 分别处于 Service、后端 Pod 和 Node 入口三个层次,不能凭名字猜测。
2. 选择 Service 数据面#
| 情况 | 建议 |
|---|---|
| 存量 Linux 集群,兼容性优先 | 保持已验证的 iptables 模式,先解决实际规模或规则同步问题。 |
| 新建传统 kube-proxy 集群,节点系统支持 nftables | 评估 nftables 模式;以当前 Kubernetes 版本的官方兼容性说明为准。 |
| 已使用 IPVS | 不把它作为新建默认方案;先核对版本支持、兼容性和迁移窗口。 |
| CNI 提供成熟 eBPF Service 实现 | 依据该 CNI 的兼容矩阵决定是否替代 kube-proxy,并验证 NetworkPolicy、观测和回滚路径。 |
无论实现是哪一种,都可用同一模型理解:它观察 Service 和 EndpointSlice,再让到达 ClusterIP / NodePort 的流量到达选中的后端。它不为 Pod 分配 IP,也不处理 Overlay 的选型。
3. 选择跨节点 Pod 网络#
先问底层网络是否能够路由 Pod CIDR:
| 环境或约束 | 传输选择 | 说明 |
|---|---|---|
| 数据中心网络可通过静态路由或 BGP 感知 Pod CIDR | 原生三层路由(可结合 BGP 分发路由) | 报文无需额外封装;底层网络必须知道 Pod 网段的下一跳。 |
| 底层网络不认识 Pod CIDR | Overlay | 外层使用节点 IP,底层只需让节点网络可达。 |
| Overlay 且网络设备更适合放行 UDP | VXLAN | 常用 UDP 4789;需考虑封装后的 MTU。 |
| 存量 IPv4 Calico IPIP 集群 | IPIP | 外层为 IPv4,协议号 4 而不是端口;切换前先评估兼容性和 MTU。 |
| 同一底层子网内不想承受封装开销 | CrossSubnet | 仅跨底层子网时封装;判断对象是 Node 的 underlay 子网,不是 Pod CIDR。 |
关键分层:BGP 传播路由可达性,IPIP/VXLAN 定义在线路上如何封装,eBPF 是节点内核处理数据面的方式。它们不是一个四选一菜单。
4. 选择 RuntimeClass#
RuntimeClass 只在节点已经配置了对应 CRI handler 后才有意义。它是集群级资源,Pod 通过 runtimeClassName 引用;可选的 scheduling 字段会把工作负载限制到支持此 handler 的节点,overhead 用于把额外开销计入调度。
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata
scheduling:
nodeSelector:
runtime.example.com/kata: "true"
tolerations:
- key: runtime
operator: Equal
value: kata
effect: NoSchedule
---
apiVersion: v1
kind: Pod
metadata:
name: isolated-app
spec:
runtimeClassName: kata
containers:
- name: app
image: nginx:stable适合 RuntimeClass 的问题是“这类不受信任或需要更强隔离的工作负载,以何种已安装运行时启动”。它不能替代容器运行时安装、CNI 配置、节点亲和性设计或 Service 配置。
快速决策与验证#
服务发现失败? 先看 DNS、Service、EndpointSlice。
Service VIP 不通? 再看端口、kube-proxy / eBPF 数据面。
目标 Pod IP 不通? 再看 CNI、路由、封装、NetworkPolicy、MTU。
需要更强工作负载隔离? 先在目标节点安装并验证运行时,再创建 RuntimeClass。# Service 与端点
kubectl get svc -A -o wide
kubectl get endpointslice -A
# RuntimeClass 与目标节点
kubectl get runtimeclass
kubectl get nodes -L runtime.example.com/kata
# Calico / 节点网络(实际 CRD、接口和工具以安装方式为准)
kubectl get ippools.crd.projectcalico.org -o yaml
ip route get <target-pod-ip>
ip link show type vxlan
# 传统 kube-proxy 数据面(不要假设每个节点都有全部命令)
iptables-save | grep KUBE-SVC
nft list ruleset | grep kube