Kubernetes (K8S) 网络原理

Pod IP 分配机制

在 Kubernetes 中,每个 Pod 都需要一个唯一的 IP 地址来实现网络通信。本页将深入探讨 Kubernetes 如何为 Pod 分配 IP 地址,以及不同 CNI 插件的 IP 分配策略。

Pod IP 分配示意图

IP 地址分配基本原理

Kubernetes 集群中的 IP 地址分配遵循以下基本原则:

Pod CIDR 规划

在 Kubernetes 集群中,通常会为 Pod 网络分配一个大的 CIDR 块,然后将其划分为更小的子网,分配给各个节点。例如:

这种划分方式使得每个节点可以独立分配 IP 地址,而不需要与其他节点协调。

# 查看节点的 Pod CIDR 分配 kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' # 查看特定节点的 Pod CIDR kubectl get node -o jsonpath='{.spec.podCIDR}'

IPAM (IP 地址管理)

IPAM 是 CNI 插件的一个重要组件,负责 IP 地址的分配和回收。常见的 IPAM 插件包括:

host-local
dhcp
calico-ipam
whereabouts

host-local IPAM

host-local 是最常用的 IPAM 插件之一,它在每个节点上本地管理 IP 地址分配。

工作原理:

  1. 在节点的本地文件系统中维护已分配 IP 地址的记录(通常在 /var/lib/cni/networks/ 目录下)
  2. 从配置的子网中顺序分配可用 IP 地址
  3. 确保在同一节点上不会出现 IP 地址冲突
  4. 当 Pod 被删除时,释放相应的 IP 地址

配置示例:

{ "cniVersion": "0.3.1", "name": "mynet", "type": "bridge", "bridge": "cni0", "isGateway": true, "ipMasq": true, "ipam": { "type": "host-local", "subnet": "10.244.1.0/24", "routes": [ { "dst": "0.0.0.0/0" } ] } }

优缺点:

  • 优点:简单可靠,不依赖外部服务,适合大多数场景
  • 缺点:不支持跨节点协调,可能导致大型集群中的 IP 地址浪费

DHCP IPAM

DHCP IPAM 插件使用 DHCP 协议为 Pod 分配 IP 地址。

工作原理:

  1. 启动一个 DHCP 客户端守护进程
  2. 当需要为 Pod 分配 IP 地址时,向 DHCP 服务器发送请求
  3. 接收 DHCP 服务器分配的 IP 地址,并配置到 Pod 的网络接口
  4. 定期续约 DHCP 租约

配置示例:

{ "cniVersion": "0.3.1", "name": "mynet", "type": "bridge", "bridge": "cni0", "isGateway": true, "ipam": { "type": "dhcp" } }

优缺点:

  • 优点:可以集中管理 IP 地址,与现有的 DHCP 基础设施集成
  • 缺点:依赖 DHCP 服务器,增加了复杂性和潜在的故障点

Calico IPAM

Calico IPAM 是 Calico CNI 插件的一部分,提供了分布式的 IP 地址管理功能。

工作原理:

  1. 使用 Kubernetes API 或 etcd 作为后端存储
  2. 为每个节点分配一个 IP 池(CIDR 块)
  3. 支持 IP 地址的动态分配和静态分配
  4. 提供 IP 地址的回收和重用机制

配置示例:

{ "cniVersion": "0.3.1", "name": "calico-network", "type": "calico", "ipam": { "type": "calico-ipam", "assign_ipv4": "true", "ipv4_pools": ["10.244.0.0/16"] } }

优缺点:

  • 优点:支持大规模集群,提供高级功能如 IP 池管理和 IP 地址亲和性
  • 缺点:配置相对复杂,依赖外部存储

Whereabouts IPAM

Whereabouts 是一个相对较新的 IPAM 插件,专为大规模 Kubernetes 集群设计。

工作原理:

  1. 使用 Kubernetes CRD(自定义资源定义)存储 IP 地址分配信息
  2. 支持跨节点的 IP 地址协调,避免冲突
  3. 提供范围内的 IP 地址分配,而不是按节点分配子网
  4. 支持多个 IP 范围和排除范围

配置示例:

{ "cniVersion": "0.3.1", "name": "whereabouts-network", "type": "bridge", "bridge": "cni0", "isGateway": true, "ipam": { "type": "whereabouts", "range": "10.244.0.0/16", "exclude": [ "10.244.0.0/24", "10.244.1.0/24" ], "log_file": "/tmp/whereabouts.log", "log_level": "info" } }

优缺点:

  • 优点:高效利用 IP 地址空间,适合大规模集群,不需要预先分配节点子网
  • 缺点:相对较新,可能存在稳定性问题,依赖 Kubernetes API

不同 CNI 插件的 IP 分配策略

不同的 CNI 插件采用不同的 IP 分配策略,以下是几种常见 CNI 插件的 IP 分配方式:

Flannel

Flannel 使用相对简单的 IP 分配策略:

  • 在集群初始化时,为每个节点分配一个固定大小的子网(通常是 /24)
  • 使用 host-local IPAM 插件在节点本地管理 IP 地址分配
  • 子网信息存储在 etcd 或 Kubernetes API 中
  • 当节点加入集群时,会获得一个唯一的子网

例如,如果集群 Pod CIDR 是 10.244.0.0/16,则:

  • 节点 1 可能获得 10.244.1.0/24
  • 节点 2 可能获得 10.244.2.0/24

这种方式简单可靠,但在大型集群中可能导致 IP 地址空间浪费。

Calico

Calico 提供了更灵活的 IP 分配策略:

  • 支持多个 IP 池,可以为不同的工作负载分配不同的 IP 池
  • 可以配置 IP 池的块大小(blockSize),默认为 /26
  • 按需为节点分配 IP 块,而不是预先分配固定大小的子网
  • 支持 IP 地址亲和性,可以尝试为重新创建的 Pod 分配相同的 IP 地址
  • 提供 IP 地址预留功能,可以排除特定的 IP 地址或范围

Calico 的 IP 分配更加灵活和高效,适合大型和复杂的集群环境。

Weave Net

Weave Net 使用分散式的 IP 分配策略:

  • 每个节点负责一部分 IP 地址空间的分配
  • 节点之间使用 gossip 协议同步 IP 分配信息
  • 支持 IP 地址范围的分裂和合并,以适应集群的变化
  • 不依赖中央数据存储,提高了可靠性

Weave Net 的分散式设计使其在网络分区等情况下仍能继续工作。

Cilium

Cilium 基于 eBPF 技术,提供了高级的 IP 分配功能:

  • 支持集中式和分布式的 IP 分配模式
  • 可以使用 CRD 或 etcd 存储 IP 分配信息
  • 支持 IPv4 和 IPv6 双栈
  • 提供基于身份的寻址,减少对 IP 地址的依赖
  • 支持 IP 地址池和范围管理

Cilium 的 IP 分配策略与其基于身份的安全模型紧密集成,提供了更强大的网络控制能力。

Pod IP 分配的最佳实践

在规划和管理 Kubernetes 集群的 Pod IP 分配时,可以参考以下最佳实践:

1. CIDR 规划

2. IP 地址管理

3. 故障处理

4. 安全考虑

故障排除

在 Pod IP 分配过程中可能遇到的常见问题及解决方法:

IP 地址冲突

症状:Pod 无法启动,日志中显示 IP 地址已被使用

可能原因:

  • IPAM 数据不一致
  • 多个 IPAM 实例管理同一 IP 范围
  • 手动配置的静态 IP 与动态分配的 IP 冲突

解决方法:

# 检查已分配的 IP 地址 kubectl get pods -o wide --all-namespaces # 检查 IPAM 存储 # 对于 host-local IPAM ls -la /var/lib/cni/networks/ # 对于 Calico kubectl get ipamblocks -o yaml # 清理孤立的 IP 分配记录 rm -f /var/lib/cni/networks/*/10.244.1.2 # 重启 CNI 相关组件 kubectl rollout restart ds -n kube-system calico-node

IP 地址耗尽

症状:新 Pod 无法获取 IP 地址,卡在 ContainerCreating 状态

可能原因:

  • 节点的 IP 地址池已用尽
  • CIDR 块太小,无法容纳所有 Pod
  • IP 地址泄漏,已删除的 Pod 的 IP 没有被释放

解决方法:

# 检查节点的 Pod CIDR 使用情况 kubectl get pods -o wide --all-namespaces | grep # 对于 Calico,扩展 IP 池 kubectl patch ippool default-ipv4-ippool -p '{"spec":{"cidr":"10.244.0.0/16"}}' # 清理未释放的 IP 地址 # 这需要根据具体的 CNI 插件采取不同的操作

IP 分配延迟

症状:Pod 创建时间较长,主要卡在获取 IP 地址的阶段

可能原因:

  • IPAM 插件性能问题
  • 外部依赖(如 DHCP 服务器)响应慢
  • 集群规模大,IPAM 处理压力大

解决方法:

  • 优化 IPAM 配置,如增加缓存
  • 考虑使用更高效的 IPAM 插件
  • 检查和优化外部依赖服务
  • 分析 CNI 插件日志,找出瓶颈

相关资源

要了解更多关于 Pod IP 分配的信息,可以参考以下资源:

了解 Pod 内部网络