Jenkins流水线使用Hadolint v2.8.0执行Dockerfile lint时出现OCI运行时错误,切换v1.18.0版本正常
看起来你遇到的问题是Hadolint镜像版本更新后基础镜像变更导致的——v2.x版本的hadolint/hadolint镜像改用了scratch基础镜像(完全最小化,没有任何shell环境),而v1.18.0这类旧版本是基于带shell的Linux发行版镜像构建的。
错误原因分析
你的流水线脚本里用了hadolint Dockerfile > hadolint-results.txt,这里的>重定向是shell的核心功能,但scratch镜像里没有bash/sh这类shell程序,也没有cat、echo这类基础系统命令(错误日志里提到的exec: "cat"找不到,其实是Jenkins在尝试启动容器时,默认依赖shell执行操作导致的失败)。
解决方案
这里有几个可行的解决办法,你可以根据需求选择:
方案一:使用带shell的Hadolint镜像变体
Hadolint官方提供了基于Debian的镜像变体(后缀为-debian),这个版本包含完整的shell环境,可以完美支持重定向这类shell操作。只需要修改你的流水线镜像配置即可:stage("Lint") { agent { docker { image "docker.io/hadolint/hadolint:v2.8.0-debian" reuseNode true } } steps { script { def result = sh label: "Lint Dockerfile", script: """\ hadolint Dockerfile > hadolint-results.txt """, returnStatus: true if (result > 0) { unstable(message: "Linting issues found") } } } }方案二:避免shell重定向,用Jenkins步骤处理输出
如果不想更换镜像,可以通过Jenkins的sh步骤捕获命令输出,再用writeFile写入文件,完全绕开shell的重定向依赖:stage("Lint") { agent { docker { image "docker.io/hadolint/hadolint:v2.8.0" reuseNode true } } steps { script { // 捕获lint输出并写入文件 def lintOutput = sh label: "Lint Dockerfile", script: "hadolint Dockerfile", returnStdout: true writeFile file: "hadolint-results.txt", text: lintOutput // 检查lint结果状态 def result = sh label: "Check lint status", script: "hadolint Dockerfile", returnStatus: true if (result > 0) { unstable(message: "Linting issues found") } } } }方案三:覆盖容器的Entrypoint
你可以在docker agent配置里直接覆盖镜像的entrypoint为hadolint,这样可以直接执行命令,但这种方式不支持复杂的shell操作,适合只需要执行lint命令、不需要保存输出的场景:stage("Lint") { agent { docker { image "docker.io/hadolint/hadolint:v2.8.0" reuseNode true entrypoint ["hadolint"] } } steps { script { def result = sh label: "Lint Dockerfile", script: "Dockerfile", returnStatus: true if (result > 0) { unstable(message: "Linting issues found") } } } }
推荐方案
个人最推荐方案一,因为它几乎不需要修改你的原有脚本逻辑,同时能完整使用新版本Hadolint的所有功能,还保留了shell环境带来的灵活性。
备注:内容来源于stack exchange,提问作者ahmed mohamed

