我试图从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
答案 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'
'''
}