4. 资源模型概述:定义 eBPF 租户隔离中的核心资源模型
在 eBPF 租户隔离架构中,资源模型是控制平面与数据平面交互的语义基础。每个租户的隔离边界由一组可量化的资源配额构成,控制平面通过统一的资源描述符向 eBPF 程序下发策略。本章定义 CPU、内存、网络、文件系统四大核心资源的抽象模型,并给出对应的 eBPF 数据结构映射。
4.1 资源模型设计原则
资源模型遵循三条核心原则:
- 统一描述:所有资源使用相同的元数据结构(类型、ID、配额、统计),便于控制平面统一编排。
- 可观测性:每个资源实例附带计数器与时间戳,支持实时监控与审计。
- 可执行性:资源模型直接映射为 eBPF map 中的键值对,数据平面无需额外解析。
| 原则 | 说明 | eBPF 实现载体 |
|---|---|---|
| 统一描述 | 资源类型枚举 + 租户 ID + 配额上限 | struct resource_quota |
| 可观测性 | 当前用量、峰值、最后更新时间 | struct resource_stats |
| 可执行性 | 键值对直接用于 eBPF map 查找与更新 | BPF_MAP_TYPE_HASH |
设计提示:资源模型应保持扁平化,避免嵌套结构。eBPF 验证器对栈深度和循环次数有限制,扁平键值对能显著降低验证失败风险。
4.2 CPU 资源模型
CPU 资源模型以 时间片配额 和 并发执行上限 两个维度定义租户的 CPU 使用边界。控制平面将配额写入 eBPF map,eBPF 程序在调度点(如 sched/sched_switch)执行检查。
- 时间片配额:每毫秒可使用的 CPU 微秒数(μs/ms),例如 500 μs/ms 表示占用 50% 单核。
- 并发上限:同一时刻允许运行的任务数,防止租户通过多线程抢占。
- 统计字段:累计使用时间、被节流次数、最后调度时间戳。
// CPU 资源配额结构
struct cpu_quota {
__u32 tenant_id; // 租户标识
__u64 quota_us_per_ms; // 每毫秒配额(微秒)
__u32 max_concurrency; // 最大并发任务数
};
// CPU 运行时统计
struct cpu_stats {
__u64 used_us; // 累计使用微秒
__u64 throttled_count; // 被节流次数
__u64 last_update_ns; // 最后更新时间(纳秒)
};
关键约束:CPU 配额检查必须在
sched/sched_switch 或 sched/sched_process_exec 等低开销挂载点执行,避免在热路径中引入高延迟。
4.3 内存资源模型
内存资源模型覆盖 物理内存上限 和 内存分配速率 两个维度。eBPF 程序通过跟踪 kmem_cache_alloc、mmap 等内核函数实现配额控制。
| 维度 | 描述 | eBPF 挂载点 |
|---|---|---|
| 物理内存上限 | 租户可使用的最大 RSS(常驻内存)字节数 | kmem_cache_alloc、mmap |
| 分配速率 | 每秒允许分配的内存页数,防止内存暴涨 | page_fault_user、page_fault_kernel |
// 内存资源配额结构
struct mem_quota {
__u32 tenant_id;
__u64 rss_limit_bytes; // RSS 上限(字节)
__u32 page_rate_limit; // 每秒允许分配的页数
};
// 内存运行时统计
struct mem_stats {
__u64 current_rss_bytes; // 当前 RSS
__u32 page_alloc_count; // 当前秒已分配页数
__u64 last_reset_ns; // 速率计数器重置时间
};
注意事项:内存统计需要处理
cgroup 事件与 eBPF 程序的同步问题。建议使用 BPF_MAP_TYPE_PERCPU_HASH 减少锁竞争,并在用户态定期聚合。
4.4 网络资源模型
网络资源模型以 带宽、连接数、包速率 三个指标定义租户的网络边界。eBPF 程序在 tc 入口/出口或 XDP 点执行流量整形与限速。
- 带宽:每秒允许通过的字节数(bps),支持入站与出站独立配置。
- 连接数:租户可同时建立的 TCP/UDP 连接数上限。
- 包速率:每秒允许处理的数据包数量(pps),防止小包攻击。
// 网络资源配额结构
struct net_quota {
__u32 tenant_id;
__u64 ingress_bps; // 入站带宽(字节/秒)
__u64 egress_bps; // 出站带宽(字节/秒)
__u32 max_connections; // 最大连接数
__u32 max_pps; // 最大包速率
};
// 网络运行时统计
struct net_stats {
__u64 ingress_bytes; // 累计入站字节
__u64 egress_bytes; // 累计出站字节
__u32 active_connections;// 当前活跃连接数
__u32 pps_count; // 当前秒包数
};
性能建议:网络资源检查应优先在
XDP 层完成,避免数据包进入协议栈后再丢弃。XDP 的包丢弃延迟比 tc 低 2-3 个数量级。
4.5 文件系统资源模型
文件系统资源模型管理 磁盘空间、inode 数量 和 IOPS。eBPF 程序通过跟踪 vfs_write、vfs_read、ext4_* 等文件系统操作实现配额控制。
| 维度 | 描述 | eBPF 挂载点 |
|---|---|---|
| 磁盘空间 | 租户可使用的磁盘字节数上限 | vfs_write、ext4_write_begin |
| inode 数量 | 租户可创建的文件/目录数量上限 | vfs_create、vfs_mkdir |
| IOPS | 每秒允许的读写操作次数 | block_rq_issue、block_rq_complete |
// 文件系统资源配额结构
struct fs_quota {
__u32 tenant_id;
__u64 disk_limit_bytes; // 磁盘空间上限
__u32 inode_limit; // inode 上限
__u32 iops_limit; // IOPS 上限
};
// 文件系统运行时统计
struct fs_stats {
__u64 used_bytes; // 已用磁盘空间
__u32 used_inodes; // 已用 inode 数
__u32 iops_count; // 当前秒 IOPS
__u64 last_reset_ns; // IOPS 计数器重置时间
};
实现要点:文件系统配额需要与内核的
dquot(磁盘配额)机制协同。eBPF 程序负责实时拦截与计数,而 dquot 负责持久化配额状态。两者通过共享 eBPF map 交换数据。
4.6 资源模型统一视图
下图展示四大资源模型在 eBPF 租户隔离架构中的统一视图。控制平面通过统一的资源描述符下发配额,eBPF 数据平面在各自挂载点执行检查与统计。
4.7 资源模型与控制平面的接口映射
控制平面通过统一的 资源描述符 与 eBPF 数据平面交互。描述符包含资源类型、租户 ID、操作类型(查询/更新/删除)和配额数据。eBPF 程序通过 bpf_map_lookup_elem 和 bpf_map_update_elem 操作对应的资源 map。
// 统一资源描述符
struct resource_descriptor {
__u32 tenant_id;
enum resource_type type; // CPU, MEM, NET, FS
enum op_type op; // QUERY, UPDATE, DELETE
union {
struct cpu_quota cpu;
struct mem_quota mem;
struct net_quota net;
struct fs_quota fs;
} quota;
};
// eBPF map 定义
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, __u32); // tenant_id
__type(value, struct resource_descriptor);
} resource_map SEC(".maps");
接口设计要点:控制平面与 eBPF 数据平面之间使用共享 map 通信,避免系统调用开销。控制平面通过
bpf() 系统调用更新 map,eBPF 程序在挂载点读取 map 执行策略。建议为每个资源类型创建独立的 map,减少锁竞争。