我正在同一个镜像中运行 Jenkins 的 Docker 容器和 Ansible。 Ansible 正在更新同一 Docker 网络上的另一个 Docker 容器。
使用 ssh 密钥文件。
使用root用户和用户jenkins进行测试
两位用户都进行了测试。我可以使用 CLI 从 Jenkins/Ansible 容器 ssh 到目标容器。我可以在 CLI 上运行剧本并且它可以工作,只有当我通过 Jenkins pipline 运行剧本时才会失败。
如果我运行 Jenkins 尝试的相同命令(从 Jenkins 控制台复制)。我所做的唯一更改是将 tmp ssh 密钥更改为真实密钥。临时密钥来自 Jenkins 凭证。该剧本运行良好。
--private-key /var/lib/jenkins/workspace/TestJs/ssh9809173197875714932.key
真正的钥匙
--private-key /var/lib/jenkins/.ssh/jenkins_key
/usr/bin/ansible-playbook /var/lib/jenkins/workspace/TestJs/deploy/playbooks/deployToTarget.yml -i /var/lib/jenkins/workspace/TestJs/deploy/playbooks/inventory.inv --private-key /var/lib/jenkins/.ssh/jenkins_key -u jenkins
上述对 Jenkins Docker cli 的调用按预期工作。
为了排除 Jenkins 临时密钥并验证 Jenkins 密钥凭据,我编写了一个简单的 pipline,它直接连接到主机并运行 shell 脚本,该脚本连接良好并按预期工作。
管道片段
stages {
stage('Deploy on Test') {
steps {
ansiblePlaybook( credentialsId: 'TEST_HOST_SSH_KEY',
disableHostKeyChecking: true,
installation: 'Ansible',
inventory: "${WORKSPACE}/deploy/playbooks/inventory.inv",
playbook: "${WORKSPACE}/deploy/playbooks/deployToBSI_SMA.yml",
colorized: true)
}
}
}
控制台每次都会显示这个错误。我承认我在这个问题上很挣扎。
PLAY [Deploy On Test] ***************************************************
TASK [Gathering Facts] *********************************************************
[1;31mfatal: [bsi_sma]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: muxserver_listen: link mux listener /var/lib/jenkins/.ansible/cp/119f480311.4lIaQB6LhOC2svmf => /var/lib/jenkins/.ansible/cp/119f480311: Bad file descriptor", "unreachable": true}[0m
PLAY RECAP *********************************************************************
[0;31mbsi_sma[0m : ok=0 changed=0 [1;31munreachable=1 [0m failed=0 skipped=0 rescued=0 ignored=0
非常感谢任何帮助,我在这个问题上花了很多天。
这通常与 SSH 用于连接共享的控制路径有关。 当 Ansible 在 Jenkins 中运行时,这看起来像是 SSH 连接复用的问题。
要修复此问题,请将其添加到您的 Ansible 配置 (ansible.cfg) 中:
[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r
control_persist = no
禁用
control_persist
可以避免使用可能导致容器内出现“错误文件描述符”问题的控制套接字。
确保 Jenkins 管道使用正确的持久密钥 (/var/lib/jenkins/.ssh/jenkins_key),而不是临时密钥。
此外,Jenkins 用户应该对 Ansible 控制路径目录 (/var/lib/jenkins/.ansible/cp/) 具有写入权限。
应该可以了。