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
|
type NetworkPlugin interface { Init(host Host, hairpinMode bool, nonMasqueradeCIDR string) error
Name() string
Status() error
Event(name string, details map[string]interface{}) }
type PodNetwork interface { SetUpPod(namespace, name string, podSandboxID container.ContainerID) error
TearDownPod(namespace, name string, podSandboxID container.ContainerID) error
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
| 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 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
|
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
| ls /etc/cni/net.d/
ls /opt/cni/bin/
journalctl -u kubelet | grep -i cni
|
2. DNS 解析失败
1 2 3 4 5 6 7 8
| kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl exec -it <pod> -- nslookup kubernetes.default
kubectl exec -it <pod> -- cat /etc/resolv.conf
|
3. 网络不通
1 2 3 4 5 6 7 8
| ip addr show
ip route show
iptables -t nat -L -n -v
|
4. IP 地址耗尽
1 2 3 4 5
| ls /var/lib/cni/networks/
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. 并行网络操作
3. 连接复用
- 容器复用 Pod 网络命名空间
- 仅首次创建时配置网络
面试题
基础题
1. 什么是 CNI?它的作用是什么?
参考答案:
CNI (Container Network Interface) 是 Kubernetes 的网络插件标准,负责:
- 为 Pod 分配 IP 地址
- 配置 Pod 的网络接口
- 实现 Pod 之间、Pod 与 Service 之间的网络通信
- 管理网络策略(部分插件)
2. Kubernetes 对网络有什么基本要求?
参考答案:
Kubernetes 网络模型要求:
- 所有 Pod 不使用 NAT 就能相互通信
- 所有 Node 不使用 NAT 就能与所有 Pod 通信
- 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
| CNI_COMMAND=ADD CNI_CONTAINERID=xxx CNI_NETNS=/proc/xxx/ns/net \ /opt/cni/bin/bridge < config.json
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
| kubectl exec -it <pod> -- ping <target-ip> kubectl exec -it <pod> -- curl -v http://<service>:<port>
ping <pod-ip>
|
4. 检查 CNI 配置:
1 2 3 4 5 6
| ls /etc/cni/net.d/ cat /etc/cni/net.d/*.conflist
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
| kubectl logs -n kube-system -l app=flannel
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
| apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-from-other-namespaces namespace: production spec: podSelector: {} 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
| kubectl exec -it <pod> -- cat /etc/resolv.conf
spec: dnsConfig: options: - name: ndots value: "2"
|
3. 检查上游 DNS:
1 2
| kubectl exec -it <pod> -- time nslookup google.com 8.8.8.8
|
4. 启用 CoreDNS 缓存:
1 2 3 4 5
| Corefile: | .:53 { cache 100 # 缓存 100 条记录 }
|
5. 检查 Conntrack:
1 2 3 4 5 6
|
spec: dnsConfig: options: - name: use-vc
|
16. 大规模集群如何选择 CNI 插件?
参考答案:
评估因素:
| 因素 |
Flannel |
Calico |
Cilium |
| 节点规模 |
<1000 |
<5000 |
>5000 |
| Pod 密度 |
低 |
中 |
高 |
| NetworkPolicy |
不支持 |
支持 |
支持 |
| 性能 |
一般 |
好 |
最好 |
| 可观测性 |
差 |
中 |
好 |
| 运维复杂度 |
低 |
中 |
高 |
推荐方案:
**小型集群 (<500 节点)**:
- 简单场景:Flannel
- 需要策略:Canal (Flannel + Calico 策略)
**中型集群 (500-2000 节点)**:
- Calico + IPIP 模式
- 或 Cilium
**大型集群 (>2000 节点)**:
- Cilium (eBPF 性能最优)
- 或 Calico + eBPF
优化建议:
1 2 3 4 5 6
| apiVersion: cilium.io/v1 kind: CiliumOperatorConfig spec: operator: enableCiliumEndpointSlice: true
|