Skip to content

第一百二十三章:隔离之海

问道期

涉及内核源码:

林小源在网络之海的边缘看到了一幕奇景——同一片海域被分割成了无数个独立的小海,每个小海都有自己的港口、自己的航线、自己的灯塔。

"这是什么?"

"网络命名空间。"一个低沉的声音从身后传来。

林小源转身,看到一个穿着灰色斗篷的老人。斗篷上绣着无数层叠的网状图案,每一层都是一个独立的网络世界。老人的面容模糊,仿佛同时存在于多个空间。

"我是 net_namespace。"老人说,"网络隔离的守护者。你看到的每个小海——都是一个独立的网络命名空间。每个命名空间有自己的网络设备、IP 地址、路由表、iptables 规则、端口空间。"

"完全独立?"

"完全独立。"老人说,"命名空间 A 里的 eth0 和命名空间 B 里的 eth0 是不同的设备——可以有不同的 IP 地址,不同的 MTU,甚至不同的驱动。它们互不可见,互不干扰。"

林小源看着那些独立的小海:"这有什么用?"

"容器。"老人说,"Docker、Kubernetes、LXC——它们都用网络命名空间。每个容器有自己的网络栈,就像一台独立的机器。容器 A 监听端口 80,容器 B 也可以监听端口 80——因为它们在不同的命名空间里。"

"但这些小海之间怎么通信?"林小源问。

老人从斗篷下抽出一根细细的线——一端连着一个小海,另一端连着另一个小海。

"veth pair。"老人说,"虚拟以太网对。一端在命名空间 A,另一端在命名空间 B。数据从一端进入,从另一端出来——就像一根虚拟的网线。"

林小源接过那根线,感到里面有数据在流动:"那多个命名空间呢?"

"用 bridge。"老人指向那些小海的交汇处——那里有一个巨大的平台,所有 veth pair 的另一端都连接在上面。"bridge 是虚拟交换机——它连接多个网络设备,根据 MAC 地址转发数据包。"

"就像一个中心交换机。"

"对。"老人说,"容器的 veth 一端在容器里,另一端在 bridge 上。容器发的数据包通过 veth 到达 bridge,bridge 再转发到目标容器的 veth。"

林小源看着那个平台上的数据流——无数光点在 veth pair 之间穿梭,bridge 根据 MAC 地址表把它们送到正确的目的地。

"网络命名空间是谁创建的?"林小源问。

"通常是容器运行时。"老人说,"但你也可以手动创建——ip netns add ns1。然后在命名空间里执行命令:ip netns exec ns1 ip addr。"

"那容器的网络是怎么配置的?"

老人走到一块石板前,上面刻着容器网络的拓扑图:

"容器启动时,运行时创建网络命名空间,创建 veth pair,一端放入容器,另一端连接到 bridge。然后配置 IP 地址、路由、iptables 规则。容器里的进程看到的是一块网卡————但实际上是 veth 的一端。"

"那跨主机的容器通信呢?"

"那是更复杂的问题。"老人说,"overlay network、VXLAN、BGP——都是解决方案。但基础是一样的:网络命名空间提供隔离,veth pair 提供连接,bridge 提供交换。"

林小源看着那些独立的小海,忽然明白了——容器的"独立网络"不是魔法,而是网络命名空间的隔离能力。每个容器以为自己有一块独立的网卡,实际上是 veth pair 的一端。

c
/*
 * 网络命名空间:
 *
 *   命名空间 A              命名空间 B
 *   ┌──────────┐           ┌──────────┐
 *   │ eth0     │           │ eth0     │
 *   │ 10.0.1.2 │           │ 10.0.2.2 │
 *   │          │           │          │
 *   │ 路由表   │           │ 路由表   │
 *   │ iptables │           │ iptables │
 *   └──────────┘           └──────────┘
 *        ↑                       ↑
 *        └─────────┬─────────────┘
 *              veth pair
 *
 * 网络命名空间的隔离:
 *   - 独立的网络设备
 *   - 独立的 IP 地址
 *   - 独立的路由表
 *   - 独立的 iptables 规则
 *   - 独立的端口空间
 *
 * 创建网络命名空间:
 *   ip netns add ns1
 *   ip netns exec ns1 ip addr
 */

printf("=== 网络命名空间 — 隔离的网络 ===\n\n");

printf("网络命名空间:\n\n");
printf("  命名空间 A              命名空间 B\n");
printf("  ┌──────────┐           ┌──────────┐\n");
printf("  │ eth0     │           │ eth0     │\n");
printf("  │ 10.0.1.2 │           │ 10.0.2.2 │\n");
printf("  │          │           │          │\n");
printf("  │ 路由表   │           │ 路由表   │\n");
printf("  │ iptables │           │ iptables │\n");
printf("  └──────────┘           └──────────┘\n\n");

printf("--- 隔离的内容 ---\n");
printf("独立的网络设备\n");
printf("独立的 IP 地址\n");
printf("独立的路由表\n");
printf("独立的 iptables 规则\n");
printf("独立的端口空间\n\n");

printf("--- 创建和使用 ---\n");
printf("创建:\n");
printf("  ip netns add ns1\n\n");
printf("查看:\n");
printf("  ip netns list\n\n");
printf("在命名空间中执行:\n");
printf("  ip netns exec ns1 ip addr\n\n");

printf("--- 连接命名空间 ---\n");
printf("veth pair:\n");
printf("  虚拟以太网对\n");
printf("  一端在命名空间 A\n");
printf("  另一端在命名空间 B\n\n");
printf("创建 veth:\n");
printf("  ip link add veth0 type veth peer name veth1\n");
printf("  ip link set veth1 netns ns1\n\n");

printf("--- 容器网络 ---\n");
printf("每个容器有自己的网络命名空间:\n");
printf("  容器 1: 10.0.1.2\n");
printf("  容器 2: 10.0.2.2\n");
printf("  互相隔离\n");

道藏笔记

内核启示

网络命名空间隔离网络资源。

网络命名空间的隔离:

  • 独立的网络设备
  • 独立的 IP 地址
  • 独立的路由表
  • 独立的 iptables 规则

连接命名空间:

  • veth pair — 虚拟以太网对
  • 网桥 — 连接多个命名空间

容器网络:

  • 每个容器有自己的命名空间
  • 通过 veth pair 和网桥通信

网络命名空间是"隔离之海"——让容器拥有独立的网络世界。


破关试炼

网络命名空间之试

容器能拥有独立 IP、路由表、防火墙和端口空间,本章依靠的隔离机制是什么?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道