Linux I/O 栈 — 一次 write() 和一次 send() 穿越的 6 层

模块 1 — Linux 基础与容器技术入门  |  PPT 第 3-8 页  |  静态示意图

存储栈 — 一次 write() 调用 应用程序 Python: f.write(buf) write(fd, buf, len) glibc (libc.so) syscall(SYS_write, ...) syscall 陷入内核 VFS (虚拟文件系统) vfs_write() → 统一接口 file→f_op→write() 文件系统 (ext4/xfs) 分配 inode + 数据块 submit_bio() Block Layer IO 调度 / 合并 / 重排 blk_mq_submit_bio() NVMe 驱动 Doorbell → 硬件队列 NVMe SSD 硬件 容器 Namespace 与 Cgroup 如何隔离/限制这两条 I/O 路径? mount namespace → 隔离 VFS 层 每个容器有独立的文件系统树。Docker 通过 OverlayFS 将多个只读 镜像层 (lower) 与一个可写层 (upper) 合并为容器的根文件系统。 net namespace → 隔离网络栈 每个容器有独立的网卡 (veth pair)、IP 地址、路由表、iptables 规则。容器间通信通过虚拟网桥 (docker0) 转发。 cgroup blkio → 限制 Block Layer 控制每个容器的块设备 I/O:读写 IOPS 上限、吞吐量 (BPS) 上限。 防止一个容器占满磁盘带宽影响其他容器。 pid namespace → 隔离进程视图 容器内 PID 1 = init 进程。Host 上可以看到容器的真实 PID,容器内看不到 Host 进程。 cgroup memory / cpu → 资源限制 内存上限 + OOM Killer、CPU shares 权重、cpuset 绑核。与 I/O 路径协同发挥作用。 总结 • 存储 I/O 路径:mount ns (VFS 隔离) + cgroup blkio (Block Layer 限速) • 网络 I/O 路径:net ns (协议栈隔离) + cgroup net_prio (流量优先级) • 容器 = Namespace (隔离可见性) + Cgroup (限制资源量) + OverlayFS (分层镜像) 网络栈 — 一次 send() 调用 应用程序 Python: sock.send(data) send(fd, buf, len, 0) glibc (libc.so) syscall(SYS_sendto, ...) syscall 陷入内核 Socket Layer sock_sendmsg() → BSD API tcp_sendmsg() TCP/IP 协议栈 分段 · 封装 · 拥塞控制 ip_queue_xmit() Netfilter / TC iptables 规则 · 流量整形 ndo_start_xmit() NIC 驱动 DMA 映射 → 发送队列 网卡 (NIC) 硬件