JenkinsパイプラインのDockerコンテナ内からSSHコマンドを実行しようとしています。 CloudBees Docker Pipeline Plugin を使用してコンテナーを起動し、コマンドを実行し、 SSH Agent Plugin を使用してSSHキーを管理しています。これが私のJenkinsfileの基本バージョンです:
node {
step([$class: 'WsCleanup'])
docker.image('node').inside {
stage('SSH') {
sshagent (credentials: [ 'MY_KEY_UUID' ]) {
sh "ssh -vvv -o StrictHostKeyChecking=no [email protected] uname -a"
}
}
}
}
SSHコマンドを実行すると、次のエラーが発生します。
+ ssh -vvv -o StrictHostKeyChecking=no [email protected] uname -a
No user exists for uid 1005
ログを調べたところ、Docker Pipeline Pluginが、コマンドライン引数として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 [email protected] uname -a"
}
}
}
}
@ nathan-thompsonが提供するソリューションは素晴らしいですが、私の場合、ホストマシンの/etc/passwd
でもユーザーを見つけることができませんでした。これは、passwd
ファイルをマウントしても問題が解決しなかったことを意味します。この質問 https://superuser.com/questions/580148/users-not-found-in-etc-passwd 一部のユーザーがLDAPなどのIDプロバイダーを使用してホストにログインしていることを示唆しています。
解決策は、コンテナの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 ********
"""
}
}
}