K8s 网络模型简述 —— Pod IP、Service IP、流量到底怎么走的?

前置知识

需掌握 Kubernetes 核心资源(Pod、Service、Ingress)及 kubectl 基础命令。本文聚焦网络底层逻辑,通俗讲解 Pod IP 分配、Service 负载均衡原理、内外网流量流转路径,无复杂命令实操,主打核心概念梳理。

1. 困惑:K8s 集群中有多少种 IP?

日常操作 K8s 时,我们会接触到多种 IP 术语:通过 kubectl get pods -o wide 可查看到 Pod IP(如 10.244.1.5),通过 kubectl get services 可查看到 ClusterIP(如 10.96.100.1),此外还有节点 IP、NodePort、LoadBalancer IP 等概念。

各类 IP 各司其职、层级不同,很多人困惑其关联关系,以及外部请求接入集群的完整链路。本文将完整梳理这套网络体系。


2. K8s 网络核心准则

K8s 对网络有统一强制规范,该规范由 CNI 网络插件(Calico、Flannel、Cilium 等)落地实现:

每个 Pod 拥有独立唯一 IP,所有 Pod 之间无需 NAT 转换,可直接互通

基于该准则,衍生三大核心通信特性:

  • Pod 可直接通过对端 Pod IP 跨 Pod 通信(不推荐直接使用,Pod IP 会动态变化)

  • Pod 与集群节点之间可直接通信

  • 不同节点上的 Pod 可通过 overlay 网络或集群路由直接互通

3. K8s 核心三类 IP 详解

集群网络最核心、最常用的 IP 仅有三类,其余端口/IP 均为衍生能力,核心属性对比如下:

IP 类型 归属主体 是否固定 访问范围 作用
Pod IP 单个 Pod 不固定(Pod 重建即变更) 仅集群内部可路由访问 Pod 在集群内的唯一网络地址,用于集群内部 Pod 与 Pod、Pod 与节点之间直接通信
Service ClusterIP 单个 Service 资源 固定(删除重建才会变更) 仅集群内部可访问 为一组动态 Pod 提供统一不变的内部访问入口,自动转发流量并屏蔽 Pod IP 的变化
Node IP 集群节点(物理/虚拟机) 固定 网络放行后可被集群外部访问 用于节点运维、节点间通信,也是 NodePort 对外访问的基础地址

衍生能力:NodePort(节点开放端口,归属节点 IP 延伸)、LoadBalancer IP(云厂商分配公网 IP,生产外部入口)。

4. Pod IP:Pod 的真实物理网络地址

4.1 Pod IP 分配机制

集群部署 CNI 网络插件后,插件会预先为每个节点划分独立 IP 地址池。当 Pod 启动时,CNI 插件自动从所在节点的 IP 池中,为 Pod 分配一个唯一 IP 地址。

核心特性:各节点 IP 池无重叠,所有 Pod IP 在全局集群内唯一、可正常路由。

4.2 Pod IP 特点

  • 直接可达:集群内任意节点、任意 Pod,均可通过 Pod IP+端口直接访问目标 Pod(网络策略未限制前提下)

  • 非持久化:Pod 属于临时资源,删除、重建、漂移后 IP 会变更,绝对不可硬编码至业务配置中

  • 容器共享:同一个 Pod 内所有容器共享同一个网络命名空间,共用一个 Pod IP,通过不同容器端口区分不同容器服务

5. Service 网络:ClusterIP 负载均衡原理

5.1 什么是 ClusterIP?

ClusterIP 是 K8s Service 默认类型,会为 Service 分配一个固定的虚拟 IP(如 10.96.100.1)。该 IP 不绑定任何节点、任何网卡,无真实网络实体,完全依靠集群组件实现流量转发。

5.2 ClusterIP 核心实现组件:kube-proxy

kube-proxy 是运行在集群每一个节点上的核心系统组件(以静态 Pod 或 DaemonSet 形式运行),是 Service 流量转发的核心载体。

职责:实时监听 API Server 中 Service、Pod 资源的变化,自动更新节点内核网络规则,实现流量负载均衡。

完整工作流程
  1. 用户创建 ClusterIP 类型 Service,配置标签选择器(如 app: flask-app),绑定业务 Pod;

  2. API Server 存储 Service 配置,持续监控匹配标签的 Pod 集合,生成 Endpoints 后端地址列表;

  3. 所有节点的 kube-proxy 感知 Service 与 Endpoints 变更,自动在节点写入 iptables/IPVS 转发规则;

  4. 集群内流量访问 ClusterIP 时,节点网络规则自动拦截请求,随机/轮询转发至后端健康 Pod。

5.3 kube-proxy 两大主流工作模式

工作模式 实现原理 性能表现 核心特点
iptables 依托 Linux 内核 iptables 规则实现流量转发 一般,大规模规则场景性能衰减明显 稳定性极高,是 K8s 默认模式,兼容性强
IPVS 依托 Linux 专用负载均衡内核模块 IPVS 实现 高性能,适配大规模集群、大量 Service 场景 支持轮询、最少连接等多种负载均衡算法

5.4 ClusterIP 完整请求链路(集群内部)

客户端(集群内 Pod/节点)访问 http://10.96.100.1:80 的完整流转路径:

客户端(其他Pod/节点)
    │
    │ 发起请求:访问 ClusterIP 10.96.100.1:80
    ▼
节点网络栈接收数据包
    │
    │ kube-proxy 预设 iptables/IPVS 规则拦截流量
    ▼
匹配虚拟 ClusterIP 规则,从 Endpoints 列表筛选后端Pod
    │
    │ 转发至目标 Pod IP:端口(可同节点/跨节点)
    ▼
目标Pod容器接收并处理请求

结论:ClusterIP 仅为虚拟入口,无数据处理能力,所有流量转发、负载均衡均依赖 kube-proxy 规则实现。

区分:Pod IP 是集群内真实存在的物理网络地址,而 Service IP 是虚拟抽象地址。

6. NodePort:集群外部简易访问方案

6.1 适用场景

ClusterIP 仅支持集群内部访问,无法对外暴露服务。NodePort 是 K8s 提供的最简外部访问方式,适用于测试、本地开发、小规模服务暴露场景。

6.2 核心原理

NodePort 会在集群所有节点上开放一个统一固定端口(默认端口范围 30000~32767),所有节点该端口的流量,都会被 kube-proxy 拦截并转发至对应 Service 的 ClusterIP,最终转发至后端 Pod。

访问链路:任意节点IP:NodePort端口 → ClusterIP → 后端Pod

6.3 NodePort 配置示例

apiVersion: v1
kind: Service
metadata:
  name: flask-service
spec:
  type: NodePort
  selector:
    app: flask-app
  ports:
    - port: 80              # Service集群内部访问端口
      targetPort: 5000      # Pod容器监听端口
      nodePort: 30080       # 节点对外暴露端口(不指定则自动分配)

6.4 NodePort 优缺点

优点
  • 配置简单,无需依赖云厂商能力

  • 所有节点端口统一,任意节点 IP 均可访问服务

  • 可配合外部硬件负载均衡器实现高可用

缺点
  • 端口范围固定且有限(30000-32767),端口不规整,不利于业务管理

  • 依赖节点 IP,节点变更后访问地址失效,稳定性差

  • 直接暴露节点端口,存在安全风险,不推荐生产直接使用

7. LoadBalancer & Ingress:生产环境标准对外入口

7.1 LoadBalancer Service

云原生集群(阿里云 ACK、AWS EKS、GCP GKE)专属服务类型。将 Service 类型设置为 LoadBalancer 后,云厂商会自动创建公有云负载均衡器(SLB/ELB),分配独立公网 IP。

外部流量统一访问公网 LoadBalancer IP,由云负载均衡将流量分发至集群节点 NodePort,最终流转至后端 Pod,无需手动管理节点 IP 和端口。

7.2 Ingress 七层路由

Ingress 是 K8s 七层应用层路由资源,核心作用是根据域名、URL 路径规则,将不同流量分发至不同 Service,解决多服务统一入口、域名路由问题。

Ingress 本身无转发能力,依赖 Ingress Controller 实现流量处理,而 Ingress Controller 本质是一组 Pod,需要通过 LoadBalancer/NodePort 对外暴露。

标准流量链路:公网用户 → LoadBalancer/NodePort → Ingress Controller → 匹配路由规则 → 对应 Service ClusterIP → 后端Pod

8. 全场景网络流量路径总览

8.1 集群内部直连通信(Pod → Pod)

Pod A (10.244.1.5) → 直接路由访问 → Pod B (10.244.2.8)
# 依托CNI网络实现跨节点Pod直接互通,无中间转发

8.2 集群内部通过 Service 通信(Pod → Service → Pod)

Pod A 发起请求访问 Service ClusterIP (10.96.100.1:80)
→ kube-proxy 规则拦截流量
→ 负载均衡筛选后端Pod IP
→ 流量转发至目标业务Pod

8.3 外部公网访问完整链路(生产标准)

用户浏览器访问 https://flask.example.com
→ DNS解析至云厂商LoadBalancer公网IP
→ 云LoadBalancer分发流量至集群节点NodePort
→ 节点流量转发至Ingress Controller Pod
→ Ingress匹配域名/路径路由规则
→ 转发至对应业务Service ClusterIP
→ kube-proxy负载均衡至后端可用Pod
→ Pod处理请求并返回响应

8.4 全层级端口映射对照表

流量层级 IP 地址 端口映射
用户公网请求 公网域名解析IP 443(HTTPS标准端口)
云LoadBalancer 公网IP 443 → 节点NodePort(如30080)
集群节点 节点IP 30080 → Ingress监听80/443端口
Service集群服务 ClusterIP(10.96.100.1) 80 → Pod容器端口5000
业务Pod Pod真实IP 5000(业务服务监听端口)

9. 常见网络核心问题解答

Q1:同一 Pod 内多个容器如何通信?

同一 Pod 所有容器共享同一个网络命名空间,直接通过 localhost+端口 即可互通,无需跨网络路由。

Q2:Service 的 Endpoints 是什么?

Endpoints 是 Service 标签选择器匹配到的后端 Pod IP+端口列表,是 Service 负载均衡的真实数据源。可通过 kubectl get endpoints 服务名 查看。

若 Endpoints 列表为空,说明无匹配标签的就绪 Pod,Service 无法转发业务流量。

Q3:K8s 集群内部是否支持域名解析访问 Service?

支持。集群内置 CoreDNS 组件提供域名解析服务,同命名空间内可直接通过 服务名访问,跨命名空间可通过完整域名 服务名.命名空间.svc.cluster.local 访问。

Q4:NodePort 端口是否可以自定义?

可以,自定义端口必须在 30000~32767 官方指定范围内,超出范围会被 API Server 拒绝创建。未手动指定时,集群会自动分配空闲端口。

Q5:Ingress Controller 必须通过 NodePort/LoadBalancer 暴露吗?

是。Ingress Controller 本质是普通 Pod,无天然对外暴露能力。云生产环境优先使用 LoadBalancer,裸金属/测试环境可使用 NodePort 或 hostNetwork 模式暴露。

10. 知识点总结

核心资源定位

  • Pod IP:Pod 真实物理地址,集群内唯一可路由,重建即变更,不持久化

  • ClusterIP:Service 虚拟固定入口,集群内部专属,依托 kube-proxy 实现负载均衡

  • NodePort:节点端口暴露方案,适配测试环境外部访问

  • LoadBalancer:云厂商公网入口,生产环境标准外网方案

  • Ingress:七层域名路由,实现多服务统一入口、精细化流量分发

网络核心逻辑

  • 集群内部通信:依托 CNI 插件实现 Pod 直连、ClusterIP 负载均衡转发

  • 集群外部通信:流量必经 NodePort/LoadBalancer,配合 Ingress 实现规范路由

  • 底层核心支撑:所有 Service 流量转发、负载均衡,均依赖 kube-proxy(iptables/IPVS)实现

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐