X86:kernel-4.18/4.19 + 20.03/22.03 系列

error:容器内无法创建线程
表现:curl 命令执行返回失败

参考上游patch:https://github.com/containerd/containerd/commit/55923daa9f56c8a890875f1e111201d918b382e2
patch中,如果clone3返回错误,不使用默认的EPERM错误码,而是改用unix.ENOSYS:
clone3 is explicitly requested to give ENOSYS instead of the default EPERM, when CAP_SYS_ADMIN is unset.
See moby/moby PR 42681 (thanks to berrange).

Without this commit, rawhide image does not work:

$ sudo ctr run --rm --net-host --seccomp registry.fedoraproject.org/fedora:rawhide foo /usr/bin/curl google.com

问题:
根据和华为同学的定位,认为openEuler的glibc会使用系统调用clone3,快手4.18.0内核没有clone3,导致curl执行失败。
由于问题只在快手部分主机上发生,所以基于华为的结论在快手环境继续排查,确定根因在containerd的安全模块seccomp与新版glibc兼容有问题:
容器内glibc创建线程的函数,会依次尝试调用系统的clone3/clone2/clone接口,如果目标接口不存在,系统会返回错误码38(Invalid system call number),glibc换下一个继续尝试。containerd的安全模块seccomp拦截了白名单外的系统调用,当在镜像内调用clone3,返回的错误码是1(Operation not permitted),glibc误认为环境权限不足,跳过尝试路径直接退出。这个问题影响所有使用glibc pthread的程序。
新版的containerd修复了clone3错误码的问题,但是快手有多个版本的containerd,在旧版的containerd环境使用接口会触发这个问题。
影响:
containerd 1.6.0以前的容器环境,使用pthread的程序无法在glibc 2.34+的OS镜像中运行,涉及容器镜像包括KwaiOS/openEuler 22.03+、Rockylinux9、Fedora39+、openSUSE Leap 15.6+、Ubuntu 22.04+、Debian12等比较新的操作系统。