Jenkins sh 脚本在特定容器中运行时挂起

问题描述 投票:0回答:3

我正在尝试使用官方 ArgoCD docker 映像来自动化部署(https://hub.docker.com/r/argoproj/argocd/dockerfile

我使用 kubernetes 插件为代理创建了一个声明性 jenkins 管道,并使用 yaml 定义了 pod,容器定义如下所示:

pipeline {
    agent {
        kubernetes {
            yaml """
kind: Pod
metadata:
  name: agent
spec:
  containers:
  - name: maven
    image: maven:slim
    command:
    - cat
    tty: true
    volumeMounts:
      - name: jenkins-maven-cache
        mountPath: /root/.m2/repository
  - name: argocd
    image: argoproj/argocd:latest
    command:
    - cat
    tty: true
    ...

我正在尝试在该容器内运行命令,管道中的步骤如下所示:

stage('Build') {
    steps {
        container('maven') {
            sh 'echo testing' // this works just fine
        }
    }
}
stage('Deploy') {
    steps {
        container('argocd') {
            sh "echo testing" // this does not work
            // more deploy scripts here, once sh works
        }
    }
}

所以我有两个容器,一个容器中 sh 脚本工作正常,另一个容器则不能。 “argocd”容器中的 sh 脚本仅挂起 5 分钟,然后 Jenkins 将其杀死,退出消息为:


process apparently never started in /home/jenkins/agent/workspace/job-name@tmp/durable-46cefcae (running Jenkins temporarily with -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true might make the problem clearer)

我无法在这个特定容器中回显简单的字符串。

它在其他容器中运行良好,例如 Docker 的 Maven 官方容器,我用它来构建 Spring Boot 应用程序。我还可以使用 docker exec 从命令行直接在 argocd 容器中手动运行命令,但由于某种原因,jenkins 不会出现在管道中。 可能是什么?

我正在运行最新版本(1.33)的持久任务插件。

更新: 事实证明,argo-cd(持续部署工具)argoproj/argocd:latest的镜像不包含除

argocd
之外的其他命令,所以问题出在我尝试使用的容器镜像上,而不是Jenkins本身。我的解决方案是将 Argo-CD CLI 安装到自定义 docker 容器中并使用它而不是官方容器。

docker jenkins kubernetes continuous-integration sh
3个回答
9
投票

我刚刚在自己创建的自定义 docker 映像中遇到了类似的问题。 事实证明,我在该映像的 Dockerfile 中使用了

USER nobody
,不知何故,这样 Jenkins 代理 pod 就无法从我的管道脚本运行
cat
命令或任何其他 shell 命令。使用 root 用户运行特定容器对我有用。

因此,在您的情况下,我会添加 securityContext: runAsUser: 0 ,如下所示。

...
  - name: argocd
    image: argoproj/argocd:latest
    command:
    - cat
    tty: true
    securityContext:
      runAsUser: 0
...

Kubernetes 参考:https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container


0
投票

虽然 gkc 的答案是正确的,但我想进一步说明原因。我以非 root 用户身份使用

sh
运行了
LAUNCH_DIAGNOSTICS=true
,并在写入由
持久任务插件
管理的各种文件时看到了许多 permission denied 错误。

我正在使用 Kubernetes 插件,pod 中有多个容器。据我所知,这些文件是由 jnlp 容器中的用户创建和拥有的。因此,当在第二个容器中运行

sh
时,用户需要这些文件的权限。如果两个容器以同一用户身份运行,或者第二个容器以 root 身份运行,则这应该有效。

仍然可以通过设置

runAsUser: 0
然后使用 sudo 切换到其他用户来以其他用户身份运行命令:

sh "sudo -H -u newuser bash -c 'whoami'"

-2
投票

如果问题与 Jenkins 相关,这里有一些可能有助于解决问题的事情:

  1. 工作目录的问题,如果您从某个旧版本更新了 Jenkins,则工作目录是
    /home/jenkins
    ,而在最近的版本中它应该是
    /home/jenkins/agent
    或者,如果您在 Windows 中运行它,路径应以
    C:\dir
    开头,而不是
    /dir
  2. 您可以使用
    apt-get --purge remove jenkins
    尝试全新安装,然后使用
    apt-get install jenkins
  3. 这不是您的情况,因为您运行最新版本的持久任务插件。但对于其他人参考 1.28-1.30 之前的版本导致了同样的问题.

如果您的 Jenkins 是干净的,则应该以不同的方式调查问题,似乎它不会向 sh 命令返回退出代码和/或脚本在不同的 shell 中执行。 我会尝试将 sh 文件放置在容器的工作目录中

#!/bin/bash
echo "testing"
echo $?

并尝试使用

source my_script.sh
运行它 或与
bash my_script.sh

$?是最新 bash 操作的退出代码,将其打印出来将确保您的脚本正确终止。运行脚本的 source 命令将使其在调用它的同一个 shell 中运行,以便可以访问 shell 变量。 Bash 命令将在另一个子 shell 中运行它。

© www.soinside.com 2019 - 2024. All rights reserved.