Skip to content

Linux 安装

以下流程覆盖安装脚本、系统依赖、运行时动态库和 io_uring 安全策略。

支持的包管理器

install_linux.sh 使用 POSIX sh 语法,并识别以下包管理器:

  • apt-get
  • dnf
  • yum
  • zypper
  • pacman
  • apk

脚本会先检查系统包是否已经安装,只为缺失项尝试安装对应发行版候选包。主要依赖包括编译器、CMake、Ninja、Git、Autotools、pkg-config、libtirpc、libffi、UUID、BZip2、Zlib、CURL、Bison 和 Flex。

执行安装

sh
# 默认构建 Release
sh install/install_linux.sh

# 构建 Debug
sh install/install_linux.sh Debug

# 明确构建 Release
sh install/install_linux.sh Release

Linux 使用以下 CMake 配置:

text
Preset:       linux-ninja
Generator:    Ninja Multi-Config
Build dir:    kbe/src/out/build/linux-ninja
Runtime dir:  kbe/bin/server

如果机器已经由运维预装全部构建依赖,可以跳过系统包安装,但脚本仍会验证工具和 libtirpc

sh
KBE_SKIP_SYSTEM_DEPS=1 sh install/install_linux.sh Release

若不希望刷新软件包索引:

sh
KBE_SKIP_PACKAGE_UPDATE=1 sh install/install_linux.sh Release

自定义首次克隆的 vcpkg 仓库或 revision:

sh
KBE_VCPKG_REPOSITORY=https://github.com/microsoft/vcpkg.git \
KBE_VCPKG_REF=<revision> \
sh install/install_linux.sh Release

KBE_VCPKG_REF 只在 kbe/vcpkg 首次克隆时应用。安装脚本不会强制重置已经存在的 vcpkg 工作区,避免覆盖本地状态。

CMake 版本

主工程要求 CMake 3.25+。Linux 发行版自带 CMake 过旧时,脚本会尝试使用 vcpkg 管理的 CMake;如果网络环境无法获取该工具,应先手工安装满足版本要求的 CMake。

Linux 运行期要求

当前 Linux 网络后端使用 io_uring。完成编译并不代表目标宿主机一定允许创建 io_uring:部分加固系统、容器 seccomp 或 Kubernetes 安全策略会拒绝相关 syscall。

启动前可以检查:

sh
uname -r
sysctl kernel.io_uring_disabled 2>/dev/null || true

如果启动日志出现 io_uring setup failed: Operation not permitted,应由运维人员检查宿主机和容器安全策略,并只放行运行所需能力。不要把特权容器或关闭整个安全策略作为正式部署默认值。

关闭宿主机的 io_uring 禁用策略

先查看当前值:

sh
sysctl kernel.io_uring_disabled

kernel.io_uring_disabled 的含义如下:

含义
0所有进程可以正常创建 io_uring;关闭禁用策略
1普通进程禁止创建,只有具备 CAP_SYS_ADMIN 或属于 io_uring_group 的进程可以创建
2所有进程都禁止创建,io_uring_setup() 返回 EPERM

临时关闭禁用策略,立即允许 io_uring:

sh
sudo sysctl -w kernel.io_uring_disabled=0
sysctl kernel.io_uring_disabled

该设置在重启后可能恢复。验证引擎可以正常启动后,再创建持久化配置:

sh
printf '%s\n' 'kernel.io_uring_disabled = 0' | \
  sudo tee /etc/sysctl.d/90-kbengine-io-uring.conf

sudo sysctl --system
sysctl kernel.io_uring_disabled

如果发行版的其他 /etc/sysctl.d/*.conf 文件在后面重新写入该值,应删除冲突配置或调整文件加载顺序,保证最终结果为 0。修改后需要重新启动失败的 KBEngine 组件;已经初始化失败的进程不会自动重新创建网络 Poller。

内核参数的完整语义见 Linux Kernel io_uring_disabled 文档

更严格:只允许 KBEngine 服务账号

若内核同时提供 kernel.io_uring_group,可以保持 io_uring_disabled=1,仅允许指定 Unix 组和具备管理能力的进程创建 io_uring:

sh
# 检查当前内核是否支持 io_uring_group
sysctl kernel.io_uring_group

# 创建专用组,并把运行 KBEngine 的账号加入该组
sudo groupadd --system kbe-io-uring
sudo usermod -aG kbe-io-uring kbe

# 读取该组的数字 GID
KBE_IO_URING_GID="$(getent group kbe-io-uring | cut -d: -f3)"

sudo sysctl -w kernel.io_uring_group="$KBE_IO_URING_GID"
sudo sysctl -w kernel.io_uring_disabled=1

持久化配置:

sh
KBE_IO_URING_GID="$(getent group kbe-io-uring | cut -d: -f3)"

printf 'kernel.io_uring_group = %s\nkernel.io_uring_disabled = 1\n' \
  "$KBE_IO_URING_GID" | \
  sudo tee /etc/sysctl.d/90-kbengine-io-uring.conf

sudo sysctl --system

用户组变化需要重新登录服务账号,或重新创建 systemd/容器进程后才会进入新的附加组。使用以下命令确认:

sh
id kbe
sudo -u kbe id

如果系统没有 kernel.io_uring_group,只能使用值 0,或由运维系统为进程提供经过评估的能力和隔离策略。

Docker 容器

宿主机允许 io_uring 后,Docker seccomp 仍可能单独拦截以下系统调用:

text
io_uring_setup
io_uring_enter
io_uring_register

Docker 官方默认 seccomp profile 当前会阻止这三个调用。可以先在隔离测试环境中临时关闭 seccomp,确认错误确实来自该层:

sh
docker run --rm \
  --security-opt seccomp=unconfined \
  your-kbengine-image:tag

seccomp=unconfined 会取消容器的整套 syscall 过滤,只能用于原因验证。正式环境应复制与当前 Docker Engine 版本匹配的默认 seccomp profile,在其 syscalls 数组中增加以下允许规则:

json
{
  "names": [
    "io_uring_setup",
    "io_uring_enter",
    "io_uring_register"
  ],
  "action": "SCMP_ACT_ALLOW"
}

然后只为 KBEngine 容器应用该 profile:

sh
docker run --rm \
  --security-opt seccomp=/etc/docker/seccomp/kbengine-io-uring.json \
  your-kbengine-image:tag

Docker Compose 示例:

yaml
services:
  kbengine:
    image: your-kbengine-image:tag
    security_opt:
      - seccomp=./kbengine-io-uring.json

不要创建一个只允许上述三个 syscall 的空白 profile;应基于当前容器运行时的完整默认 profile 增加规则,否则容器启动和标准库运行所需的其他 syscall 会被拒绝。参见 Docker seccomp 文档

Kubernetes

Kubernetes 中推荐使用 Localhost seccomp profile,而不是把 Pod 设置为 privileged。流程如下:

  1. 基于节点容器运行时的默认 seccomp profile,增加 io_uring_setupio_uring_enterio_uring_register 允许规则;
  2. 将完整 profile 放到所有候选节点的 kubelet seccomp 根目录,默认通常为 /var/lib/kubelet/seccomp/
  3. 在 Pod 或 Container 的 securityContext 中引用它。
yaml
apiVersion: v1
kind: Pod
metadata:
  name: kbengine
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: kbengine-io-uring.json
  containers:
    - name: kbengine
      image: your-kbengine-image:tag
      securityContext:
        allowPrivilegeEscalation: false

如果 profile 没有部署到实际调度节点,Pod 会以 CreateContainerError 启动失败。不同 containerd、CRI-O 和 Kubernetes 版本的默认 profile 可能不同,因此自定义 profile 必须跟随节点运行时版本进行测试和维护。参见 Kubernetes Seccomp 文档

完成宿主机 sysctl 与容器 seccomp 调整后,重新创建容器或 Pod,再检查 KBEngine 启动日志。只修改容器 profile 不能覆盖宿主机的 kernel.io_uring_disabled=2;两层限制必须同时允许。