Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Jenkins docker build error

命令

docker build --no-cache --rm --tag spring-boot-initial:dev-3014127 .

错误信息

time="2026-01-04T16:15:35+08:00" level=error msg="Failed to set rlimits: setting new rlimits: operation not permitted"
time="2026-01-04T16:15:35+08:00" level=error msg="Failed to set rlimits: setting new rlimits: operation not permitted"
STEP 1/5: FROM custom/jdk:21.0.9-0
STEP 2/5: RUN mkdir -p /app
error running container: did not get container start message from parent: EOF
Error: building at STEP "RUN mkdir -p /app": setup network: pasta failed with exit code 1:
Failed to set current limit for open files: Operation not permitted

解决方法

这错误日志非常有价值,它进一步确认了问题的核心,并且指出了具体的“受害者”:Pasta

Error: ... setup network: pasta failed with exit code 1:
Failed to set current limit for open files: Operation not permitted

发生了什么?

  1. Pasta 是什么? Pasta 是新版 Podman(通常是 4.x+)默认使用的Rootless 网络后端(替代了旧的 slirp4netns)。
  2. 为什么报错? Pasta 为了性能和处理网络流量,在启动时会尝试申请大量的文件描述符(File Descriptors)。它试图调高 ulimit -n
  3. 为何失败? Jenkins 进程(由 Systemd 管理)被锁死在一个较低的“硬限制”(Hard Limit,通常是 4096 或 1024)里。Pasta 试图突破这个限制,内核直接拒绝,导致 Pasta 崩溃,进而导致 Podman 无法启动构建容器。

针对这个具体的 pasta 错误,有以下几种解决方案(按推荐程度排序):

方案一:彻底解决(修改 Systemd 配置)

这是最稳妥的方案。既然你已经看到了 Operation not permitted,说明 Systemd 确实限制了 Jenkins。

  1. 在运行该 Job 的节点上(如果是 Master 节点就在 Master 上,如果是 Agent 就在 Agent 机器上),运行:

    sudo systemctl edit jenkins
    

    (注意:如果你的 Jenkins Agent 是通过 SSH 启动的普通 Java 进程,你需要修改 sudo systemctl edit sshd 或者该 Agent 对应的服务文件)

  2. 粘贴以下内容

    [Service]
    # 设置为无限或一个极大值 (如 65536)
    LimitNOFILE=infinity
    
  3. 生效配置

    sudo systemctl daemon-reload
    sudo systemctl restart jenkins
    
  4. 重新运行 Jenkins Job,此时 Pasta 应该就能成功申请到资源了。


方案二:构建时绕过网络隔离(快速绕过)

如果你的构建过程(RUN 指令)不需要访问外网(或者你可以接受与宿主机共享网络),可以使用 --network host

这会告诉 Podman 不要启动 pasta 或网络命名空间,直接使用宿主机的网络堆栈。因为不启动 pasta,就不会触发这个 ulimit 报错。

修改你的构建命令:

# 增加了 --network host
podman build --network host --no-cache --rm --tag spring-boot-initial:dev-3014127 .
  • 优点:立即生效,不需要 root 权限修改系统配置。
  • 缺点:容器内的网络与宿主机不隔离(通常在 build 阶段这不是问题,甚至还能加速下载依赖)。

方案三:换回旧版网络后端(Slirp4netns)

如果方案二不行,且你无法修改 Systemd,可以尝试强制 Podman 使用旧版的 slirp4netns,它对 ulimit 的要求可能没有 pasta 那么激进(或者它失败时不会直接导致崩溃)。

方式 A:命令行参数(仅本次生效)

尝试在 build 命令中加入:

podman build --network-backend slirp4netns ...

(注意:并非所有版本的 Podman 都支持在 build 命令直接透传此参数,如果报错,请用方式 B)

方式 B:修改配置文件(推荐)

修改 Jenkins 用户的 ~/.config/containers/containers.conf

[network]
# 将默认网络后端从 pasta 改回 slirp4netns
default_rootless_network_cmd = "slirp4netns"

总结

  • 如果你有 sudo 权限:请使用 方案一(修改 Systemd LimitNOFILE),这是一劳永逸的办法。
  • 如果你没有 sudo 权限:请使用 方案二--network host),这是最快的解决办法。