一文带你彻底搞懂K8s网络

描述

说实话,K8s 网络是我见过最让新手头疼的知识点,没有之一。记得我刚接触 K8s 那会儿,看着流量在 Pod、Service、Node 之间穿梭,完全是一脸懵逼。后来踩了无数坑,熬了无数夜,总算把这套网络模型摸透了。今天这篇文章,我会用最接地气的方式,带你彻底搞懂 K8s 网络。

一、概述

1.1 背景介绍

在传统的虚拟机时代,网络相对简单——每台 VM 一个 IP,通过交换机互联,顶多再加个负载均衡。但到了容器时代,事情变得复杂了:

一台宿主机上可能跑着几十上百个容器

容器随时可能被销毁重建,IP 地址不固定

跨主机的容器需要互相通信

还要对外暴露服务

K8s 的网络模型就是为了解决这些问题而生的。它定义了一套清晰的网络规范,让不同的网络插件(CNI)可以按照统一的标准来实现。

K8s 网络的四大通信场景:

 

┌─────────────────────────────────────────────────────────────┐
│                    K8s 网络通信场景                          │
├─────────────────────────────────────────────────────────────┤
│  1. 容器间通信     同一 Pod 内的容器通过 localhost 通信       │
│  2. Pod 间通信     不同 Pod 之间直接通过 Pod IP 通信          │
│  3. Pod-Service    Pod 通过 Service 的 ClusterIP 访问服务    │
│  4. 外部-Service   外部流量通过 NodePort/LB/Ingress 进入集群  │
└─────────────────────────────────────────────────────────────┘

 

1.2 技术特点

K8s 网络模型有几个核心设计原则,理解了这些,后面的内容就好懂多了:

扁平化网络:所有 Pod 都在一个扁平的网络空间中,可以直接通过 IP 互访,不需要 NAT

IP-per-Pod:每个 Pod 拥有独立的 IP 地址,Pod 内的所有容器共享这个 IP

无 NAT 通信:Pod 看到的自己的 IP 就是其他 Pod 看到的 IP,没有地址转换的困扰

插件化架构:通过 CNI 标准接口,支持各种网络插件(Calico、Cilium、Flannel 等)

2026年主流 CNI 插件对比:

CNI 插件 网络模式 性能 NetworkPolicy eBPF 支持 适用场景
Cilium Overlay/路由 极高 完整+扩展 原生 大规模生产、安全敏感
Calico BGP/IPIP/VXLAN 完整 可选 通用生产环境
Flannel VXLAN/host-gw 不支持 不支持 小规模、学习环境
Weave VXLAN 支持 不支持 简单部署场景
Antrea Geneve/VXLAN 完整 可选 VMware 生态

个人建议:2026年了,新集群直接上 Cilium。eBPF 带来的性能提升和可观测性是传统方案没法比的。我们公司去年从 Calico 迁移到 Cilium 后,网络延迟降低了约 15%,而且 Hubble 的可视化简直是排障神器。

1.3 适用场景

不同的网络方案适用于不同场景,选错了后期改造成本很高(别问我怎么知道的...):

Overlay 网络(VXLAN/Geneve)

适合:跨云部署、网络环境复杂、IP 地址受限

缺点:有封装开销,性能略低

典型:Flannel VXLAN、Calico IPIP

路由网络(BGP/Host-Gateway)

适合:数据中心内部、对性能要求高、有 BGP 基础设施

缺点:需要网络团队配合,配置相对复杂

典型:Calico BGP、Cilium Native Routing

eBPF 网络

适合:大规模集群、需要高级网络策略、追求极致性能

缺点:内核版本要求高(建议 5.10+)

典型:Cilium、Calico eBPF 模式

1.4 环境要求

组件 版本要求 说明
Kubernetes 1.28+ 建议使用 1.29/1.30,支持最新网络特性
Linux 内核 5.10+ 使用 eBPF 特性建议 5.15+,生产推荐 6.1 LTS
CNI 插件 Cilium 1.15+ / Calico 3.27+ 2026年主流版本
kube-proxy 可选 使用 Cilium 可完全替代 kube-proxy
CoreDNS 1.11+ 集群 DNS 服务

内核版本检查:

 

# 检查当前内核版本
uname -r

# 检查 eBPF 支持情况
# 如果输出包含 CONFIG_BPF=y 说明支持
grep CONFIG_BPF /boot/config-$(uname -r)

# 检查 BTF 支持(Cilium 需要)
ls -la /sys/kernel/btf/vmlinux

 

二、详细步骤

2.1 准备工作

2.1.1 网络基础概念回顾

在深入 K8s 网络之前,先确保你理解这些基础概念(老手可以跳过):

 

┌────────────────────────────────────────────────────────────────┐
│                    Linux 网络命名空间                           │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│   ┌─────────────┐     veth pair      ┌─────────────┐          │
│   │  容器网络    │◄──────────────────►│  宿主机网络  │          │
│   │  namespace  │     (虚拟网线)      │  namespace  │          │
│   │             │                    │             │          │
│   │  eth0       │                    │  vethXXX    │          │
│   │  10.244.1.5 │                    │             │          │
│   └─────────────┘                    └──────┬──────┘          │
│                                             │                 │
│                                      ┌──────▼──────┐          │
│                                      │   cni0/     │          │
│                                      │   cilium_   │          │
│                                      │   host      │          │
│                                      │  (网桥)     │          │
│                                      └─────────────┘          │
└────────────────────────────────────────────────────────────────┘

 

关键概念解释:

Network Namespace:Linux 内核提供的网络隔离机制,每个 Pod 有自己的网络命名空间

veth pair:虚拟以太网设备对,像一根网线连接两个网络命名空间

Bridge(网桥):二层交换设备,连接同一主机上的多个 veth 设备

路由表:决定数据包下一跳去哪里

2.1.2 实验环境搭建

为了更好地理解网络原理,建议搭建一个测试环境:

 

# 使用 kind 快速创建多节点集群(推荐用于学习)
cat < kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  disableDefaultCNI: true# 禁用默认 CNI,手动安装
  podSubnet: "10.244.0.0/16"
  serviceSubnet: "10.96.0.0/12"
nodes:
- role: control-plane
- role: worker
- role: worker
EOF

kind create cluster --config kind-config.yaml --name network-lab

# 安装 Cilium(2026年推荐方案)
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.15.0 
  --namespace kube-system 
  --set kubeProxyReplacement=true 
  --set k8sServiceHost=kind-control-plane 
  --set k8sServicePort=6443

 

2.1.3 网络诊断工具准备

这些工具是排查网络问题的必备神器:

 

# 创建一个网络调试 Pod
kubectl run netshoot --image=nicolaka/netshoot --command -- sleep infinity

# 常用诊断命令
kubectl exec -it netshoot -- bash

# 在 Pod 内可以使用:
# - ip addr / ip route / ip neigh
# - ping / traceroute / mtr
# - curl / wget
# - tcpdump / tshark
# - nslookup / dig
# - ss / netstat
# - iperf3(性能测试)

 

2.2 核心配置

2.2.1 CNI 插件工作原理

CNI(Container Network Interface)是 K8s 网络的核心。当 kubelet 创建 Pod 时,会调用 CNI 插件来配置网络。

CNI 调用流程:

 

┌─────────────────────────────────────────────────────────────────────┐
│                        CNI 插件调用流程                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. kubelet 创建 Pod                                                │
│       │                                                             │
│       ▼                                                             │
│  2. 创建 pause 容器(持有网络命名空间)                               │
│       │                                                             │
│       ▼                                                             │
│  3. 调用 CNI 插件(/opt/cni/bin/)                                  │
│       │                                                             │
│       ├──► 读取配置(/etc/cni/net.d/)                              │
│       │                                                             │
│       ├──► 创建 veth pair                                          │
│       │                                                             │
│       ├──► 配置 IP 地址(IPAM)                                     │
│       │                                                             │
│       └──► 配置路由规则                                             │
│                │                                                    │
│                ▼                                                    │
│  4. 返回网络配置给 kubelet                                          │
│                │                                                    │
│                ▼                                                    │
│  5. 启动业务容器(共享网络命名空间)                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

 

CNI 配置文件示例(Cilium):

 

# 查看 CNI 配置
cat /etc/cni/net.d/05-cilium.conflist
{
  "cniVersion": "0.3.1",
  "name": "cilium",
  "plugins": [
    {
      "type": "cilium-cni",
      "enable-debug": false,
      "log-file": "/var/run/cilium/cilium-cni.log"
    }
  ]
}

 

2.2.2 Pod 网络模型详解

这是理解 K8s 网络的关键!每个 Pod 都有自己的网络栈:

 

┌─────────────────────────────────────────────────────────────────────┐
│                         Pod 网络模型                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────────────────────────────────────────────────────┐      │
│   │                      Pod                                 │      │
│   │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │      │
│   │  │ Container A │  │ Container B │  │   Pause     │     │      │
│   │  │   (app)     │  │  (sidecar)  │  │ (infra容器) │     │      │
│   │  │             │  │             │  │             │     │      │
│   │  │ localhost:  │  │ localhost:  │  │  持有网络   │     │      │
│   │  │   8080      │  │   9090      │  │  命名空间   │     │      │
│   │  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘     │      │
│   │         │                │                │            │      │
│   │         └────────────────┴────────────────┘            │      │
│   │                          │                             │      │
│   │                   共享网络命名空间                       │      │
│   │                          │                             │      │
│   │                    ┌─────▼─────┐                       │      │
│   │                    │   eth0    │                       │      │
│   │                    │10.244.1.5 │                       │      │
│   │                    └───────────┘                       │      │
│   └─────────────────────────────────────────────────────────┘      │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

 

关键点:

同一 Pod 内的容器共享网络命名空间,可以通过 localhost 互访

Pause 容器(也叫 infra 容器)负责持有网络命名空间

每个 Pod 有独立的 IP,端口空间也是独立的

验证 Pod 网络:

 

# 创建测试 Pod
kubectl run nginx --image=nginx:alpine

# 查看 Pod IP
kubectl get pod nginx -o wide

# 进入 Pod 查看网络配置
kubectl exec -it nginx -- sh
/ # ip addr
/ # ip route
/ # cat /etc/resolv.conf

 

2.2.3 Service 四种类型详解

Service 是 K8s 网络的核心抽象,它为一组 Pod 提供稳定的访问入口。说白了,Pod IP 会变,但 Service IP 不会变。

 

┌─────────────────────────────────────────────────────────────────────┐
│                     Service 四种类型对比                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌───────────┐ │
│  │ ClusterIP   │  │  NodePort   │  │LoadBalancer │  │ExternalName│ │
│  │  (默认)     │  │             │  │             │  │           │ │
│  ├─────────────┤  ├─────────────┤  ├─────────────┤  ├───────────┤ │
│  │ 仅集群内部  │  │ 节点端口    │  │ 云LB + NP   │  │ DNS别名   │ │
│  │ 访问       │  │ 30000-32767 │  │ 自动创建    │  │ 无代理    │ │
│  │            │  │             │  │             │  │           │ │
│  │ 10.96.x.x  │  │ NodeIP:Port │  │ External IP │  │ CNAME记录 │ │
│  └─────────────┘  └─────────────┘  └─────────────┘  └───────────┘ │
│                                                                     │
│  适用场景:                                                          │
│  - ClusterIP: 内部微服务通信                                         │
│  - NodePort: 开发测试、简单暴露                                      │
│  - LoadBalancer: 生产环境对外服务                                    │
│  - ExternalName: 访问集群外部服务                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

 

1. ClusterIP(默认类型)

 

apiVersion: v1
kind:Service
metadata:
name:my-service
spec:
type:ClusterIP# 可省略,默认就是 ClusterIP
selector:
    app:my-app
ports:
-port:80        # Service 端口
    targetPort:8080# Pod 端口

 

2. NodePort

 

apiVersion: v1
kind:Service
metadata:
name:my-nodeport-service
spec:
type:NodePort
selector:
    app:my-app
ports:
-port:80
    targetPort:8080
    nodePort:30080# 可选,不指定会自动分配 30000-32767

 

3. LoadBalancer

 

apiVersion: v1
kind:Service
metadata:
name:my-lb-service
annotations:
    # 云厂商特定注解
    service.beta.kubernetes.io/aws-load-balancer-type:"nlb"
spec:
type:LoadBalancer
selector:
    app:my-app
ports:
-port:80
    targetPort:8080

 

4. ExternalName

 

apiVersion: v1
kind:Service
metadata:
name:external-db
spec:
type:ExternalName
externalName:db.example.com# 返回 CNAME 记录

 

2.2.4 kube-proxy 三种模式深度解析

kube-proxy 是实现 Service 负载均衡的关键组件。它有三种工作模式,理解它们的区别对于性能调优和故障排查非常重要。

模式对比:

特性 iptables IPVS nftables (1.31+)
性能 O(n) 规则匹配 O(1) 哈希查找 O(1) 集合查找
大规模支持 差(>1000 Service 性能下降) 优秀 优秀
负载均衡算法 随机 rr/lc/dh/sh/sed/nq 随机
连接追踪 依赖 conntrack 内置 依赖 conntrack
调试难度 中等 较难 中等
内核要求 3.10+ 4.0+ 5.13+

1. iptables 模式(传统默认)

 

┌─────────────────────────────────────────────────────────────────────┐
│                    iptables 模式工作原理                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Client Pod                                                        │
│       │                                                             │
│       │ dst: 10.96.0.10:80 (ClusterIP)                             │
│       ▼                                                             │
│   ┌─────────────────────────────────────────────────────────┐      │
│   │                    iptables 规则链                        │      │
│   │                                                          │      │
│   │  PREROUTING → KUBE-SERVICES → KUBE-SVC-XXX              │      │
│   │                                    │                     │      │
│   │                    ┌───────────────┼───────────────┐    │      │
│   │                    ▼               ▼               ▼    │      │
│   │              KUBE-SEP-A      KUBE-SEP-B      KUBE-SEP-C │      │
│   │              (Pod A)        (Pod B)         (Pod C)     │      │
│   │              33.3%          33.3%           33.3%       │      │
│   │                                                          │      │
│   └─────────────────────────────────────────────────────────┘      │
│       │                                                             │
│       │ DNAT: dst → 10.244.1.5:8080 (Pod IP)                       │
│       ▼                                                             │
│   Backend Pod                                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
# 查看 iptables 规则
iptables -t nat -L KUBE-SERVICES -n --line-numbers

# 查看特定 Service 的规则
iptables -t nat -L KUBE-SVC-XXXXXXXXXXXXXXXX -n

 

2. IPVS 模式(推荐大规模集群)

 

┌─────────────────────────────────────────────────────────────────────┐
│                      IPVS 模式工作原理                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Client Pod                                                        │
│       │                                                             │
│       │ dst: 10.96.0.10:80                                         │
│       ▼                                                             │
│   ┌─────────────────────────────────────────────────────────┐      │
│   │                    IPVS Virtual Server                    │      │
│   │                                                          │      │
│   │   VIP: 10.96.0.10:80                                    │      │
│   │   调度算法: rr (round-robin)                             │      │
│   │                                                          │      │
│   │   Real Servers:                                          │      │
│   │   ├── 10.244.1.5:8080  weight=1                         │      │
│   │   ├── 10.244.2.3:8080  weight=1                         │      │
│   │   └── 10.244.3.7:8080  weight=1                         │      │
│   │                                                          │      │
│   └─────────────────────────────────────────────────────────┘      │
│       │                                                             │
│       │ 直接转发到选中的 Real Server                                │
│       ▼                                                             │
│   Backend Pod                                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
# 启用 IPVS 模式
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "ipvs"

# 查看 IPVS 规则
ipvsadm -Ln

# 查看特定 Service
ipvsadm -Ln -t 10.96.0.10:80

 

3. nftables 模式(K8s 1.31+ 新增)

这是 2025 年底新增的模式,用于替代老旧的 iptables。如果你的内核版本够新(5.13+),建议尝试。

 

# 启用 nftables 模式(需要 K8s 1.31+)
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "nftables"

# 查看 nftables 规则
nft list ruleset | grep -A 20 "chain services"

 

踩坑经验:我们在一个 500+ Service 的集群上从 iptables 切换到 IPVS 后,Service 访问延迟从平均 2ms 降到了 0.5ms。但要注意,IPVS 模式下需要确保 ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh 等内核模块已加载。

2.3 DNS 解析流程

2.3.1 CoreDNS 工作原理

K8s 集群内的服务发现主要依赖 DNS。CoreDNS 是集群的 DNS 服务器,负责解析 Service 名称到 ClusterIP。

 

┌─────────────────────────────────────────────────────────────────────┐
│                    K8s DNS 解析流程                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Pod (curl my-service)                                             │
│       │                                                             │
│       │ 1. 查询 my-service                                          │
│       ▼                                                             │
│   ┌─────────────────────────────────────────────────────────┐      │
│   │              /etc/resolv.conf                            │      │
│   │  nameserver 10.96.0.10  (CoreDNS ClusterIP)             │      │
│   │  search default.svc.cluster.local svc.cluster.local     │      │
│   │         cluster.local                                    │      │
│   └─────────────────────────────────────────────────────────┘      │
│       │                                                             │
│       │ 2. 依次尝试:                                                │
│       │    - my-service.default.svc.cluster.local                  │
│       │    - my-service.svc.cluster.local                          │
│       │    - my-service.cluster.local                              │
│       ▼                                                             │
│   ┌─────────────────────────────────────────────────────────┐      │
│   │                    CoreDNS                               │      │
│   │                                                          │      │
│   │  ┌─────────────┐    ┌─────────────┐                     │      │
│   │  │ kubernetes  │    │  forward    │                     │      │
│   │  │   plugin    │    │  plugin     │                     │      │
│   │  │             │    │             │                     │      │
│   │  │ 查询 K8s API│    │ 转发到上游  │                     │      │
│   │  │ 获取 Service│    │ DNS 服务器  │                     │      │
│   │  └─────────────┘    └─────────────┘                     │      │
│   └─────────────────────────────────────────────────────────┘      │
│       │                                                             │
│       │ 3. 返回 ClusterIP: 10.96.100.50                            │
│       ▼                                                             │
│   Pod 访问 10.96.100.50                                             │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

 

DNS 记录类型:

记录类型 格式 示例
Service A 记录 ..svc.cluster.local nginx.default.svc.cluster.local
Pod A 记录 ..pod.cluster.local 10-244-1-5.default.pod.cluster.local
Headless Service 返回所有 Pod IP 用于 StatefulSet
SRV 记录 _._...svc.cluster.local 包含端口信息

2.3.2 CoreDNS 配置优化

 

# CoreDNS ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
            ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
            max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }

 

常见 DNS 问题排查:

 

# 测试 DNS 解析
kubectl run dnstest --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes

# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns -f

# 检查 CoreDNS Pod 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 查看 DNS 配置
kubectl get configmap coredns -n kube-system -o yaml

 

踩坑提醒:曾经遇到过一个诡异的问题,Pod 内 DNS 解析偶发超时。排查了半天,发现是 ndots 配置的锅。默认 ndots:5 意味着域名中点数少于 5 个时,会先尝试加上 search 域。建议在 Pod spec 中显式设置:

 

spec:
  dnsConfig:
    options:
    - name: ndots
      value: "2"  # 减少不必要的 DNS 查询
    - name: single-request-reopen  # 避免 conntrack 竞争

 

三、NetworkPolicy 实战

3.1 NetworkPolicy 基础

NetworkPolicy 是 K8s 的网络安全策略,用于控制 Pod 之间的流量。默认情况下,K8s 集群内所有 Pod 可以互相访问,这在生产环境是很危险的。

 

┌─────────────────────────────────────────────────────────────────────┐
│                  NetworkPolicy 工作原理                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   默认行为(无 NetworkPolicy):                                     │
│   ┌─────┐     ┌─────┐     ┌─────┐                                  │
│   │Pod A│◄───►│Pod B│◄───►│Pod C│   所有 Pod 互通                  │
│   └─────┘     └─────┘     └─────┘                                  │
│                                                                     │
│   应用 NetworkPolicy 后:                                           │
│   ┌─────┐     ┌─────┐     ┌─────┐                                  │
│   │Pod A│────►│Pod B│  ✗  │Pod C│   只允许特定流量                  │
│   └─────┘     └─────┘     └─────┘                                  │
│       │           ▲                                                 │
│       │           │ 只允许来自 Pod A 的流量                          │
│       └───────────┘                                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

 

重要概念:

NetworkPolicy 是 白名单 机制

一旦对 Pod 应用了 NetworkPolicy,默认拒绝所有未明确允许的流量

需要 CNI 插件支持(Flannel 不支持!)

3.2 实战案例

案例一:默认拒绝所有入站流量

 

# deny-all-ingress.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:deny-all-ingress
namespace:production
spec:
podSelector:{}# 选择该命名空间所有 Pod
policyTypes:
-Ingress
# 没有 ingress 规则 = 拒绝所有入站

 

案例二:只允许特定 Pod 访问数据库

 

# allow-app-to-db.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:allow-app-to-db
namespace:production
spec:
podSelector:
    matchLabels:
      app:mysql# 应用到 mysql Pod
policyTypes:
-Ingress
ingress:
-from:
    -podSelector:
        matchLabels:
          app:backend# 只允许 backend Pod 访问
    ports:
    -protocol:TCP
      port:3306

 

案例三:允许来自特定命名空间的流量

 

# allow-from-namespace.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:allow-monitoring
namespace:production
spec:
podSelector:{}
policyTypes:
-Ingress
ingress:
-from:
    -namespaceSelector:
        matchLabels:
          name:monitoring# 允许 monitoring 命名空间的所有 Pod
    ports:
    -protocol:TCP
      port:9090# Prometheus 指标端口

 

案例四:限制出站流量(防止数据泄露)

 

# restrict-egress.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:restrict-egress
namespace:production
spec:
podSelector:
    matchLabels:
      app:sensitive-app
policyTypes:
-Egress
egress:
# 允许访问 DNS
-to:
    -namespaceSelector:{}
      podSelector:
        matchLabels:
          k8s-app:kube-dns
    ports:
    -protocol:UDP
      port:53
# 允许访问内部数据库
-to:
    -podSelector:
        matchLabels:
          app:mysql
    ports:
    -protocol:TCP
      port:3306
# 禁止其他所有出站流量

 

3.3 NetworkPolicy 调试技巧

 

# 查看命名空间下的所有 NetworkPolicy
kubectl get networkpolicy -n production

# 查看详细规则
kubectl describe networkpolicy allow-app-to-db -n production

# 使用 Cilium 的话,可以用 Hubble 可视化流量
hubble observe --namespace production

# 测试连通性
kubectl exec -it test-pod -- nc -zv mysql-service 3306

 

生产经验:建议采用"默认拒绝 + 显式允许"的策略。先在每个命名空间部署 deny-all 策略,然后根据实际需求逐步开放。这样可以最大程度减少攻击面。

四、最佳实践和注意事项

4.1 最佳实践

4.1.1 CNI 选型建议

根据我这些年的经验,给出以下选型建议:

场景 推荐方案 理由
学习/测试环境 Flannel 简单易用,资源占用少
中小规模生产 Calico 成熟稳定,社区活跃
大规模生产 Cilium eBPF 性能优异,可观测性强
多集群/混合云 Cilium Cluster Mesh 原生支持跨集群通信
安全敏感场景 Cilium + Tetragon 内核级安全监控

4.1.2 性能优化

 

# 1. 启用 IPVS 模式(大规模集群必备)
kubectl edit configmap kube-proxy -n kube-system
# 设置 mode: "ipvs"

# 2. 调整 conntrack 参数
cat >> /etc/sysctl.conf << EOF
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600
EOF
sysctl -p

# 3. 如果使用 Cilium,启用 BPF 主机路由
helm upgrade cilium cilium/cilium 
  --set bpf.masquerade=true 
  --set routingMode=native 
  --set autoDirectNodeRoutes=true

 

4.1.3 高可用配置

 

# CoreDNS 高可用配置
apiVersion:apps/v1
kind:Deployment
metadata:
name:coredns
namespace:kube-system
spec:
replicas:3# 至少 3 副本
strategy:
    type:RollingUpdate
    rollingUpdate:
      maxUnavailable:1
template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          -labelSelector:
              matchLabels:
                k8s-app:kube-dns
            topologyKey:kubernetes.io/hostname# 分散到不同节点

 

4.2 注意事项

4.2.1 常见陷阱

问题 原因 解决方案
Pod 无法访问 Service kube-proxy 未运行或规则未同步 检查 kube-proxy 日志,重启 Pod
跨节点 Pod 不通 CNI 配置错误或防火墙阻断 检查节点间网络,开放 VXLAN 端口
DNS 解析超时 CoreDNS 资源不足或 ndots 配置 增加副本数,调整 ndots
Service 负载不均 会话亲和性或 IPVS 调度算法 检查 sessionAffinity 配置
NetworkPolicy 不生效 CNI 不支持或规则配置错误 确认 CNI 支持,检查 selector

4.2.2 安全加固

 

# 1. 禁用 NodePort 范围外的端口
# 在 kube-apiserver 配置中设置
--service-node-port-range=30000-32767

# 2. 启用 Pod 安全策略(或 Pod Security Standards)
kubectl label namespace production 
  pod-security.kubernetes.io/enforce=restricted

# 3. 限制 hostNetwork 使用
# 在 NetworkPolicy 中明确禁止

 

五、故障排查和监控

5.1 故障排查

5.1.1 网络排查流程图

 

┌─────────────────────────────────────────────────────────────────────┐
│                    K8s 网络故障排查流程                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Pod 网络不通?                                                     │
│       │                                                             │
│       ▼                                                             │
│   ┌─────────────────────────────────────────┐                      │
│   │ 1. 检查 Pod 状态                         │                      │
│   │    kubectl get pod -o wide              │                      │
│   │    Pod 是否 Running?IP 是否分配?       │                      │
│   └─────────────────┬───────────────────────┘                      │
│                     │                                               │
│         ┌───────────┴───────────┐                                  │
│         ▼                       ▼                                  │
│   Pod 异常                 Pod 正常                                 │
│   检查 CNI 日志            │                                       │
│                            ▼                                       │
│                   ┌─────────────────────────────────────┐         │
│                   │ 2. 检查同节点 Pod 互通               │         │
│                   │    kubectl exec pod1 -- ping pod2   │         │
│                   └─────────────────┬───────────────────┘         │
│                                     │                              │
│                         ┌───────────┴───────────┐                 │
│                         ▼                       ▼                 │
│                   同节点不通              同节点通                  │
│                   检查 CNI/网桥           │                        │
│                                          ▼                        │
│                                 ┌─────────────────────────────┐   │
│                                 │ 3. 检查跨节点 Pod 互通       │   │
│                                 └─────────────────┬───────────┘   │
│                                                   │               │
│                                       ┌───────────┴───────────┐   │
│                                       ▼                       ▼   │
│                                 跨节点不通              跨节点通   │
│                                 检查 Overlay/路由       │         │
│                                 检查防火墙              ▼         │
│                                                 ┌─────────────┐   │
│                                                 │ 4. 检查     │   │
│                                                 │ Service/DNS │   │
│                                                 └─────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

 

5.1.2 常用排查命令

 

# === Pod 层面 ===
# 查看 Pod 网络配置
kubectl exec -it  -- ip addr
kubectl exec -it  -- ip route
kubectl exec -it  -- cat /etc/resolv.conf

# 测试连通性
kubectl exec -it  -- ping 
kubectl exec -it  -- curl -v :
kubectl exec -it  -- nslookup 

# === 节点层面 ===
# 查看网桥和 veth
ip link show type bridge
ip link show type veth
brctl show  # 如果使用网桥模式

# 查看路由表
ip route show
ip route get 

# 查看 iptables 规则
iptables -t nat -L -n -v | grep 
iptables -t filter -L -n -v

# 查看 IPVS 规则
ipvsadm -Ln
ipvsadm -Ln --stats

# === CNI 层面 ===
# Cilium 状态检查
cilium status
cilium connectivity test

# Calico 状态检查
calicoctl node status
calicoctl get ippool -o wide

 

5.1.3 抓包分析

 

# 在节点上抓取特定 Pod 的流量
# 首先找到 Pod 的 veth 接口
POD_ID=$(crictl pods --name  -q)
VETH=$(ip link | grep -A1 "veth" | grep $POD_ID | awk '{print $2}' | tr -d ':')

# 抓包
tcpdump -i $VETH -nn -w pod-traffic.pcap

# 或者使用 nsenter 进入 Pod 网络命名空间
PID=$(crictl inspect $POD_ID | jq '.info.pid')
nsenter -t $PID -n tcpdump -i eth0 -nn

 

5.2 性能监控

5.2.1 关键指标

指标 正常范围 告警阈值 说明
DNS 查询延迟 < 5ms > 50ms CoreDNS 响应时间
Service 延迟 < 1ms > 10ms kube-proxy 转发延迟
跨节点延迟 < 1ms > 5ms Overlay 网络开销
conntrack 使用率 < 70% > 85% 连接跟踪表使用
丢包率 0% > 0.1% 网络丢包

5.2.2 Prometheus 监控配置

 

# 网络相关告警规则
apiVersion:monitoring.coreos.com/v1
kind:PrometheusRule
metadata:
name:network-alerts
spec:
groups:
-name:network
    rules:
    -alert:HighDNSLatency
      expr:histogram_quantile(0.99,rate(coredns_dns_request_duration_seconds_bucket[5m]))>0.05
      for:5m
      labels:
        severity:warning
      annotations:
        summary:"DNS 查询延迟过高"

    -alert:ConntrackTableFull
      expr:node_nf_conntrack_entries/node_nf_conntrack_entries_limit>0.85
      for:5m
      labels:
        severity:critical
      annotations:
        summary:"Conntrack 表即将满"

 

六、总结

6.1 技术要点回顾

Pod 网络模型:每个 Pod 独立 IP,同 Pod 容器共享网络命名空间

CNI 插件:2026年首选 Cilium,eBPF 带来性能和可观测性优势

Service 类型:ClusterIP(内部)、NodePort(测试)、LoadBalancer(生产)、ExternalName(外部)

kube-proxy 模式:大规模集群用 IPVS,新集群可尝试 nftables

DNS 解析:CoreDNS 负责服务发现,注意 ndots 配置优化

NetworkPolicy:白名单机制,生产环境必须配置

6.2 进阶学习方向

eBPF 深入学习

学习资源:Cilium 官方文档、eBPF.io

实践建议:部署 Hubble 可视化,学习 BPF 程序编写

服务网格(Service Mesh)

学习资源:Istio、Linkerd 官方文档

实践建议:理解 Sidecar 模式,对比 Cilium Service Mesh

多集群网络

学习资源:Cilium Cluster Mesh、Submariner

实践建议:搭建跨集群通信实验环境

6.3 参考资料

Kubernetes 官方网络文档

Cilium 官方文档

Calico 官方文档

CoreDNS 官方文档

附录

A. 命令速查表

 

# Pod 网络
kubectl get pod -o wide                    # 查看 Pod IP
kubectl exec -it  -- ip addr          # 查看 Pod 网络配置

# Service
kubectl get svc                            # 查看 Service
kubectl get endpoints                      # 查看 Endpoints

# DNS
kubectl run -it --rm debug --image=busybox -- nslookup 

# CNI
cilium status                              # Cilium 状态
calicoctl node status                      # Calico 状态

# kube-proxy
iptables -t nat -L KUBE-SERVICES -n        # iptables 规则
ipvsadm -Ln                                # IPVS 规则

 

B. 术语表

术语 英文 解释
CNI Container Network Interface 容器网络接口标准
IPAM IP Address Management IP 地址管理
VXLAN Virtual Extensible LAN 虚拟可扩展局域网
BGP Border Gateway Protocol 边界网关协议
eBPF extended Berkeley Packet Filter 扩展伯克利包过滤器

写在最后:K8s 网络确实复杂,但只要理解了核心概念,剩下的就是实践和积累。建议大家多动手搭建测试环境,用 tcpdump 抓包分析,这样才能真正掌握。有问题欢迎交流,我们下篇文章见!

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分