带有 jenkins 插件的 Nodejs 在高山图像中不可执行并显示“找不到符号”

Jer*_*u M 2 node.js jenkins docker alpine-linux

背景

我们安装了节点版本 8,并且在基于 Jenkins alpine 的 docker 映像(在 AWS ECS 中运行)中运行良好。节点 8 安装在 jenkins-alpine docker 镜像中。

然后,又来了一个安装nodejs Jenkins插件的需求,这样自定义版本就可以根据需要使用全局工具配置安装和应用,我们安装了nodejs 10,如下图所示: Node JS jenkins 插件

Nodejs 插件无法在 jenkins 中运行

然后我尝试在 jenkins 管道中使用 jenkins nodejs 10 插件,如下所示:

#!groovy?

pipeline {
    options {
        buildDiscarder(logRotator(daysToKeepStr: '5'))
        timeout(time: 5, unit: 'MINUTES')
        ansiColor('xterm')
    }
    agent {
        label 'jenkins-slave'
    }
    stages {
        stage('Nodejs test') {
            steps {
                nodejs('NodeJS 10.19.0') {
                    sh "which node; which npm"
                    sh "ls -l /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node"
                    sh "node -v"
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

jenkins 作业失败,因为它找不到节点,即使它确实存在并且是可执行的:

11:00:31  + which node
11:00:31  /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node
11:00:31  + which npm
11:00:31  /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/npm
[Pipeline] sh
11:00:31  + ls -l /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node
11:00:31  -rwxrwxr-x 1 jenkins jenkins 41122344 Feb  5 23:36 /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node

11:00:32  + /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node -v
11:00:32  /var/jenkins_home/workspace/test-jerald-nodejs-plugin@tmp/durable-55482f4f/script.sh: line 1: /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: not found

Run Code Online (Sandbox Code Playgroud)

在 jenkins slave docker 容器内进行测试

我尝试直接在 jenkins slave docker 容器中执行 node version 命令,但是,输出是相同的。然后我用谷歌搜索并引用了以下线程,其中提到这是因为缺少 nodejs 所需的库。 找不到Jenkins NodeJSPlugin节点命令

以下是从 jenkins 插件中查找 nodejs 共享库的初始输出

bash-4.4$ ldd /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node
    /lib64/ld-linux-x86-64.so.2 (0x7fcbe2e7e000)
    libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7fcbe2e7e000)
    librt.so.1 => /lib64/ld-linux-x86-64.so.2 (0x7fcbe2e7e000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7fcbe2d29000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fcbe2e7e000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7fcbe2d15000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7fcbe2e7e000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fcbe2e7e000)
Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node)
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: gnu_get_libc_version: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: __register_atfork: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: setcontext: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: makecontext: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: backtrace: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: getcontext: symbol not found
Run Code Online (Sandbox Code Playgroud)

然后我使用以下命令安装了缺少的库:

apk add libc6-compat gcompat
Run Code Online (Sandbox Code Playgroud)

安装缺少的库后,没有与缺少库相关的错误,但是仍然存在“找不到符号”的错误并且节点仍然无法执行。

bash-4.4# ldd /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node
    /lib64/ld-linux-x86-64.so.2 (0x7f0e698f6000)
    libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f0e698f6000)
    librt.so.1 => /lib64/ld-linux-x86-64.so.2 (0x7f0e698f6000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f0e697a1000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f0e698f6000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f0e6978d000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f0e698f6000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f0e698f6000)
    ld-linux-x86-64.so.2 => /lib/ld-linux-x86-64.so.2 (0x7f0e69787000)
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: gnu_get_libc_version: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: __register_atfork: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: setcontext: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: makecontext: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: backtrace: symbol not found
Error relocating /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_10.19.0/bin/node: getcontext: symbol not found
bash-4.4# 
Run Code Online (Sandbox Code Playgroud)

我还检查了现有 node v8 的共享库,它没有问题:

bash-4.4# which node
/usr/local/bin/node
bash-4.4# ldd /usr/local/bin/node
    /lib/ld-musl-x86_64.so.1 (0x7f1e07118000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f1e0539f000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f1e0538b000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f1e07118000)

bash-4.4# /usr/local/bin/node -v
v8.11.3

Run Code Online (Sandbox Code Playgroud)

那么有人可以帮助我让 Jenkins nodejs 插件工作吗?

val*_*ano 6

使用 Jenkins GUI,您已经安装了“主流”Linux NodeJS 插件。从上面的输出可以清楚地看出这个插件与 Alpine Linux 不兼容。

Alpine Linux 建立在musl-libc(musl 标准 C 库)之上,而大多数 Linux 发行版都是围绕glibc(GNU 的标准 C 库)构建的。libc 库为任何本机 Linux 程序提供基本设施,包括标准 C 和 POSIX API,并且是操作系统的固有部分。因此,在具有不同 libc 实现的不同操作系统上构建的二进制文件,例如 Alpine 的 musl 和 Debian 的 glibc,通常不会混合使用,因为这些实现并不完全兼容。

您提到的缺少的库,libc6-compat以及gcompat围绕 Alpine 的 musl 添加一个 glibc 兼容层,它允许运行简单的glibc 程序。但是,它不提供所有 glibc API - 因此缺少符号。

对于 Alpine 上的 nodejs,您通常应该安装nodejsAlpine 存储库的包,但不幸的是没有提供 Jenkins 插件。您需要一个与musl libc 兼容的nodeJS Jenkins 插件 - 我不确定是否有可用的插件。

有几种选择:

  1. 您可以通过在您的 Alpine 容器(示例)上安装适当的 glibc 在 Alpine Linux 上使用“完整 glibc” 。但是,这将需要重构您当前的图像,并且您会失去 Alpine 图像的“纯度”。
  2. 如果找不到与 musl 兼容的插件,请考虑切换到(不太)紧凑的、与 glibc 兼容的基础映像,例如debian.
  3. 或者,尝试在 Alpine Linux 上从源代码构建 Jenkins 插件,然后手动安装。