在我们的整个组织中,我们在本地运行 Jenkins 2.303.1。我们每天运行数千个构建。我从事的项目使用一个 Jenkins master 和一组大约十个构建节点。我们构建了数百个具有类似架构的 Maven/Java/Spring 应用程序。
在构建过程中,我们有一个“工具映像”,其中包含java和mvn以及其他一些工具。
昨天,我们更新了构建过程以引用更新版本的工具映像,其中包含我们需要使用的一些其他工具。在我们进行更新后不久,我们注意到现在有四个构建节点,其中构建都以相同的方式失败,大致的命令行和输出如下:
+ bash -o pipefail -c mvn -U -s ... -Duser.home=/ clean compile test-compile 2>&1 | tee mvn.out
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.
请注意,此命令由“sh”管道步骤运行。
此错误消息来自“mvn”脚本内部。如果发现$JAVA_HOME/bin/java
不存在,就会出现此错误。
然后我在此之前添加了几个“sh”调用以显示以下内容:
which java
which mvn
ls -lt $JAVA_HOME/bin/java
在“坏”节点上,前两个命令的结果都是空字符串。这意味着在 PATH 中找不到“java”和“mvn”,或者它们不可执行。在“好”节点上,它们打印“java”和“mvn”可执行文件的预期位置。
第三个命令的输出是这样的:
-rwxr-xr-x. 1 root root 12768 Oct 17 21:48 /opt/java/openjdk/bin/java
在此之前我还添加了“env”输出。它表明“JAVA_HOME”等于“ /opt/java/openjdk
”,并且PATH 中包含mvn 和java 发行版的bin 目录。
这些证据显示了多个因素,但这些因素放在一起是没有意义的。 “mvn”脚本显然抱怨$JAVA_HOME/bin/java
不存在,但 sh 输出清楚地表明它确实存在。 “ which mvn
”输出表明在 PATH 中找不到“mvn”,但是上面的 bash 命令行只执行“mvn”而没有绝对路径,因此它可以到达它的唯一方法是从 PATH 中,并且很明显表明它正在找到它,否则不会从“mvn”脚本内部打印错误消息。
我尝试比较在“好”节点上运行的构建与在“坏”节点上运行的构建的几个方面。例如,我复制了两者的环境变量列表并进行了比较,没有发现显着差异。
我们尝试重新启动错误的构建节点。我们尝试清除整个本地 docker 缓存并重新启动 docker。这些步骤都没有产生任何影响。
我正在寻找任何可能的领域的想法来探索来解释这个问题。我们已经有几个人盯着这个问题很长一段时间了,包括一名维护 Jenkins 构建节点的人、一名维护工具镜像的人,以及其他几位具有丰富经验的人。我们都在这里一片空白。