You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenShift集群中Tekton执行npm ci报EMFILE文件打开过多错误排查

EMFILE错误在Tekton buildah任务中,对比OpenShift Build Config的差异分析与解决方案

问题描述

我在OpenShift集群中使用Tekton流水线构建Angular应用,流水线包含两个ClusterTask:

  • git-clone:拉取源码
  • buildah:构建并推送镜像

在执行Dockerfile中的RUN npm ci步骤时,出现如下错误:

npm ERR! code EMFILE
npm ERR! syscall open
npm ERR! path /root/.npm/_cacache/index-v5/d8/c0/7503a3169361b6a2c8813bf0eddb92eed6417987f616accf18698f2b71f4
npm ERR! errno -24
npm ERR! EMFILE: too many open files, open '/root/.npm/_cacache/index-v5/d8/c0/7503a3169361b6a2c8813bf0eddb92eed6417987f616accf18698f2b71f4'

npm ERR! A complete log of this run can be found in: /root/.npm/_logs/2024-03-27T13_42_33_018Z-debug-0.log
subprocess exited with status 232
subprocess exited with status 232
Error: building at STEP "RUN npm ci": exit status 232

推测是npm打开文件数超出容器默认ulimit(1024),但相同操作的OpenShift Build Config可正常运行,怀疑差异在于Build Config使用特权上下文,想明确问题根源以及Tekton任务使用特权上下文的安全性。


问题根源

  1. Build Config与Tekton的权限差异
    OpenShift Build Config默认使用的构建容器(如Source-to-Image或Docker构建器)以特权模式运行,特权模式下容器会继承宿主机的文件描述符限制(通常为65535或更高),因此不会触发EMFILE错误。而Tekton的buildah ClusterTask默认以非特权模式运行,容器的默认nofile(最大打开文件数)ulimit为1024,npm ci安装Angular依赖时会同时打开大量缓存文件、依赖包文件,超出该限制就会报错。

  2. 特权上下文的安全风险
    给Tekton任务启用特权模式会授予容器几乎与宿主机等同的权限,包括访问宿主机设备、修改内核参数、挂载宿主机文件系统等。这意味着如果构建过程中引入恶意代码(如恶意依赖、被篡改的源码),攻击者可通过特权容器突破到宿主机,进而威胁整个集群的安全。除非有绝对必要,否则不建议使用特权模式。


非特权模式下的解决方案

1. 调整Tekton Task的ulimit限制

修改buildah ClusterTask的容器定义,添加securityContext配置提升nofile的软/硬限制:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: buildah # 或对应ClusterTask的名称
spec:
  steps:
    - name: build
      securityContext:
        ulimits:
          - name: nofile
            soft: 65535
            hard: 65535
      # 其他步骤配置...

该配置会将容器的最大打开文件数提升到65535,满足npm ci的文件操作需求。

2. 限制npm并发数

通过npm参数或配置文件减少并发操作,降低同时打开的文件数量:

  • 在Dockerfile中修改命令:
    RUN npm ci --maxsockets 10
    
  • 或在项目根目录添加.npmrc文件:
    maxsockets=10
    

3. 启用npm依赖缓存

使用Tekton Workspace缓存npm的node_modules和缓存目录,避免每次构建重复下载依赖,减少文件操作次数:
在PipelineRun中定义缓存Workspace,并在buildah Task中挂载:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName: angular-build-
spec:
  workspaces:
    - name: npm-cache
      persistentVolumeClaim:
        claimName: npm-cache-pvc
  pipelineSpec:
    workspaces:
      - name: npm-cache
    tasks:
      - name: git-clone
        taskRef:
          name: git-clone
        workspaces:
          - name: output
            workspace: source-code
      - name: buildah
        taskRef:
          name: buildah
        runAfter: [git-clone]
        workspaces:
          - name: source
            workspace: source-code
          - name: npm-cache
            workspace: npm-cache
        params:
          - name: BUILD_EXTRA_ARGS
            value: "--build-arg NPM_CONFIG_CACHE=/workspace/npm-cache"

同时在Dockerfile中指定缓存路径:

ARG NPM_CONFIG_CACHE=/root/.npm
RUN npm ci

内容的提问来源于stack exchange,提问作者Otrebor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:26:30