EC2用户数据中Bash脚本无法复制SSH密钥至远程服务器排查
通过Terraform的EC2用户数据Bash脚本自动化部署时,除ssh-copy-id复制密钥到远程服务器的步骤外,其余安装软件包、生成SSH密钥的功能均正常。
相关脚本片段:
SERVERS=("server1" "server2") for SERVER in "$${SERVERS[@]}" do sudo -u ${USER} /usr/bin/sshpass -p ${PASSWORD} ssh-copy-id -f -i /home/ansible/.ssh/id_rsa.pub ${USER}@$SERVER done
已提前安装sshpass和ssh-copy-id,查看/var/log/cloud-init-output.log仅输出:
/ssh-copy-id: INFO: Source of keys to be installed: '/home/ansible/.ssh/id_rsa.pub'
但密钥并未实际复制到远程服务器。实例启动后手动执行该脚本片段可成功复制,且已确认${USER}和${PASSWORD}变量正确,日志无报错。补充:$${SERVERS[@]}是为避免Terraform与Shell冲突的写法,即便此处有误也会出现主机名解析错误,可排除此问题。
禁用SSH严格主机密钥检查
cloud-init运行时,远程服务器的主机密钥尚未加入本地known_hosts,ssh-copy-id会因首次连接的主机确认提示静默失败(无日志输出)。修改命令添加-o StrictHostKeyChecking=no参数:sudo -u ${USER} /usr/bin/sshpass -p ${PASSWORD} ssh-copy-id -f -o StrictHostKeyChecking=no -i /home/ansible/.ssh/id_rsa.pub ${USER}@$SERVER开启详细日志排查
在ssh-copy-id中加入-vvv参数获取完整执行细节,同时重定向输出到独立日志文件:sudo -u ${USER} /usr/bin/sshpass -p ${PASSWORD} ssh-copy-id -f -vvv -i /home/ansible/.ssh/id_rsa.pub ${USER}@$SERVER >> /var/log/ssh-copy-id.log 2>&1后续查看
/var/log/ssh-copy-id.log即可定位具体问题,比如连接超时、权限不足等。添加重试逻辑应对远程服务未就绪
cloud-init脚本执行时机较早,可能远程服务器的SSH服务尚未完全启动,或者实例间安全组未开放22端口。可增加循环重试:for SERVER in "$${SERVERS[@]}" do # 最多重试5次,每次间隔10秒 for i in {1..5}; do sudo -u ${USER} /usr/bin/sshpass -p ${PASSWORD} ssh-copy-id -f -o StrictHostKeyChecking=no -i /home/ansible/.ssh/id_rsa.pub ${USER}@$SERVER && break sleep 10 done done确保sudo切换到完整用户环境
使用sudo -u ${USER} -i切换到目标用户的完整环境执行命令,避免环境变量缺失导致的异常:sudo -u ${USER} -i /usr/bin/sshpass -p ${PASSWORD} ssh-copy-id -f -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub ${USER}@$SERVER
内容的提问来源于stack exchange,提问作者Typewriter

