Nat*_*son 10 ssh jenkins jenkins-plugins docker
我正在尝试从Jenkins管道中的Docker容器内执行SSH命令.我正在使用CloudBees Docker Pipeline插件来启动容器并执行命令,使用SSH代理插件来管理我的SSH密钥.这是我的Jenkinsfile的基本版本:
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"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当SSH命令运行时,我收到此错误:
+ ssh -vvv -o StrictHostKeyChecking=no ubuntu@example.org uname -a
No user exists for uid 1005
Run Code Online (Sandbox Code Playgroud)
Nat*_*son 18
我梳理了日志并意识到Docker Pipeline插件通过传递UID作为命令行参数,自动告诉容器使用登录主机的同一用户运行:
$ docker run -t -d -u 1005:1005 [...]
Run Code Online (Sandbox Code Playgroud)
我决定通过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"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我刚刚找到了这个问题的另一个解决方案,我想分享一下。它与现有解决方案的不同之处在于,它允许在一个代理中运行完整的管道,而不是每个阶段。
诀窍是,不要直接使用图像,而是引用 Dockerfile(可能是构建FROM原始文件),然后添加用户:
# Dockerfile
FROM node
ARG jenkinsUserId=
RUN if ! id $jenkinsUserId; then \
usermod -u ${jenkinsUserId} jenkins; \
groupmod -g ${nodeId} jenkins; \
fi
Run Code Online (Sandbox Code Playgroud)
// Jenkinsfile
pipeline {
agent {
dockerfile {
additionalBuildArgs "--build-arg jenkinsUserId=\$(id -u jenkins)"
}
}
}
Run Code Online (Sandbox Code Playgroud)
@nathan-thompson 提供的解决方案很棒,但就我而言,即使在/etc/passwd主机中我也找不到用户!这意味着挂载passwd文件没有解决问题。这个问题https://superuser.com/questions/580148/users-not-found-in-etc-passwd建议一些用户使用 LDAP 等身份提供者登录主机。
解决方案是找到一种方法将正确的行添加到passwd容器上的文件中。调用getent passwd $USER主机将为passwd运行容器的 Jenkins 用户提供线路。
我添加了一个在节点(而不是 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 ********
"""
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5547 次 |
| 最近记录: |