如何通过Jenkins Pipeline在第二台AWS Ubuntu服务器拉取部署Docker镜像
问题根源
你遇到的核心问题是SSH命令的写法错误!当前脚本里的这条命令:
ssh -o StrictHostKeyChecking=no ubuntu@2ndserver && cd /home/ubuntu/ && sudo touch test-file && docker pull docker-user/docker-repo:flask-app-push-test
这里的&&是本地Shell的逻辑运算符,它的执行逻辑是:先通过ssh登录到2nd-server,一旦SSH会话自动退出(因为你没指定要执行的远程命令),就会回到**1st-server(Jenkins代理所在服务器)**执行后面的cd、touch和docker pull——这就是为什么测试文件会出现在1st-server上,完全没在目标服务器上执行操作!
修正方案
1. 正确编写SSH远程执行命令
要让命令在2nd-server上运行,必须把所有需要远程执行的命令作为ssh的参数,用单引号包裹(避免本地Shell解析变量)。修改后的命令应该是:
ssh -o StrictHostKeyChecking=no ubuntu@2ndserver 'cd /home/ubuntu/ && sudo touch test-file && docker pull docker-user/docker-repo:flask-app-push-test'
单引号里的所有命令都会在2nd-server的SSH会话中执行,完成后自动退出会话。
2. 解决远程sudo的密码阻塞问题
远程执行sudo时默认会要求输入密码,这会导致Jenkins Pipeline卡住。你需要在2nd-server上给ubuntu用户配置免密sudo权限:
- 登录2nd-server,执行
sudo visudo(安全编辑sudoers文件) - 根据安全需求二选一添加配置:
- 完全免密(简单但权限范围大):
ubuntu ALL=(ALL) NOPASSWD: ALL - 仅允许特定命令(更安全):
ubuntu ALL=(ALL) NOPASSWD: /usr/bin/touch, /usr/bin/docker
- 完全免密(简单但权限范围大):
3. 优化Pipeline结构(可选但推荐)
把部署步骤从镜像推送阶段分离出来,单独做一个Deploy to 2nd-server阶段,让Pipeline逻辑更清晰。另外,Build阶段的docker run如果重复执行会报错(容器已存在),可以加前置判断清理旧容器。
修正后的完整Pipeline脚本
pipeline { environment { registry = "docker-user/docker-repo" registryCredential = 'docker-cred' dockerImage = '' } agent any stages { stage('Cloning Git') { steps { git url: 'https://github.com/git-user/jenkins-flask-tutorial.git/' } } stage('Building image') { steps{ script { // 先清理旧容器(如果存在),避免重复运行报错 sh "sudo docker stop flask-app-one || true" sh "sudo docker rm flask-app-one || true" // 构建并运行容器 sh "sudo docker build -t flask-app-one ." sh "sudo docker run -p 5000:5000 --name flask-app-one -d flask-app-one " // 打标签准备推送 sh "docker tag flask-app-one:latest ${registry}:flask-app-push-test" } } } stage('Push Image to Docker Hub') { steps{ script { docker.withRegistry( '', registryCredential ) { sh "docker push ${registry}:flask-app-push-test" } } } } stage('Deploy to 2nd-server') { steps { sshagent(['my-ssh-key']) { sh ''' ssh -o StrictHostKeyChecking=no ubuntu@2ndserver ' cd /home/ubuntu/ && sudo touch test-file && docker pull docker-user/docker-repo:flask-app-push-test ' ''' } } } } }
额外提示
sshagent加载密钥的部分是正确的,只要Jenkins凭证里的my-ssh-key是2nd-server的私钥就没问题。- 如果远程执行
docker pull时提示权限问题,可在2nd-server执行sudo usermod -aG docker ubuntu,把ubuntu用户加入docker组,之后就不需要用sudo docker命令了。
内容的提问来源于stack exchange,提问作者rajeev singh
相关产品推荐
相关产品推荐

