开放问答
K8s 默认 seccomp 把 io_uring 拦了,想最小放行而不放开 Unconfined,具体该加哪几个 syscall
该问题的正文、回答与评论。
提问者 苏知远-113 · 状态 open
Kubernetesio_uringseccomp容器安全性能
背景
我在给一套工业数据网关做容器化。网关里有个高吞吐转发进程(C++,自研 epoll 内核),我们想升级到 io_uring 走异步 IO,目标是单核从 ~24k QPS 提到 60k+。同一个二进制在裸机(节点内核 5.15.0-91)上 io_uring_setup 直接就能跑,但一塞进 K8s(1.28.9,containerd 1.7.13,cgroup v2)就出问题。
现象
容器内 io_uring_setup 直接返回 EPERM (Operation not permitted),strace 抓到的就是这一行,进程回退到 epoll 路径后 QPS 打不上去。我基本判断是 seccomp 拦的——同一台机器裸机能跑、容器不能,差异点只在 seccomp profile。安全团队的立场很明确:不接受 seccomp: Unconfined,要求最小放行。
已尝试
- 把 Pod 的
securityContext.seccompProfile从RuntimeDefault临时改成Unconfined——能跑了,QPS 到 58k,验证了瓶颈确实是 syscall 被拦,但安全评审直接打回; - 翻了 RuntimeDefault 的 syscall 白名单,确认
io_uring_setup/io_uring_enter/io_uring_register三个都不在里面; - 想自己写一个 seccomp profile 只放行这几个,但 K8s 1.28 自定义 profile 走
Localhost类型,要落文件到节点(如/var/lib/kubelet/seccomp/),我还没想清楚在"不 root 进每个 worker 节点"的前提下怎么把 profile 文件分发到全集群; - 也评估过干脆回退 epoll 不用 io_uring,但代码已经写了一半,想先把可行性问清楚。
期望得到的答案形态
- 精确到 syscall:io_uring 在 5.15 内核上到底要放行哪几个(只有 setup/enter 两个,还是 register 也必须放行?
io_uring_register里的 IORING_REGISTER_BUFFERS 是不是必须?),有没有人踩过"放行了 setup 但漏了 register,buffer 注册失败"的坑; - 最小放行怎么落地:K8s 1.28 用
Localhost自定义 seccomp profile,profile JSON 大概长什么样(只列这几个 syscall 的 allow 规则 + 其余 defaultAction=SCMP_ACT_ERRNO),以及 profile 文件如何在"不 root 进节点"的前提下分发(initContainer 写文件 / DaemonSet / 其他方式),最好有现成 YAML; - 成本收益判断:以"单核 24k→60k QPS"这个量级,io_uring 的收益值不值得引入「seccomp 自定义 + profile 分发 + 安全评审」这套长期维护成本?多大规模的吞吐才值得上 io_uring,什么场景 epoll 就够。
不想要"理论上可以",想要具体 JSON 片段 / YAML / 命令,外加一个明确的成本收益结论。
评论
暂无评论。