从 Docker CNM 到 Kubernetes CNI:容器网络模型的演进

容器技术彻底改变了软件的开发、部署和运行方式,而容器网络作为其基石,经历了从早期 Docker Container Network Model (CNM) Kubernetes 广泛采用的 Container Network Interface (CNI) 的显著演进。这一演进不仅反映了容器生态系统的成熟,也体现了对更灵活、可扩展和标准化的网络解决方案的需求。

 

### 一、Docker CNM:容器网络的初步探索

 

Kubernetes 崛起之前,Docker 作为容器技术的先行者,提出了自己的容器网络模型――CNM (Container Network Model)CNM 旨在为 Docker 容器提供网络连接,并抽象化底层网络的复杂性,以实现容器的便携性。

 

#### 1. CNM 的核心概念与 Libnetwork

 

CNM 的核心思想围绕着三个基本构建块:

*   **Sandbox(沙盒)**:代表一个独立的网络栈,包含容器的网络接口、DNS 配置、端口映射和路由表等。 在 Docker 中,每个容器都有自己的网络命名空间,这就是一个沙盒。

*   **Endpoint(端点)**:是一个虚拟网络接口,用于将沙盒连接到网络。 通常以一对的形式出现,一端在容器内,另一端在网络内。一个容器可以有多个端点,每个端点可以加入一个网络。

*   **Network(网络)**:是端点的集合,集合内的所有端点可以相互通信。 网络的实现可以是 Linux 网桥(如 Docker 默认的 `docker0`),也可以是 VLAN 等。

 

Libnetwork CNM 的原生实现,它是一个开源库,为 Docker daemon 和网络驱动程序之间提供了接口。 Libnetwork 负责管理网络的创建、删除,以及 IP 地址分配(通过 IPAM 插件)。 Docker 通过网络驱动程序实现不同的网络拓扑,例如:

*   **Bridge(桥接模式)**:默认的网络驱动,在主机上创建一个私有网络,容器可以通过端口映射与外部通信。

*   **Host(主机模式)**:容器直接共享宿主机的网络命名空间,移除容器与宿主机之间的网络隔离。

*   **Overlay(覆盖网络)**:用于跨多个 Docker 主机进行通信,通常用于 Docker Swarm 等集群环境。

 

CNM 允许用户通过标签(labels)定义元数据,从而自定义 Libnetwork 和驱动程序的行为。

 

#### 2. CNM 的局限性

 

尽管 CNM Docker 容器提供了基本的网络能力,但随着容器编排技术的发展,其局限性也逐渐显现:

*   ** Docker 运行时紧密耦合**CNM 主要为 Docker 运行时设计,与非 Docker 容器运行时集成较为困难。

*   **多主机网络复杂性**:在多主机环境下,CNM 的网络配置和管理相对复杂,需要依赖分布式键值存储(如 Consul)来存储网络配置。

*   **缺乏标准化**CNM Docker 提出的规范,虽然有其他项目采纳,但并非一个被广泛接受的行业标准。

 

### 二、Kubernetes CNI:标准化与开放生态

 

随着 Kubernetes 成为容器编排的事实标准,对一个更开放、更灵活的容器网络模型的需求变得迫切。CoreOS Google 联合制定了 Container Network Interface (CNI) 标准,旨在定义容器网络模型的规范,并连接容器管理系统和网络插件。

 

#### 1. CNI 的核心理念与优势

 

CNI 是一个由 Cloud Native Computing Foundation (CNCF) 定义的开放标准,它提供了一个框架,用于动态配置网络资源。 CNI 的核心理念是将网络配置的实现与容器运行时解耦,只关注容器网络接口的配置和管理。

 

CNI 的主要优势包括:

*   **标准化接口**CNI 定义了一套标准的接口规范,使得不同的容器运行时(如 Kubernetes)可以与各种网络插件无缝集成。

*   **插件化架构**CNI 采用插件化架构,允许第三方供应商开发和提供各种高级网络功能,促进了容器网络生态系统的创新。 这使得 Kubernetes 用户可以根据自身需求选择最合适的网络解决方案。

*   **简化网络配置**CNI 插件负责处理容器网络相关的逻辑,包括创建网络接口、分配 IP 地址、设置路由规则等,极大地简化了网络配置过程。 在没有 CNI 的情况下,用户需要手动完成大量网络配置操作,例如创建接口、设置网络命名空间、配置网桥、分配 IP 地址等。

*   ** Kubernetes 深度集成**:当 Pod Kubernetes 集群中调度时,kubelet 会调用 CNI 插件来配置 Pod 的网络,并在 Pod 终止时清理相关资源。 这确保了网络配置与容器的生命周期管理紧密协调。

 

#### 2. Kubernetes 网络模型的需求

 

Kubernetes 的网络模型有以下几个核心需求:

*   **Pod IP**:每个 Pod 拥有独立的 IP 地址,允许 Pod 之间直接通信,无需进行网络地址转换 (NAT)

*   **Pod Pod 通信**:同一节点上的 Pod 之间可以通过虚拟网桥通信;不同节点上的 Pod 之间需要通过覆盖网络或路由实现通信。

*   **Pod Service 通信**Service 提供稳定的虚拟 IP 地址和 DNS 入口,将请求负载均衡到后端 Pod CNI 在实现 Pod Service 之间的通信中扮演关键角色。

*   **Pod 到外部通信**Pod 可以与集群外部的服务进行通信。

*   **外部到 Service 通信**:外部客户端可以通过 Service 访问集群内部的服务。

 

CNI 插件的目标就是满足这些需求,并提供灵活的实现方式。

 

### 三、常见的 CNI 网络插件:Calico Flannel

 

Kubernetes 容器生态中,涌现了众多 CNI 网络插件,其中 Calico Flannel 是两个非常流行且各有特点的实现。

 

#### 1. Flannel:简单轻量级的覆盖网络

 

Flannel 是一个简单轻量级的 CNI 插件,主要用于为 Kubernetes 集群提供跨主机网络。 它的核心思想是为每个主机分配一个子网,并使用覆盖网络技术在不同主机上的容器之间传输数据包。

 

*   **工作原理**Flannel 在每个主机上运行一个名为 `flanneld` 的小代理,负责从预配置的地址空间中为每个主机分配一个子网租约。 `flanneld` 使用 Kubernetes API etcd 存储网络配置和分配的子网信息。 数据包通过多种后端机制进行转发,其中最常用的是 VXLAN (Virtual Extensible LAN) VXLAN 通过在现有 IP 网络上封装以太网帧来创建虚拟二层网络,实现了跨主机的容器通信。

*   **优势**

    *   **易于部署和配置**Flannel 配置简单,非常适合初学者和对网络功能要求不高的场景。

    *   **提供基本跨主机通信**Flannel 能够有效地解决跨主机容器通信问题,为每个 Pod 提供唯一的 IP 地址。

    *   ** Kubernetes 良好集成**Flannel 提供 CNI 插件,可以与 kubelet 顺利集成,自动配置 Pod 之间的网络。

 

*   **局限性**

    *   **缺乏高级网络策略**Flannel 主要关注提供基础的跨主机连接,不提供高级网络策略(如防火墙规则、流量整形等)功能。

    *   **性能开销**VXLAN 封装会带来一定的性能开销。

 

#### 2. Calico:高性能与网络策略

 

Calico 是一个功能强大的 CNI 插件,提供全面的网络、网络安全和可观测性解决方案,适用于任何 Kubernetes 发行版。 Calico 不仅提供跨主机容器网络,还专注于细粒度的网络策略执行。

 

*   **工作原理**Calico 可以使用多种网络模式,包括基于 BGP 的路由模式和 IP-in-IP 封装。 在 BGP 模式下,Calico 利用 Linux 内核的路由功能,通过 BGP 协议在节点之间直接路由容器流量,避免了封装带来的性能开销。 Calico 还支持 eBPF (extended Berkeley Packet Filter) 技术,用于实现低延迟、高性能的网络和安全策略。

*   **优势**

    *   **强大的网络策略**Calico 提供了 Kubernetes NetworkPolicies 的实现,允许用户定义细粒度的网络策略,控制 Pod 之间的通信以及 Pod 与外部实体之间的通信,从而增强集群的安全性。

    *   **高性能**Calico 可以利用 BGP 等路由协议实现高性能的网络连接,减少封装开销。

    *   **可扩展性**Calico 具有高度的可扩展性,能够在大规模 Kubernetes 集群中稳定运行。

    *   **可观测性**Calico 提供内置功能(如 Felix Typha),提供策略相关指标和流量指标,并可与 Prometheus Grafana 等工具集成进行监控和可观测性。

    *   **平台互操作性**Calico 支持广泛的平台,包括 KubernetesOpenShiftOpenStack 等。

 

*   **局限性**

    *   **复杂度相对较高**:相较于 FlannelCalico 的配置和管理可能更复杂,特别是对于 BGP 路由模式。

 

### 四、容器网络模型的演进对容器生态的影响

 

Docker CNM Kubernetes CNI 的演进,对整个容器生态产生了深远的影响:

 

*   **推动标准化**CNI 的出现推动了容器网络接口的标准化,使得不同容器运行时和网络解决方案之间能够更好地互操作。 这降低了容器网络开发的门槛,促进了创新。

*   **赋能 Kubernetes**CNI Kubernetes 网络的核心组件,为 Kubernetes 提供了灵活、可扩展的网络基础。 它使得 Kubernetes 能够支持各种复杂的网络场景,满足不同应用的需求。

*   **繁荣网络插件生态**CNI 的插件化架构催生了丰富的网络插件生态系统,除了 Flannel Calico,还有 Weave NetCiliumKube-router 等众多解决方案,它们提供了各种高级功能,如服务网格集成、多网络接口、SR-IOV 等。

*   **提升容器安全性**:网络策略的引入(如 Calico 提供的 NetworkPolicy)使得用户可以对容器间的流量进行精细控制,大大提升了容器集群的安全性。

*   **促进云原生发展**CNI 作为云原生计算基金会 (CNCF) 的倡议,是云原生生态系统的重要组成部分。 它为构建和管理云原生应用提供了强大的网络支持,加速了云原生技术的发展和普及。

 

### 总结

 

容器网络模型的演进是容器技术发展的重要缩影。从 Docker CNM 的初步探索,到 Kubernetes CNI 的标准化和开放生态,容器网络经历了从简单连接到复杂策略、从紧密耦合到解耦插件的转变。CNI 的成功,特别是 Calico Flannel 等优秀插件的广泛应用,为 Kubernetes 提供了强大而灵活的网络能力,极大地推动了容器生态的繁荣和云原生应用的落地。未来,随着 eBPF 等新技术的不断发展,容器网络将继续向着更高性能、更安全、更智能的方向演进,为构建下一代分布式应用提供更坚实的基础。

评论

此博客中的热门博文

gemini转发国内的部署教程

移动 IP 技术:如何在不同网络间无缝切换?

公共 Wi-Fi 安全吗?你需要知道的风险