容器网络的 N 做完了:每个容器自己的协议栈实例,经点对点接口接入主机的数据面;按项目分 /24 的地址表;端口映射(运行中可改、有自己的应用 / 确认 / 定时回滚);一处端口登记,冲突双向拒绝;防火墙规则。之前确认的三件事也做了:内核评估里的两项少重启改动、TLS 共享模块、用户态进程的最低 CPU 份额。
| 步骤 | 内容 | 验收(net 测试) |
|---|---|---|
| N.1 | 协议栈按地址监听:同一端口可以在不同地址上各有服务;在所有地址上监听的服务占所有地址的这个端口 | 单元测试;交接后仍分得清 |
| N.2 | 网络域:每个容器一个协议栈实例,进程带着它的域(fork 继承),套接字在它的域里;替换协议栈时所有实例一起交接 | 域里看不到主机的监听、回环可用;替换协议栈时域里的连接不断(80 次往返全对) |
| N.3 | 容器接口:每个容器一条点对点链路接入主机数据面(ct<n>),它的流量走同一条包处理链(容器之间也经过主机) | 主机连到容器里的服务;容器连到另一个容器;整个 nettest 在容器里跑,1 MB 经路由器和 NAT 出去再回来 |
| N.4 | 地址表(ctnet 模块):私有地址段,按项目给 /24,容器地址记住;与主机接口、额外地址、路由、VLAN、L2TP 地址池、VPN 隧道网络双向检查 | 同项目同一个 /24;手动配置和容器网络重叠被拒绝;只收私有地址段;替换模块后分配不变 |
| N.5 | 端口映射(nat 模块里单独的一组):运行中改、自己的候选 / 应用 / 确认 / 定时回滚;端口登记(映射、端口转发、主机服务,冲突双向拒绝);按源前缀选出口地址或接口;容器接口自动做 NAT | 两个容器都监听 80,映射到两个主机地址的 80,同时可用;运行中把映射改到第三个地址:旧连接继续,新地址立即可用,旧地址不再映射;和端口转发、主机服务冲突的映射被拒绝;主机服务不能占已映射的端口;主机网络配置回滚后映射照常;映射的候选未确认时按时回滚 |
| N.6 | 防火墙模块:按接口(ct* 是所有容器)、网段、协议、端口允许 / 拒绝,默认允许;容器能访问主机所有地址和端口 | 默认能访问;拒绝规则只对容器生效、命中计数;删掉规则恢复 |
| 另外 | 容器里不能开原始套接字;容器只能用自己的地址发包(别的源地址的帧被丢弃) | 网络域测试里检查原始套接字被拒绝 |
| 测试中发现 | 阻塞的 TCP 发送和管道写入原来会只写一部分就返回(不检查返回值的程序会丢数据,测试里的回显服务器丢了 4.5 KB);现在和 Linux 一样写完为止(等待后从停下的地方接着写,被信号打断时返回已写的长度) | 整套测试 |
tls 模块;替换时先排空(新版本接新会话,旧版本留到它的会话都结束),下载进行中替换,下载完整。cpu share 可改);没有进程要跑时不花任何代价。测试机上一个死循环进程在 64 字节满载下得到约 15%(含测量之间的空闲)。ctnet 模块的保存和冲突检查的接线。地址分配、映射、防火墙这些策略都在模块里(ctnet、nat、firewall)。tls、ctnet 接口、Module::networks / ports、Admin::spawn 带网络域、Admin::proc_share / ct_ranges / ct_check。| 缺口 | 打算 |
|---|---|
| 容器运行时本身(隔离的根目录、PID 空间、资源限制)、compose | M7a、M7b(N 的网络接口给它们用) |
| 容器作为智能流控的主体(按容器限速、SYN 洪水打容器的测试) | S2,和 M7a 一起 |
| 管理界面里显示容器网段 | 现在在 info 的 ctnet 状态行里;网页上随 M7b 的界面一起 |
| 防火墙是无状态的;看到的是 NAT 之前的地址 | 按需加有状态规则 |
| 帧的接口号是 8 位:一台机器约 250 个接口(含容器) | 容器多了再扩 |
是否发布(2026.10.26.2)并更新两台机器:内核变了,按老流程上传内核、重装所有模块(新增 tls、ctnet、firewall,shell 等需要 tls)、重启一次。之后按顺序是 M5(终端)。