Jenkins Pipeline的Docker插件 - uid 1005没有用户

时间:2017-02-22 23:47:15

标签: jenkins docker ssh jenkins-plugins

我试图从Jenkins管道中的Docker容器内执行SSH命令。我使用CloudBees Docker Pipeline Plugin来启动容器并执行命令,使用SSH Agent Plugin来管理我的SSH密钥。这是我的Jenkins文件的基本版本:

node {
  step([$class: 'WsCleanup'])
  docker.image('node').inside {
    stage('SSH') {
      sshagent (credentials: [ 'MY_KEY_UUID' ]) {
        sh "ssh -vvv -o StrictHostKeyChecking=no ubuntu@example.org uname -a"
      }
    }
  }
}

当SSH命令运行时,我收到此错误:

+ ssh -vvv -o StrictHostKeyChecking=no ubuntu@example.org uname -a
No user exists for uid 1005

4 个答案:

答案 0 :(得分:15)

我梳理了日志并意识到Docker Pipeline插件通过传递UID作为命令行参数,自动告诉容器使用登录主机的同一用户运行:

$ docker run -t -d -u 1005:1005 [...]

我决定通过在每个环境中运行cat /etc/passwd来检查主机和容器中存在的用户。果然,每个用户列表都不同。 1005是主机上的jenkins用户,但容器中不存在该UID。为了解决这个问题,我在将它旋转时将/etc/passwd从主机挂载到容器中:

node {
  step([$class: 'WsCleanup'])
  docker.image('node').inside('-v /etc/passwd:/etc/passwd') {
    stage('SSH') {
      sshagent (credentials: [ 'MY_KEY_UUID' ]) {
        sh "ssh -vvv -o StrictHostKeyChecking=no ubuntu@example.org uname -a"
      }
    }
  }
}

答案 1 :(得分:4)

我刚刚找到了我想分享的另一种解决方案。它与现有解决方案的不同之处在于,它允许在一个代理中而不是每个阶段运行完整的管道。

诀窍在于,而不是直接使用映像,而是引用Dockerfile(它可能是原始版本FROM的版本),然后添加用户:

# Dockerfile
FROM node

ARG jenkinsUserId=
RUN if ! id $jenkinsUserId; then \
    usermod -u ${jenkinsUserId} jenkins; \
    groupmod -g ${nodeId} jenkins; \
  fi
// Jenkinsfile
pipeline {
  agent {
    dockerfile {
      additionalBuildArgs "--build-arg jenkinsUserId=\$(id -u jenkins)"
    }
  }
}

答案 2 :(得分:0)

@ nathan-thompson提供的解决方案很棒,但就我而言,即使在主机的/etc/passwd中,我也找不到用户!这意味着挂载passwd文件不能解决问题。这个问题https://superuser.com/questions/580148/users-not-found-in-etc-passwd建议某些用户使用诸​​如LDAP之类的身份提供程序登录主机。

解决方案正在寻找一种方法,以将正确的行添加到容器上的passwd文件中。在主机上调用getent passwd $USER将为运行容器的Jenkins用户提供passwd行。

我添加了一个在节点(而不是Docker代理)上运行的步骤,以获取该行并将其保存在文件中。然后在下一步中,将生成的passwd挂载到容器:

stages {
    stage('Create passwd') {
        steps {
            sh """echo \$(getent passwd \$USER) > /tmp/tmp_passwd
            """
        }
    }
    stage('Test') {
        agent {
            docker {
                image '*******'
                args '***** -v /tmp/tmp_passwd:/etc/passwd'
                reuseNode true
                registryUrl '*****'
                registryCredentialsId '*****'
            }
        }
        steps {
            sh """ssh -i ********
            """
        }
    }
}

答案 3 :(得分:0)

    agent {
        docker {
            image 'node:14.10.1-buster-slim'
            args '-u root:root'
        }

    }

    environment {
        SSH_deploy = credentials('e99988ea-6bdc-45fc-b9e1-536b875bcac7')
    }

stage('build') {
            steps {
                sh '''#!/bin/bash
                    eval $(ssh-agent -s)
                    cat $SSH_deploy | tr -d '\r' | ssh-add -
                    touch .env
                    echo 'REACT_APP_BASE_API = "//172.22.132.115:8080"' >> .env
                    echo 'REACT_APP_ADMIN_PANEL_URL = "//172.22.132.115"' >> .env
                    yarn install
                    CI=false npm run build
                    ssh -t -o StrictHostKeyChecking=no root@172.22.132.115 'rm -rf /usr/local/src/build'
                    scp -r -o StrictHostKeyChecking=no build root@172.22.132.115:/usr/local/src/
                    ssh -t -o StrictHostKeyChecking=no root@172.22.132.115 'systemctl restart nginx'
                 '''
            }