CNI 网络插件流程

概述

CNI (Container Network Interface) 是 Kubernetes 的网络插件标准,负责为 Pod 配置网络接口、IP 地址分配和网络连通性。

核心架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
┌──────────────────────────────────────────────────────────────────────────────┐
│ kubelet │
│ pkg/kubelet/kubelet.go │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Pod 生命周期管理 │ │
│ │ syncPod -> managePodLifecycle │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ Runtime │
│ pkg/kubelet/kuberuntime/ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Pod Sandbox 创建 │ │
│ │ RunPodSandbox (CRI Runtime) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ Network Plugin │
│ pkg/kubelet/network/ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ cni.go │ │kubenet.go │ │hostport.go │ │ dns.go │ │
│ │ CNI 插件 │ │ 简单 bridge │ │ 端口映射 │ │ DNS 配置 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ CNI Plugin (二进制) │
│ /opt/cni/bin/ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ bridge │ │ ptp │ │ host-local│ │ portmap │ │
│ │ 网桥插件 │ │ 点对点 │ │ IPAM │ │ 端口映射 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ flannel │ │ calico │ │ weave │ ... │
│ │ 第三方插件 │ │ 第三方插件 │ │ 第三方插件 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘

核心接口

CNI Plugin 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// pkg/kubelet/network/cni/cni.go

type NetworkPlugin interface {
// 初始化插件
Init(host Host, hairpinMode bool, nonMasqueradeCIDR string) error

// 名称
Name() string

// 获取 Pod 网络状态
Status() error

// 事件通知
Event(name string, details map[string]interface{})
}

type PodNetwork interface {
// 设置 Pod 网络
SetUpPod(namespace, name string, podSandboxID container.ContainerID) error

// 拆除 Pod 网络
TearDownPod(namespace, name string, podSandboxID container.ContainerID) error

// 获取 Pod 网络状态
GetPodNetworkStatus(namespace, name string, podSandboxID container.ContainerID) (*PodNetworkStatus, error)

// 获取网络信息
GetPodNetwork(namespace, name string, id container.ContainerID) (NetworkResult, error)
}

CNI 配置结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// CNI 配置文件格式 (/etc/cni/net.d/*.conflist)
type NetworkConfigList struct {
Name string
Version string
Plugins []*NetworkConfig
}

type NetworkConfig struct {
Name string
Type string
IPAM IPAMConfig
DNS DNSConfig
// 插件特定配置
}

type IPAMConfig struct {
Type string // host-local, dhcp, calico-ipam 等
Subnet string
RangeStart string
RangeEnd string
Gateway string
Routes []Route
}

网络配置流程

Pod 创建时的网络配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
┌──────────────────────────────────────────────────────────────────────────────┐
│ Pod 创建请求 │
│ kube-apiserver -> kubelet │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ kubelet syncPod │
│ pkg/kubelet/kubelet.go │
│ │
│ 1. 计算网络配置 (generatePodSandboxConfig) │
│ - DNS 配置 │
│ - PortMappings │
│ - Hostname │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ 创建 Pod Sandbox │
│ pkg/kubelet/kuberuntime/kuberuntime_sandbox.go │
│ │
│ 1. 调用 CRI Runtime (containerd/cri-o) │
│ 2. Runtime 调用 CNI 插件 │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ CNI 网络配置 (SetUpPod) │
│ pkg/kubelet/network/cni/cni.go │
│ │
│ 1. 加载 CNI 配置文件 │
│ /etc/cni/net.d/*.conflist │
│ │
│ 2. 构建 CNI 参数 │
│ - ContainerID │
│ - Pod Namespace/Name │
│ - Pod Network Namespace │
│ │
│ 3. 执行 CNI 插件 │
│ ADD 命令 -> /opt/cni/bin/<plugin> │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ CNI 插件执行 │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 1. 主插件 (bridge/ptp/flannel/calico) │ │
│ │ - 创建网络接口 │ │
│ │ - 连接到网络 │ │
│ │ - 配置 IP 地址 (调用 IPAM) │ │
│ │ - 配置路由 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 2. IPAM 插件 (host-local/dhcp) │ │
│ │ - 分配 IP 地址 │ │
│ │ - 记录分配状态 │ │
│ │ - 配置网关 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 3. 链式插件 (portmap/tuning/bandwidth) │ │
│ │ - 端口映射 (portmap) │ │
│ │ - sysctl 配置 (tuning) │ │
│ │ - 带宽限制 (bandwidth) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ 返回网络结果 │
│ │
│ { │
│ "cniVersion": "1.0.0", │
│ "interfaces": [ │
│ { │
│ "name": "eth0", │
│ "mac": "0a:58:0a:f4:02:01", │
│ "sandbox": "/proc/12345/ns/net" │
│ } │
│ ], │
│ "ips": [ │
│ { │
│ "version": "4", │
│ "address": "10.244.2.1/24", │
│ "gateway": "10.244.2.0" │
│ } │
│ ], │
│ "routes": [ │
│ { │
│ "dst": "0.0.0.0/0", │
│ "gw": "10.244.2.0" │
│ } │
│ ], │
│ "dns": { │
│ "nameservers": ["10.96.0.10"], │
│ "domain": "cluster.local", │
│ "search": ["default.svc.cluster.local"] │
│ } │
│ } │
└──────────────────────────────────────────────────────────────────────────────┘

Pod 删除时的网络清理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──────────────────────────────────────────────────────────────────────────────┐
│ Pod 删除请求 │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ CNI 网络清理 (TearDownPod) │
│ │
│ 1. 执行 CNI 插件 DEL 命令 │
│ /opt/cni/bin/<plugin> DEL < config │
│ │
│ 2. 主插件清理 │
│ - 删除网络接口 │
│ - 断开网络连接 │
│ │
│ 3. IPAM 插件清理 │
│ - 释放 IP 地址 │
│ - 清理分配记录 │
└──────────────────────────────────────────────────────────────────────────────┘

常见 CNI 插件

1. Bridge 插件

1
2
3
4
5
6
7
8
9
10
11
12
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/16",
"routes": [{"dst": "0.0.0.0/0"}]
}
}

2. Flannel

1
2
3
4
5
6
7
8
{
"name": "cbr0",
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
}

3. Calico

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"name": "k8s-pod-network",
"type": "calico",
"etcd_endpoints": "http://10.96.232.136:6666",
"etcd_key_file": "",
"etcd_cert_file": "",
"etcd_ca_cert_file": "",
"log_level": "info",
"ipam": {
"type": "calico-ipam"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
}

DNS 配置流程

Pod DNS 配置

  • 文件: pkg/kubelet/network/dns/dns.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──────────────────────────────────────────────────────────────────────────────┐
│ DNS 配置来源 │
│ │
│ 1. ClusterFirst (默认) │
│ - 使用 CoreDNS (ClusterIP: 10.96.0.10) │
│ - 搜索域: <ns>.svc.cluster.local, svc.cluster.local, cluster.local │
│ │
│ 2. Default │
│ - 继承节点 DNS 配置 │
│ │
│ 3. None │
│ - 自定义 DNS 配置 │
│ - 需要指定 nameservers, searches, options │
└──────────────────────────────────────────────────────────────────────────────┘

DNS 配置生成

1
2
3
4
5
6
7
8
9
10
11
12
// pkg/kubelet/network/dns/dns.go

func (d *dnsConfigurer) GenerateDNSConfig(pod *v1.Pod) (*runtimeapi.DNSConfig, error) {
switch pod.Spec.DNSPolicy {
case v1.DNSClusterFirst:
return d.getClusterFirstDNS(pod)
case v1.DNSDefault:
return d.getDefaultDNS()
case v1.DNSNone:
return d.getCustomDNS(pod)
}
}

IPAM (IP 地址管理)

host-local IPAM

1
2
3
4
5
6
7
8
9
10
11
{
"type": "host-local",
"subnet": "10.244.1.0/24",
"rangeStart": "10.244.1.10",
"rangeEnd": "10.244.1.200",
"gateway": "10.244.1.1",
"routes": [
{"dst": "0.0.0.0/0"}
],
"dataDir": "/var/lib/cni/networks"
}

IP 分配流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
┌──────────────────────────────────────────────────────────────────────────────┐
│ IPAM ADD 请求 │
│ 分配 IP 地址 │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ 检查分配记录 │
│ /var/lib/cni/networks/<network>/<ip> │
│ │
│ 如果已存在该 ContainerID 的记录,返回已分配的 IP │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ 分配新 IP 地址 │
│ │
│ 1. 从 rangeStart 到 rangeEnd 遍历 │
│ 2. 检查 IP 是否已分配 (文件是否存在) │
│ 3. 找到未分配的 IP │
│ 4. 创建分配记录文件 │
│ /var/lib/cni/networks/<network>/<ip> -> ContainerID │
└──────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│ 返回分配结果 │
│ │
│ { │
│ "cniVersion": "1.0.0", │
│ "ips": [{ │
│ "version": "4", │
│ "address": "10.244.1.20/24", │
│ "gateway": "10.244.1.1" │
│ }], │
│ "routes": [{"dst": "0.0.0.0/0", "gw": "10.244.1.1"}] │
│ } │
└──────────────────────────────────────────────────────────────────────────────┘

关键代码路径

文件 说明
pkg/kubelet/network/cni/cni.go CNI 插件实现
pkg/kubelet/network/dns/dns.go DNS 配置
pkg/kubelet/network/hostport/ HostPort 管理
staging/src/k8s.io/cri-api/ CRI 接口定义

常见问题排查

1. Pod 无 IP 地址

1
2
3
4
5
6
7
8
# 检查 CNI 配置
ls /etc/cni/net.d/

# 检查 CNI 二进制
ls /opt/cni/bin/

# 检查 kubelet 日志
journalctl -u kubelet | grep -i cni

2. DNS 解析失败

1
2
3
4
5
6
7
8
# 检查 CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 测试 DNS 解析
kubectl exec -it <pod> -- nslookup kubernetes.default

# 检查 Pod DNS 配置
kubectl exec -it <pod> -- cat /etc/resolv.conf

3. 网络不通

1
2
3
4
5
6
7
8
# 检查网络接口
ip addr show

# 检查路由
ip route show

# 检查 iptables
iptables -t nat -L -n -v

4. IP 地址耗尽

1
2
3
4
5
# 检查 IPAM 分配
ls /var/lib/cni/networks/

# 清理已释放的 IP
rm /var/lib/cni/networks/<network>/<ip>

网络策略支持

Calico NetworkPolicy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080

性能优化

1. 网络配置缓存

  • kubelet 缓存 CNI 配置
  • 减少配置文件读取

2. 并行网络操作

  • 多个 Pod 并行配置网络
  • IPAM 批量分配

3. 连接复用

  • 容器复用 Pod 网络命名空间
  • 仅首次创建时配置网络

面试题

基础题

1. 什么是 CNI?它的作用是什么?

参考答案:
CNI (Container Network Interface) 是 Kubernetes 的网络插件标准,负责:

  • 为 Pod 分配 IP 地址
  • 配置 Pod 的网络接口
  • 实现 Pod 之间、Pod 与 Service 之间的网络通信
  • 管理网络策略(部分插件)

2. Kubernetes 对网络有什么基本要求?

参考答案:
Kubernetes 网络模型要求:

  1. 所有 Pod 不使用 NAT 就能相互通信
  2. 所有 Node 不使用 NAT 就能与所有 Pod 通信
  3. Pod 看到的自己 IP 与其他人看到的相同

总结:扁平网络,IP 唯一,无 NAT

3. 常见的 CNI 插件有哪些?

参考答案:

插件 特点 适用场景
Flannel 简单、支持多种后端 小型集群
Calico 支持 NetworkPolicy、性能好 生产环境
Weave 简单、自动拓扑 中小型集群
Cilium eBPF、高性能、可观测性 大规模集群
Canal Flannel 网络 + Calico 策略 需要策略的小集群

中级题

4. Pod 创建时 CNI 网络配置的完整流程是怎样的?

参考答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. kubelet 收到 Pod 创建请求

2. 调用 CRI Runtime (containerd/cri-o)

3. CRI 调用 RunPodSandbox

4. CRI Runtime 加载 CNI 配置 (/etc/cni/net.d/*.conflist)

5. 执行 CNI 插件 (/opt/cni/bin/<plugin>)
├── 主插件 (bridge/ptp/vxlan) 创建网络接口
├── IPAM 插件 分配 IP
└── 链式插件 (portmap/tuning)

6. 返回网络配置结果 (IP、路由、DNS)

7. Pod 网络就绪

5. CNI 配置文件的结构是怎样的?

参考答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"cniVersion": "1.0.0",
"name": "k8s-pod-network",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/16",
"routes": [{"dst": "0.0.0.0/0"}]
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}

关键字段

  • cniVersion:CNI 版本
  • name:网络名称
  • plugins:插件链
  • type:插件类型
  • ipam:IP 地址管理配置

6. 解释 IPAM 的作用和常见类型。

参考答案:
IPAM (IP Address Management) 负责 IP 地址分配。

常见类型

类型 说明 适用场景
host-local 本地文件存储分配记录 单节点
dhcp 通过 DHCP 服务器分配 传统网络
calico-ipam Calico 的 IPAM Calico 网络
whereabouts 分布式 IPAM 多节点

host-local 工作原理

1
2
3
4
分配 IP -> 写入 /var/lib/cni/networks/<network>/<ip>
内容为 ContainerID

释放 IP -> 删除对应文件

7. CNI ADD 和 DEL 命令分别做什么?

参考答案:

ADD 命令

  • 创建网络接口
  • 分配 IP 地址
  • 配置路由
  • 设置 DNS
  • 返回网络配置结果

DEL 命令

  • 删除网络接口
  • 释放 IP 地址
  • 清理 iptables 规则
  • 清理分配记录
1
2
3
4
5
6
7
# ADD 示例
CNI_COMMAND=ADD CNI_CONTAINERID=xxx CNI_NETNS=/proc/xxx/ns/net \
/opt/cni/bin/bridge < config.json

# DEL 示例
CNI_COMMAND=DEL CNI_CONTAINERID=xxx CNI_NETNS=/proc/xxx/ns/net \
/opt/cni/bin/bridge < config.json

高级题

8. Flannel 的工作原理是什么?

参考答案:
Flannel 为每个 Node 分配一个子网,通过 Overlay 网络实现跨节点通信。

架构

1
2
3
4
5
6
7
8
9
10
Node A (10.244.1.0/24)          Node B (10.244.2.0/24)
┌──────────────────┐ ┌──────────────────┐
│ Pod (10.244.1.5) │ │ Pod (10.244.2.3) │
└────────┬─────────┘ └────────┬─────────┘
│ │
cni0 bridge cni0 bridge
│ │
flannel.1 (VXLAN) flannel.1 (VXLAN)
│ │
└──────── VxLAN Tunnel ────────┘

后端类型

  • VXLAN:默认,Overlay 网络
  • host-gw:直接路由,性能好
  • UDP:用户态,性能差
  • WireGuard:加密

数据流

1
2
3
Pod A 发包 -> cni0 -> flannel.1 (VXLAN 封装)
-> eth0 -> 网络 -> Node B eth0
-> flannel.1 (解封) -> cni0 -> Pod B

9. Calico 与 Flannel 有什么区别?

参考答案:

特性 Flannel Calico
网络模式 Overlay (VXLAN) 路由 (BGP)
性能 一般 更好
NetworkPolicy 不支持 支持
复杂度 简单 复杂
IPAM 简单 灵活
规模 小型 大型
跨子网 支持 需要 IPIP

Calico 工作原理

1
2
3
4
5
1. Felix Agent 在每个 Node 运行
2. 配置本地路由表
3. BIRD BGP 客户端广播路由
4. 节点间通过 BGP 交换路由信息
5. 形成全网路由表

10. 解释 Kubernetes 的 DNS 解析流程。

参考答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────┐
│ Pod 发起 DNS 请求 │
│ nslookup kubernetes.default │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ /etc/resolv.conf │
│ nameserver 10.96.0.10 # CoreDNS ClusterIP │
│ search default.svc.cluster.local svc.cluster.local │
│ cluster.local │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ CoreDNS 处理请求 │
│ │
│ 1. 检查缓存 │
│ 2. 判断域名类型 │
│ ├── 集群内域名 -> Kubernetes 插件处理 │
│ └── 外部域名 -> forward 插件转发 │
│ 3. 返回结果 │
└─────────────────────────────────────────────────────────────┘

CoreDNS 配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
endpoint https://10.96.0.1:443
}
forward . /etc/resolv.conf
cache 30
loop
reload
}

11. Pod 的 DNS 策略有哪些?

参考答案:

1
2
spec:
dnsPolicy: ClusterFirst # 可选值
策略 说明
ClusterFirst 默认,优先使用集群 DNS
Default 使用节点 DNS 配置
ClusterFirstWithHostNet 主机网络 + 集群 DNS
None 自定义 DNS 配置

None 策略示例

1
2
3
4
5
6
7
8
9
10
spec:
dnsPolicy: None
dnsConfig:
nameservers:
- 8.8.8.8
searches:
- my.domain.com
options:
- name: ndots
value: "2"

12. 如何排查 Pod 网络问题?

参考答案:

1. 检查 Pod IP

1
2
kubectl get pod <name> -o wide
kubectl describe pod <name> | grep -A 5 "IP:"

2. 检查 DNS 解析

1
2
kubectl exec -it <pod> -- nslookup kubernetes.default
kubectl exec -it <pod> -- cat /etc/resolv.conf

3. 检查网络连通性

1
2
3
4
5
6
# 从 Pod 内测试
kubectl exec -it <pod> -- ping <target-ip>
kubectl exec -it <pod> -- curl -v http://<service>:<port>

# 从 Node 测试
ping <pod-ip>

4. 检查 CNI 配置

1
2
3
4
5
6
# 查看配置文件
ls /etc/cni/net.d/
cat /etc/cni/net.d/*.conflist

# 查看 CNI 二进制
ls /opt/cni/bin/

5. 检查 iptables

1
2
iptables -t nat -L -n -v
iptables -L -n -v

6. 检查 CNI 插件日志

1
2
3
4
5
# Flannel
kubectl logs -n kube-system -l app=flannel

# Calico
kubectl logs -n kube-system -l k8s-app=calico-node

场景题

13. 如何实现跨命名空间的网络隔离?

参考答案:
使用 NetworkPolicy

1
2
3
4
5
6
7
8
9
10
11
12
13
# 只允许同一命名空间的 Pod 访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: production
spec:
podSelector: {} # 应用到所有 Pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # 只允许同命名空间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 允许特定命名空间访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-monitoring
namespace: production
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring

注意:需要 CNI 插件支持 NetworkPolicy(Calico、Cilium 支持,Flannel 不支持)。

14. 如何实现 Pod 固定 IP?

参考答案:

方案 1:使用 Calico IP Pool

1
2
3
4
5
6
7
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: fixed-ip-pool
spec:
cidr: 10.244.10.0/24
blockSize: 32 # 每个地址一个块

方案 2:使用 Calico IP Reservation

1
2
3
4
5
6
7
8
apiVersion: projectcalico.org/v3
kind: IPReservation
metadata:
name: my-reservation
spec:
reservedCIDRs:
- 10.244.0.10/32
- 10.244.0.11/32

方案 3:使用 Annotations

1
2
3
4
5
apiVersion: v1
kind: Pod
metadata:
annotations:
cni.projectcalico.org/ipAddrs: "[\"10.244.0.10\"]"

15. 如何排查 CoreDNS 解析慢的问题?

参考答案:

1. 检查 CoreDNS 状态

1
2
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns

2. 检查 ndots 配置

1
2
3
4
5
6
7
8
9
# 默认 ndots=5,会导致多次查询
kubectl exec -it <pod> -- cat /etc/resolv.conf

# 优化:减少 ndots
spec:
dnsConfig:
options:
- name: ndots
value: "2"

3. 检查上游 DNS

1
2
# 测试上游 DNS 延迟
kubectl exec -it <pod> -- time nslookup google.com 8.8.8.8

4. 启用 CoreDNS 缓存

1
2
3
4
5
# CoreDNS ConfigMap
Corefile: |
.:53 {
cache 100 # 缓存 100 条记录
}

5. 检查 Conntrack

1
2
3
4
5
6
# UDP 连接跟踪可能导致 DNS 超时
# 解决:使用 TCP DNS
spec:
dnsConfig:
options:
- name: use-vc

16. 大规模集群如何选择 CNI 插件?

参考答案:

评估因素

因素 Flannel Calico Cilium
节点规模 <1000 <5000 >5000
Pod 密度
NetworkPolicy 不支持 支持 支持
性能 一般 最好
可观测性
运维复杂度

推荐方案

  1. **小型集群 (<500 节点)**:

    • 简单场景:Flannel
    • 需要策略:Canal (Flannel + Calico 策略)
  2. **中型集群 (500-2000 节点)**:

    • Calico + IPIP 模式
    • 或 Cilium
  3. **大型集群 (>2000 节点)**:

    • Cilium (eBPF 性能最优)
    • 或 Calico + eBPF

优化建议

1
2
3
4
5
6
# Cilium 高性能配置
apiVersion: cilium.io/v1
kind: CiliumOperatorConfig
spec:
operator:
enableCiliumEndpointSlice: true # 减少控制平面压力