# ckernel **Repository Path**: ye-zhu-can/ckernel ## Basic Information - **Project Name**: ckernel - **Description**: hust ckernel华为交付 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-06-18 - **Last Updated**: 2026-09-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ckernel 交付使用包 ## 文件结构 仓库根目录主要文件如下: ```text ./ README.md 本说明文档 OLK-6.6_VERSION.txt 开发机使用的 OLK-6.6 基线提交信息 OLK-6.6-to-current.patch 从 OLK-6.6 基线到当前 ckernel 功能的补丁 docs/CKERNEL_COMPONENT_DOMAINS.md 1个核心+4个能力域的设计与使用说明 docs/COMPONENT_VALIDATION.md 补丁、构建和结果验证记录 fetch_olk66_same_as_hpc05.sh 拉取相同 OLK-6.6 基线并应用补丁 deploy_ckernel_system.sh 部署脚本:编译/安装内核,安装 runck,配置 Docker runtime test_ckernel_smoke.sh 部署后基础健康检查 ckernel_acceptance_bench.sh 六类验收实验入口脚本 run_acceptance_smoke.sh 六类验收实验的最小 smoke 入口 runtime/runck/ runck 已编译的 ckernel runtime SHA256SUMS runck 校验信息 *.patch runck 相关源码补丁备份 configs/ k8s/* 可选的 Kubernetes 兼容配置,Docker 验收不使用 containerd/*.toml 可选的 containerd 配置参考 kernel/*.config 开发测试使用过的内核配置 system_micro/*.yaml 历史 Kubernetes Job 模板,仅作参考 npb3.4/*.yaml 历史 NPB Job 模板,仅作参考 alpine_cgroup_scale/* 弹性扩缩测试小程序与源码 root_profiles/* 开发测试机 profile 备份 ckernel_project/* ckernel 开关辅助脚本 tests/ build_images.sh 构建/拉取验收测试所需 Docker 镜像 fetch_offline_images.sh 从 GitHub LFS 镜像仓库下载离线镜像 load_offline_images.sh 加载离线镜像,默认只操作 Docker export_offline_images.sh 在联网机器导出离线镜像 report_results.py 生成 native 与 ckernel 的 TXT/CSV 对比表 bench/ 包内自带 benchmark 工作目录,测试默认使用这里 system_micro/ syscall 与 agent-workflow 测试 npb3.4/ NPB Dockerfile 和 Job 模板 npb-bench/ NPB runner real-apps-sysnoise/ realapp syscall-noise runner nginx-bench/ realapp same-workload runner will-it-scale/ 19项严格同口径runner与正式n=3结果 httpd-syscall/ 48实例HTTPD runner、诊断脚本与正式结果 alpine/ckernel_cgroup_scale_20260424/ 资源弹性扩缩 runner ``` 注意:该包提供 ckernel 内核补丁、runck runtime、部署脚本、配置模板、benchmark 源码和镜像制作脚本。验收测试默认使用包内 `tests/bench`,不依赖目标机已有 `/root/HiDenCon-Bench-huyanglin` 工作目录或预置镜像。 ## 新组件架构 本次新增隔离机制按“1个核心+4个能力域”整理:实例上下文、feature mask和原生回退构成Core;Security、VFS、Socket和Meta/Acct分别处理权限 状态、文件系统对象、网络对象以及元数据与热点计数。完整组件、边界条件和 OCI annotation见 `docs/CKERNEL_COMPONENT_DOMAINS.md`。 `ckernel_process_domain`未进入本次最终验收,内核和runck完整补丁均不包含 其实现或启用入口。历史结果环境中若出现`ckernel_process_domain=0`,仅表示 该功能在当时明确关闭。 ## 环境部署 目标机器建议满足: ```text 架构:aarch64 系统:openEuler;内核构建固定使用包内记录的 OLK-6.6 基线提交,不建议直接换用其他提交应用补丁 权限:root 容器运行时:Docker,必须注册 runc 和 runck runtime,并支持 OCI annotation Kubernetes:不需要;验收测试不依赖 kubelet、kubectl、kubeconfig、CNI 或 RuntimeClass 编译依赖:gcc, make, bc, bison, flex, elfutils-libelf-devel, openssl-devel, dwarves, rpm-build, dracut, grubby 镜像依赖:Docker,用于构建、加载和运行全部测试镜像 验收工具:python3、bc、curl、timeout、taskset、mountpoint、awk、sed ``` 部署前先获取仓库并进入仓库根目录: ```bash git clone ckernel-final-test cd ckernel-final-test ``` 建议先确认基础命令: ```bash test "$(id -u)" -eq 0 command -v git gcc make bc bison flex python3 sha256sum nproc grubby dracut docker ``` 内核部署脚本默认从 `https://gitee.com/openeuler/kernel.git` 拉取 OLK-6.6,并固定检出 `3832db9d09e243ef4a0ef969801c5ab689bdff64`。目标机不能访问 Gitee 时,需要准备包含该提交的内部 Git 镜像,并通过 `REPO_URL` 指定: ```bash REPO_URL=https:///openeuler/kernel.git \ JOBS=$(nproc) ./deploy_ckernel_system.sh --skip-runtime ``` 测试镜像由包内脚本自动构建/拉取。部署前建议确认 Docker 可用: ```bash command -v docker systemctl is-active docker ``` 当前交付包不会自动安装 Docker。若机器无法访问软件源,需要提前准备离线 Docker RPM;若机器无法访问外网镜像源,需要提前导入基础镜像,或修改 `tests/build_images.sh` 中的镜像源。 推荐按下面的顺序完成一次完整部署。第一步安装内核后会重启机器: ```bash JOBS=$(nproc) ./deploy_ckernel_system.sh --skip-runtime reboot ``` 重新登录并确认已进入 ckernel 内核后,再安装 runck、配置 Docker 并执行检查: ```bash cd ckernel-final-test ./deploy_ckernel_system.sh --skip-kernel ./test_ckernel_smoke.sh ./run_acceptance_smoke.sh ``` 部署脚本默认设置 `CONFIGURE_CKERNEL_MONITOR=1`:它会尝试挂载 `/sys/fs/resctrl`,安装 `/etc/modprobe.d/ckernel-monitor.conf`,并验证 `ckernel_monitor=1`。硬件不支持 resctrl/MPAM 时无需手工关闭 monitor,更新后的内核会自动保留调度压制并跳过硬件带宽隔离。仅在排障时可显式关闭这一步: ```bash CONFIGURE_CKERNEL_MONITOR=0 ./deploy_ckernel_system.sh --skip-kernel ``` ## 内核如何换 推荐使用包内部署脚本自动完成内核编译、安装和 grub 默认项切换: ```bash cd ckernel-final-test JOBS=$(nproc) ./deploy_ckernel_system.sh --skip-runtime reboot ``` 该脚本会执行以下动作: ```text 1. 调用 fetch_olk66_same_as_hpc05.sh 拉取与开发机一致的 OLK-6.6 基线源码 2. 应用 OLK-6.6-to-current.patch 3. 使用 configs/kernel/ckernel_test_running_config-6.6.0+.config 作为 .config 4. 按本次部署时间生成唯一 LOCALVERSION,例如 6.6.0-ckernel-r20260721193000 5. 将 BPF、FAT、VFAT 和 EFI 常用 NLS 支持固定为 built-in,然后执行 make olddefconfig 6. make -j$(nproc) 7. 在临时目录执行 modules_install、depmod,并验证 ckernel 模块和 modules.dep 8. 发布独立的 /lib/modules/$release,并生成、校验对应的 Image 和 initramfs 9. 全部产物验证成功后,使用 grubby 添加启动项并设置为默认内核 10. 写入必要启动参数;任一步骤失败时不会切换默认内核 ``` 部署脚本不会覆盖已经存在的内核 release。每次直接运行脚本会自动生成新的 `BUILD_ID`;如需自定义版本,可设置一个尚未安装的 `LOCALVERSION`: ```bash LOCALVERSION=-ckernel-release2 JOBS=$(nproc) \ ./deploy_ckernel_system.sh --skip-runtime ``` 脚本写入的关键启动参数包括: ```text modprobe.blacklist=odc_core,odc_base,odc_intf cgroup_ifs=0 kpti=off apparmor=1 security=apparmor arm64.mpam ``` 重启后检查是否已经进入 ckernel 内核: ```bash uname -r find /lib/modules/$(uname -r) -iname '*ckernel*.ko*' ``` 如果只想安装 runtime,不重新编译内核: ```bash ./deploy_ckernel_system.sh --skip-kernel ``` 如果要同时部署内核和 runtime: ```bash JOBS=$(nproc) ./deploy_ckernel_system.sh --reboot ``` ## runck 如何换 推荐使用部署脚本安装 runck,并更新 Docker runtime 配置: ```bash cd ckernel-final-test ./deploy_ckernel_system.sh --skip-kernel ``` 该步骤会: ```text 1. 将 runtime/runck/runck 安装到 /usr/bin/runck 2. 在 Docker daemon.json 中注册 runck 并重启 Docker 3. 默认不修改 containerd、kubelet,不读取 kubeconfig,也不创建 Kubernetes RuntimeClass ``` 如果需要额外配置 containerd,可以显式设置 `CONFIGURE_CONTAINERD=1`。如果以后确实需要兼容 Kubernetes,可设置 `CONFIGURE_KUBERNETES=1`,此模式也会配置 containerd;二者都不是 Docker 验收的前置条件: ```bash CONFIGURE_CONTAINERD=1 ./deploy_ckernel_system.sh --skip-kernel CONFIGURE_KUBERNETES=1 ./deploy_ckernel_system.sh --skip-kernel ``` 手工替换 runck 的最小流程如下: ```bash install -m 0755 runtime/runck/runck /usr/bin/runck /usr/bin/runck --version ``` 如果需要从源码重新构建 runck,基线固定为 upstream `opencontainers/runc` 提交 `ccaecfcbc907d70a7aa870a6650887b901b25b82`(v1.1.9): ```bash cd ckernel-final-test PKG_DIR=$(pwd) git clone https://github.com/opencontainers/runc.git cd runc git checkout ccaecfcbc907d70a7aa870a6650887b901b25b82 git apply "$PKG_DIR/runtime/runck/runc_ck.patch" make install -m 0755 runc /usr/bin/runck /usr/bin/runck --version ``` Docker 验收只要求 `/etc/docker/daemon.json` 注册 runck: ```json { "runtimes": { "runck": {"path": "/usr/bin/runck"} } } ``` 重启并验证 Docker: ```bash systemctl restart docker docker info --format '{{range $name, $_ := .Runtimes}}{{$name}} {{end}}' docker run --help | grep -- --annotation ``` ## 基础健康检查 部署后先跑基础检查: ```bash cd ckernel-final-test ./test_ckernel_smoke.sh ``` 该脚本会检查: ```text 1. 当前内核版本是否包含 ckernel 2. ckernel.ko 是否已安装并可 modprobe 3. /usr/bin/runck 是否存在且可执行 4. Docker daemon 是否注册 runck runtime,并支持 `--annotation` 5. 默认跳过 faascale cgroup v2 文件检查,兼容 cgroup v1;如需强制检查,设置 SMOKE_CHECK_FAASCALE=1 6. runck SHA256 是否匹配 ``` ## ckernel 开关说明 ckernel 功能通过 `modprobe ckernel ...` 的 module 参数组合启用。当前交付包的验收脚本默认只比较两组:`native` 原生基线和 `ckernel_all` v1-compatible 组合。为兼容 cgroup v1,默认测试暂时关闭 `faascale_memory` 和 `faascale_task_domain`,保留 monitor、AppArmor、acct 和 socket fast path。NPB 是例外:默认只比较 `native` 和 `ckernel_monitor`;被测主容器使用 online 标注,9 个干扰容器使用 offline 标注。单开关、三开关组合仍然保留在脚本里,需要拆分分析时可以通过环境变量手工指定。 单个开关含义如下: ```text ckernel_monitor: 启用 ckernel monitor 路径,对在线目标容器和干扰容器做调度/资源侧压制,目标是降低噪声 workload 对目标 workload 的调度干扰。 部署脚本默认尝试挂载 resctrl,并写入持久化 module 参数以启用 monitor。目标机没有可用的 resctrl/MPAM 能力时,monitor 仍保留调度压制,只跳过硬件带宽隔离子路径;ckernel_all 中的 AppArmor、acct 和 socket 等开关也继续生效。 ckernel_apparmor: 启用 ckernel 的 AppArmor/LSM 隔离路径。受保护路径仍执行完整检查;已接受的文件 fast path 延迟并省去逐文件共享 label 引用,避免多个容器在 open/close 时争用同一引用计数缓存线。每个 ckernel 实例使用唯一 cookie 约束 fast file,跨实例传递文件描述符时不会继承该旁路权限。 ckernel_acct: 启用 ckernel accounting 路径优化,用于降低容器资源统计、记账和相关内核 bookkeeping 对系统调用吞吐的影响。 faascale_memory: 启用 faascale memory,为 cgroup 维护独立内存区域和 buddy-style 管理,减少跨 cgroup 内存分配/释放干扰,并支撑快速内存回收。 faascale_task_domain: 启用 task domain,把同一 cgroup 内任务纳入 ckernel 的任务域管理,和 faascale_memory 配合减少跨容器共享状态带来的干扰。 ckernel_socket_fast: 启用 socket fast path,主要面向 socket/AF_UNIX/network 相关路径,降低 send/recv/bind 等网络类系统调用的干扰和开销。 ``` 验收测试中使用的配置名和开关组合如下: ```text native: 不加载 ckernel,使用普通 runc/runtime,作为系统原生基线。 ckernel 或 ckernel_no_switch: 使用 runck/ckernel 基础路径,但关闭所有优化开关: ckernel_monitor=0 ckernel_apparmor=0 ckernel_acct=0 faascale_memory=0 faascale_task_domain=0 ckernel_socket_fast=0 ckernel_monitor: 只打开 ckernel_monitor=1,其余优化开关关闭。 ckernel_apparmor: 只打开 ckernel_apparmor=1,其余优化开关关闭。 ckernel_acct: 只打开 ckernel_acct=1,其余优化开关关闭。 ckernel_3switch 或 ckernel_faascale_task_socket: v1-compatible 默认只保留 socket fast path;faascale/task_domain 暂时关闭: faascale_memory=0 faascale_task_domain=0 ckernel_socket_fast=1 ckernel_all: v1-compatible 默认打开 monitor/AppArmor/acct/socket,关闭 faascale/task_domain: ckernel_monitor=1 ckernel_apparmor=1 ckernel_acct=1 faascale_memory=0 faascale_task_domain=0 ckernel_socket_fast=1 ``` 注意:除 NPB 外,默认验收测试只运行 `native` 和 `ckernel_all`。这里的 `ckernel_all` 是当前 cgroup v1 兼容口径,不包含 faascale/task_domain。NPB 默认只开 `ckernel_monitor=1`,其余 ckernel 开关关闭;被测主容器传入 `ckernel.mode=1`,9 个干扰容器传入 `ckernel.mode=0`,避免主 NPB 被 offline CFS quota 主动限速。如果需要恢复单开关拆分,可以手工设置 `CONFIGS` 或 `REALAPP_SAME_CONFIGS_CK`。 ## 测试方法 六类验收测试统一入口: ```bash cd ckernel-final-test ./ckernel_acceptance_bench.sh syscall ./ckernel_acceptance_bench.sh realapp-noise ./ckernel_acceptance_bench.sh realapp-same ./ckernel_acceptance_bench.sh elastic ./ckernel_acceptance_bench.sh npb ./ckernel_acceptance_bench.sh agent-workflow ``` 最小 smoke 测试入口: ```bash ./run_acceptance_smoke.sh ``` ### will-it-scale 19项正式测试 首次运行需要拉取固定的上游提交并构建测试镜像。`fetch_upstream.sh` 同时生成runner需要挂载到容器中的主机侧benchmark二进制,不能只准备Docker 镜像: ```bash cd tests/bench/will-it-scale ./fetch_upstream.sh docker build -t ckernel-upstream/will-it-scale:75f66e4 . ``` 执行Native与完整CKernel组件的严格同口径`n=3`对比: ```bash STAMP="will19_customer_n3_$(date +%Y%m%d_%H%M%S)" ROOT="$PWD" WILL_ROOT="$PWD/upstream" \ ROUNDS=3 DURATION=10 NOISE_COUNT=9 TASKS=4 \ STAMP="$STAMP" ./run_will_19_components.py ``` 全部场景完成后,runner会在终端直接打印19项的Native/CKernel solo、 loaded、干扰率、干扰率下降、单容器变化和最大CV,并打印结果目录及 `raw.csv`、`summary.csv`、`report.md`路径。相同`STAMP`断点续跑时增加 `RESUME=1`,已完成场景不会重测。 ### HTTPD 48实例正式测试 先准备固定版本镜像,并确认版本: ```bash docker image inspect httpd:2.4.66 >/dev/null docker run --rm httpd:2.4.66 httpd -v ``` 执行`static-ka`和`metadata`的Native与当前完整CKernel组件`n=3`对比: ```bash cd ../httpd-syscall STAMP="httpd48_customer_n3_$(date +%Y%m%d_%H%M%S)" ROOT="$PWD" HTTPD_IMAGE=httpd:2.4.66 MODE=formal \ SERVER_COUNT=48 LOADED_ROUNDS=3 \ SCENARIOS=static-ka,metadata \ CONFIGS=native,ckernel \ STAMP="$STAMP" ./run_httpd_syscall48.py ``` 全部场景完成后,runner会在终端直接打印两组的solo/loaded吞吐、平均/P95/ 最差干扰率、干扰率下降、单容器变化、总吞吐变化和P99延迟,并打印结果 目录及`raw.csv`、`summary.csv`、`per_container.csv`、`report.md`路径。 `correctness`、`non_2xx`和ApacheBench `failed_requests`仍以原始CSV为准, 不得只依据汇总表判断正确性。 默认结果目录: ```text ./results ``` syscall 测试结束后,脚本会在本轮结果目录生成 native 与 ckernel 全开关的对比表。直接读取最新一轮: ```bash latest=$(ls -dt ./results/syscall_* | head -n 1) cat "$latest/native_vs_ckernel_all.txt" ``` 同一目录中的结果文件用途如下: ```text native_vs_ckernel_all.txt 人工阅读的逐 syscall 对比表 native_vs_ckernel_all.csv 可用 Excel 打开的逐 syscall 对比表 selected_avg.csv 每个配置所选三轮的平均结果 selected_rounds.csv 稳定性筛选后实际采用的三轮数据 all_attempts.csv 本轮产生的全部原始 attempt 数据 ``` 其余五类测试也会在具备完整对照数据时直接打印比较结果,并在对应结果目录生成: ```text native_vs_ckernel.txt 人工阅读的 native/ckernel 对比表 native_vs_ckernel.csv 可用 Excel 打开的同一份对比数据 ``` `syscall` 每完成一个 syscall、`realapp-noise` 和 `realapp-same` 每完成一轮、`agent-workflow` 每完成一个 workflow、`elastic` 每完成一个 controller/count、`npb` 每完成一个 benchmark 的两组数据后,都会刷新并打印当前对比表;整项测试结束时还会再次打印最终汇总。NPB 表中的 ckernel 列表示 `ckernel_monitor` 组,其中主容器 online、干扰容器 offline。 对比表中的 `solo` 是主容器单独运行时的平均吞吐量,`9-noise` 是九个干扰容器同时运行时主容器的平均吞吐量,`loss` 是干扰率 `(solo - 9-noise) / solo`。除 NPB 的 ckernel_monitor 组使用 offline noise 外,其他测试的干扰容器均为 online。吞吐量越高越好,干扰率越低越好;`noise gain` 表示 ckernel 全开关相对 native 的干扰场景吞吐提升,`loss reduced` 表示干扰率降低了多少个百分点。 默认 benchmark 工作目录: ```text ./tests/bench ``` 如果需要使用外部 benchmark 工作目录,可以设置: ```bash ROOT=/path/to/bench ./run_acceptance_smoke.sh ``` 测试前会自动调用镜像准备脚本: ```bash tests/build_images.sh ``` 六类测试现在全部使用 Docker,不读取 kubeconfig,也不要求 kubelet/apiserver 可用。运行前检查: ```bash docker info --format '{{range $name, $_ := .Runtimes}}{{$name}} {{end}}' docker run --help | grep -- --annotation ``` realapp 的 Web 阶段默认采用 20 秒固定测量窗口,避免低核数机器因固定完成 300 万请求而长时间无输出;native 与 ckernel 使用相同窗口。可显式调整: ```bash WEB_MEASURE_SEC=30 ./ckernel_acceptance_bench.sh realapp-noise WEB_MEASURE_SEC=30 ./ckernel_acceptance_bench.sh realapp-same ``` `realapp-noise` 会根据在线 CPU 和当前进程 affinity 自动调整 CPUSET。`realapp-same` 默认采用更高部署密度:自动选择一个至少包含 20 个完整 SMT2 物理核的 NUMA node,把主服务和 9 个同类噪声服务全部放在该 node;每个服务容器使用两个完整物理核的 4 个逻辑 CPU,10 组 CPU 及物理核均不重叠。Web 与 memcache 负载客户端也各使用 4 个逻辑 CPU,优先放到其他 NUMA node,并且不会占用服务端物理核。因此整机至少需要 40 个当前进程可用的完整 SMT2 物理核,其中一个 NUMA node 至少提供 20 个。目标机不满足该拓扑要求时测试会明确失败,不会静默退回跨 NUMA 布局。 低于 88 个可用 CPU 时仍会自动使用 compact memcache profile:每个 server 使用 1GB 数据和 1GB 内存,避免原参考配置的 `10×10GB` warmup 在小机器上长时间无输出。native 与 ckernel 使用完全相同的服务端、客户端 CPU 和内存 profile。可以指定 realapp-same 使用的 NUMA node,或者提供经过严格拓扑校验的 10 组服务 CPU: ```bash REALAPP_SAME_NUMA_NODE=2 ./ckernel_acceptance_bench.sh realapp-same REALAPP_SAME_SERVER_CPUSETS="128-129,160-161 130-131,162-163 ..." \ ./ckernel_acceptance_bench.sh realapp-same ``` 运行阶段会实时打印当前 app、配置和场景,完整日志仍保存在本轮结果目录。需要复现大机原参考规模,或显式强制 compact profile 时使用: ```bash REALAPP_PROFILE=reference ./ckernel_acceptance_bench.sh realapp-same REALAPP_PROFILE=compact ./ckernel_acceptance_bench.sh realapp-same ``` agent-workflow 默认直接使用包内的 aarch64 静态二进制,不要求目标机现场执行 `gcc -static`。如果修改了对应 C 源码并希望重编,可显式设置: ```bash REBUILD_AGENT_WORKFLOW=1 ./ckernel_acceptance_bench.sh agent-workflow ``` `syscall` 和 `agent-workflow` 使用 10 组互不重叠的 4 CPU cpuset,第一组给主容器,后九组给干扰容器。脚本会先检查开发机参考布局;如果目标机 CPU 编号、在线状态或进程 CPU affinity 不同,会自动从当前可用 CPU 中生成 10 组布局。也可以显式覆盖: ```bash DOCKER_CPUSETS="0-3 4-7 8-11 12-15 16-19 20-23 24-27 28-31 32-35 36-39" \ ./ckernel_acceptance_bench.sh syscall ``` 自动布局要求至少有 40 个在线且允许当前进程使用的 CPU。排查或验证自动布局时,可以强制重新生成: ```bash AUTO_DOCKER_CPUSETS=force ./ckernel_acceptance_bench.sh syscall ``` NPB 单独采用 packed-NUMA 布局:主容器和 9 个噪声容器位于同一个 NUMA node,每组使用两个完整 SMT sibling 物理核,共 4 个逻辑 CPU,容器之间不共享 CPU 或物理核。可以指定 node 或显式覆盖布局: ```bash NPB_NUMA_NODE=2 ./ckernel_acceptance_bench.sh npb NPB_DOCKER_CPUSETS="128-129,160-161 130-131,162-163 ..." \ ./ckernel_acceptance_bench.sh npb ``` syscall 测试对每个 syscall/config 只创建一组 10 个常驻 worker,由容器 init 进程派生三轮测量子进程,避免每个场景反复创建容器。默认每轮测量 3 秒、预热 1 秒、保留 3 轮;三轮干扰率跨度超过 3 个百分点或吞吐量变异系数超过 5% 时,最多补测到第 5 轮,再按离散度选择最稳定的 3 轮,不按干扰率高低挑选。`brk_alloc/brk_free` 是进程级地址空间操作,使用单线程和 1 秒测量;`munmap` 使用单线程但保留 3 秒测量。这样可避免同一进程的多个线程争用 `mmap_lock`,使结果只反映主容器与 9 个 all-online 噪声容器之间的干扰。每个 syscall 完成 native 与 ckernel_all 后立即在终端打印吞吐量、干扰率和干扰率降低百分点,同时持续更新结果目录中的对比 TXT/CSV。 参考 256 CPU 开发机上全套 18 项 syscall 约需 20–30 分钟;实际时间会随 CPU 数量、补测次数和机器负载变化。日志中的 `elapsed` 与 `eta` 会持续给出已用时间和剩余时间估计。 native 使用 Docker 当前配置的默认非 ckernel runtime(通常是 `runc`);ckernel 组使用 `runck --annotation ckernel.mode=1`;NPB monitor 组的主容器同样使用 `ckernel.mode=1`,仅 9 个干扰容器使用 `ckernel.mode=0`。需要调整 syscall 测量时间或最大轮数时使用: ```bash SYSCALL_DURATION=5 SYSCALL_MAX_ATTEMPTS=4 ./ckernel_acceptance_bench.sh syscall ``` 如果选择配置 containerd,或者 Docker 使用了非默认配置路径,可在部署时覆盖: ```bash CONFIGURE_CONTAINERD=1 \ CONTAINERD_CONFIG=/path/to/config.toml \ DOCKER_CONFIG=/path/to/daemon.json \ ./deploy_ckernel_system.sh --skip-kernel ``` `realapp-same` 默认使用离线 `httpd` 镜像内的 `/usr/local/apache2/bin/ab`,不要求宿主机安装 `ab`。每个 Web 客户端直接加入对应服务器容器的网络命名空间,绕开宿主机端口转发和防火墙差异;开始测量前还会等待服务器真正可访问。仅在排障时需要强制使用宿主机 `ab`,可设置 `AB_CLIENT_MODE=host`。 如果验证机不能访问 Docker Hub 或其他镜像站,但可以访问 GitHub,默认不需要单独准备镜像。`ckernel_acceptance_bench.sh` 会调用 `tests/build_images.sh`,后者在发现本地缺少测试镜像且 `offline-images/*.tar` 不存在时,会自动从公开 GitHub LFS 镜像仓库下载离线镜像包并加载: ```bash ./ckernel_acceptance_bench.sh syscall ``` 镜像仓库地址: ```text https://github.com/cangex/ckernel-bench-images ``` 下载完成后会得到: ```text offline-images/ckernel-bench-images-all.tar offline-images/ckernel-bench-images-all.images.txt offline-images/ckernel-bench-images-all.sha256 ``` 如果希望提前下载,或者自动下载失败后手工重试,也可以显式执行: ```bash ./tests/fetch_offline_images.sh ./tests/load_offline_images.sh ``` 如果验证机也不能访问 GitHub,则必须提前准备离线镜像。可以在一台可联网且已配置 Docker 的机器上进入交付包目录并自行导出: ```bash ./tests/export_offline_images.sh all ``` 生成的文件位于: ```text offline-images/ckernel-bench-images-all.tar offline-images/ckernel-bench-images-all.images.txt offline-images/ckernel-bench-images-all.sha256 ``` 把 `offline-images/` 目录拷贝到验证机交付包目录后,可以手工加载一次: ```bash ./tests/load_offline_images.sh ``` 该脚本会加载 Docker 镜像;即使目标机 Kubernetes 不可用,也不影响后续测试: ```bash ./ckernel_acceptance_bench.sh syscall ./run_acceptance_smoke.sh ``` `tests/load_offline_images.sh` 默认只执行 Docker 加载;仅在另有 containerd 兼容需求时,才显式设置 `IMPORT_TO_CONTAINERD=1`。 如果 `offline-images/*.tar` 已存在,`tests/build_images.sh` 会自动先加载离线镜像;镜像存在后不会再访问外网。需要禁用自动 GitHub 下载时,可设置: ```bash AUTO_FETCH_OFFLINE_IMAGES=0 ./ckernel_acceptance_bench.sh syscall ``` 各 suite 依赖如下: ```text syscall: 需要 ROOT/system_micro 需要 hidencon-system-micro:latest 基础镜像;脚本会构建 hidencon-system-micro:ckernel-stable 测试镜像 agent-workflow: 需要 ROOT/system_micro 需要 hidencon-system-micro:latest 基础镜像;脚本会构建 hidencon-system-micro:ckernel-stable 测试镜像 npb: 需要 ROOT/npb-bench 需要 ROOT/npb3.4 需要 npb:3.4 镜像 realapp-noise: 需要 ROOT/real-apps-sysnoise 需要 docker 命令和 nginx/httpd/memcache 相关镜像 realapp-same: 需要 ROOT/nginx-bench 需要 docker 命令和 nginx/httpd/memcache 相关镜像 elastic: 需要 ROOT/alpine/ckernel_cgroup_scale_20260424 需要 docker 命令和 alpine 镜像 ``` 各 suite 的默认开关覆盖如下: ```text syscall: 默认比较 native 与 ckernel_all: native, ckernel_all agent-workflow: 默认比较 native 与 ckernel_all: native, ckernel_all 覆盖 CMD/CI/PIPE/LG 四类 workflow。 realapp-noise: 默认比较 native 与 ckernel_all: native, ckernel_all 覆盖 nginx/httpd/memcache 在 syscall noise 干扰下的性能。 realapp-same: 默认比较 native 与 ckernel_all: native, ckernel_all elastic: 默认比较 native 与 ckernel_all: native, ckernel_all 该实验聚焦全开关场景下资源弹性扩缩收益,不用于单开关拆分。 每个 controller/count 的三轮测试采用 native -> ckernel、ckernel -> native、native -> ckernel 的 ABBA 配对顺序,ckernel 模块在整批实验开始前只加载一次;native 使用 runc 且不添加 ckernel annotation,结果取三轮中位数,避免模块装卸和测试先后顺序干扰对比。 CPU 从当前进程允许使用的在线 CPU 中动态分配。所有目标容器共享同一个 4-CPU 窗口,并在其中进行 2 CPU 与 4 CPU 切换;controller 进程固定到窗口外的独立 CPU,避免控制面与目标容器争抢。可用 `ELASTIC_CPU_POOL=0-47` 显式覆盖 CPU 池。 每个 controller/count 会先校准轮数,正式采样默认至少持续 5 秒(`ELASTIC_MIN_SAMPLE_SEC` 可覆盖),两种配置使用完全相同的轮数,以降低微秒级操作的短窗口波动。 结果日志会记录 Docker cgroup 版本;cgroup v1 的 cpuset 写入可能包含全局调度域重建成本,因此不要把 cgroup v1 与 cgroup v2 的绝对延迟直接比较。 npb: 默认比较 native 与 ckernel_monitor: native, ckernel_monitor ckernel_monitor 组只打开 ckernel_monitor=1,其余开关关闭。 ckernel_monitor 组的被测主容器默认使用 ckernel.mode=1,9 个干扰容器使用 ckernel.mode=0。 主容器完成后立即停止干扰容器,不等待受限的 offline 噪声负载自行跑完。 单容器默认超时为 3600 秒;可通过 `NPB_TIMEOUT=7200 ./ckernel_acceptance_bench.sh npb` 调整。 ``` 常用 smoke 参数示例: ```bash SYSCALL_TESTS=open SYSCALL_CONFIGS="native ckernel_all" ./run_acceptance_smoke.sh AGENT_TESTS="cmd ci pipe lg" RUN_CKERNEL_AGENT=1 ./run_acceptance_smoke.sh ``` 如果需要临时恢复单开关拆分,可以显式覆盖配置,例如: ```bash CONFIGS="native ckernel ckernel_monitor ckernel_apparmor ckernel_acct ckernel_3switch ckernel_all" ./ckernel_acceptance_bench.sh syscall REALAPP_SAME_CONFIGS_CK="ckernel_no_switch ckernel_monitor ckernel_apparmor ckernel_acct ckernel_faascale_task_socket ckernel_all" ./ckernel_acceptance_bench.sh realapp-same ``` ## 自定义负载测试 自定义 Docker 负载建议按两组测试:先跑 `native` 基线,再打开 ckernel 全开关并用 `runck` 运行同一个容器。 native 基线不加载 ckernel,使用 Docker 默认 runtime: ```bash rmmod ckernel 2>/dev/null || true docker run --rm ``` ckernel 全开关测试先加载模块: ```bash rmmod ckernel 2>/dev/null || true modprobe ckernel \ ckernel_monitor=1 \ ckernel_apparmor=1 \ ckernel_acct=1 \ faascale_memory=0 \ faascale_task_domain=0 \ ckernel_socket_fast=1 ``` 然后在 Docker 命令里指定 `runck` runtime: ```bash docker run --rm --runtime=runck --annotation ckernel.mode=1 ``` 如果 Docker 报 `unknown or invalid runtime name: runck`,说明 Docker daemon 还没有配置 `runck` runtime。先检查 `/etc/docker/daemon.json`,确保存在类似配置,并重启 Docker: ```json { "runtimes": { "runck": { "path": "/usr/bin/runck", "runtimeArgs": [] } } } ``` ```bash systemctl restart docker docker info --format '{{range $name, $_ := .Runtimes}}{{$name}} {{end}}' ``` 如果 `/etc/docker/daemon.json` 已包含 runck,但结构化查询仍没有输出 `runck`,说明当前 dockerd 很可能通过 `--config-file` 读取了其他配置。检查实际启动参数后,把 `DOCKER_CONFIG` 指向该文件重新部署: ```bash systemctl cat docker ps -ef | grep '[d]ockerd' DOCKER_CONFIG=/实际/daemon.json ./deploy_ckernel_system.sh --skip-kernel ``` 注意:只加载 `ckernel` 模块但仍用默认 `runc` 启动容器,不能完整覆盖 runck 负责传递的 ckernel 容器语义。做自定义负载对比时,ckernel 组应同时满足两个条件:`modprobe ckernel` 全开关已打开,容器启动命令使用 `--runtime=runck`。 如果目标机没有 Docker,`realapp-noise`、`realapp-same`、`elastic` 会失败并报告: ```text ERROR: missing command: docker docker: command not found ``` 这表示 Docker runtime 环境缺失,不代表 ckernel 内核或 runck 部署失败。 ## 故障排查 查看当前内核和模块: ```bash uname -r lsmod | grep ckernel || true modinfo ckernel ``` 查看 runck 和 Docker runtime: ```bash /usr/bin/runck --version docker info --format '{{range $name, $_ := .Runtimes}}{{$name}} {{end}}' docker run --help | grep -- --annotation ``` 如果测试后需要清理 ckernel 模块: ```bash rmmod ckernel 2>/dev/null || true ```