CircleCI执行Ansible任务连接EC2报错:SSH协议Banner读取失败
解决CircleCI中Ansible连接EC2时的SSH重置错误
问题概述
在CircleCI任务中执行Ansible配置EC2实例时,持续抛出Error reading SSH protocol banner[Errno 104] Connection reset by peer错误,wait_for_connection任务超时失败。本地可正常SSH连接目标EC2实例,且已在CircleCI项目中配置对应SSH密钥指纹。
可能的原因及解决步骤
1. 验证EC2安全组是否允许CircleCI的IP访问
EC2安全组的SSH入站规则可能仅允许本地IP,拒绝了CircleCI执行环境的IP:
- 临时修改EC2安全组的22端口入站规则,允许
0.0.0.0/0(测试用,后续需恢复),重新运行CircleCI任务确认是否解决。 - 若测试有效,查询CircleCI官方IP段,将其添加到安全组的SSH允许列表中,保证长期访问权限。
2. 优化Ansible SSH连接参数
调整Ansible的SSH连接参数,提升连接稳定性:
在playbook的vars中添加:
vars: - ansible_ssh_common_args: '-o ConnectTimeout=15 -o ConnectionAttempts=10 -o TCPKeepAlive=yes'
同时修改wait_for_connection任务,增加重试逻辑:
- name: wait for target connection to become reachable ansible.builtin.wait_for_connection: delay: 10 timeout: 600 sleep: 5
3. 确认CircleCI的SSH密钥正确加载
在CircleCI任务的Configure server步骤前,添加密钥检查命令,确认密钥已正确加载:
- run: name: Verify SSH key command: ssh-add -l
输出中应包含配置的指纹,若未显示,检查CircleCI项目中SSH密钥的指纹是否配置正确,以及密钥是否对应EC2实例~/.ssh/authorized_keys中的公钥。
4. 拆分等待逻辑:先等端口,再等SSH服务
将原有的wait_for_connection拆分为两步,先确保22端口开放,再等待SSH服务就绪:
pre_tasks: - name: Wait for SSH port to be open ansible.builtin.wait_for: port: 22 host: '{{ inventory_hostname }}' timeout: 600 state: started - name: Wait for SSH connection to be usable ansible.builtin.wait_for_connection: delay: 5 timeout: 300
5. 更换CircleCI执行环境镜像
Alpine镜像的依赖库可能存在兼容性问题,换成Ubuntu/Debian系的Python镜像:
修改CircleCI任务的docker配置:
docker: - image: cimg/python:3.7
然后调整依赖安装命令:
- run: name: Install dependencies command: | sudo apt update && sudo apt install -y ansible pip install awscli
6. 确保Ansible与Paramiko版本兼容
Alpine包管理器安装的Ansible可能与Paramiko版本不匹配,改用pip安装指定版本的Ansible:
修改CircleCI的依赖安装命令:
- run: name: Install dependencies command: | apk add --update tar gzip openssh-client pip install ansible==2.10.10 paramiko==2.7.2 awscli
内容的提问来源于stack exchange,提问作者KHCoding El
相关产品推荐
相关产品推荐

