我正在编写一个脚本,用boto旋转一个新的EC2实例,并使用Paramiko SSH客户端在实例上执行远程命令。无论出于何种原因,Paramiko客户端无法连接,我收到错误:
Traceback (most recent call last):
File "scripts/sconfigure.py", line 29, in <module>
ssh.connect(instance.ip_address, username='ubuntu', key_filename=os.path.expanduser('~/.ssh/test'))
File "build/bdist.macosx-10.3-fat/egg/paramiko/client.py", line 291, in connect
File "<string>", line 1, in connect
socket.error: [Errno 61] Connection refused
我可以使用相同的密钥文件和用户手动ssh。有没有人使用Paramiko遇到问题?我的完整代码如下。感谢。
import boto.ec2, time, paramiko, os
# Connect to the us-west-1 region
ec2 = boto.ec2.regions()[3].connect()
image_id = 'ami-ad7e2ee8'
image_name = 'Ubuntu 10.10 (Maverick Meerkat) 32-bit EBS'
new_reservation = ec2.run_instances(
image_id=image_id,
key_name='test',
security_groups=['web'])
instance = new_reservation.instances[0]
print "Spinning up instance for '%s' - %s. Waiting for it to boot up." % (image_id, image_name)
while instance.state != 'running':
print "."
time.sleep(1)
instance.update()
print "Instance is running, ip: %s" % instance.ip_address
print "Connecting to %s as user %s" % (instance.ip_address, 'ubuntu')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(instance.ip_address, username='ubuntu', key_filename=os.path.expanduser('~/.ssh/test'))
stdin, stdout, stderr = ssh.exec_command('echo "TEST"')
print stdout.readlines()
ssh.close()
答案 0 :(得分:10)
我似乎通过反复试验弄明白了。即使实例状态是根据boto“运行”,实际允许SSH连接的时间也会延迟。在“ssh.connect(...)”之前添加“time.sleep(30)”似乎对我有用,尽管这可能会有所不同。
答案 1 :(得分:2)
为什么不使用boto.manage.cmdshell
?
cmd = boto.manage.cmdshell.sshclient_from_instance(instance,
key_path,
user_name='ec2_user')
(代码取自ec2_launch_instance.py中的第152行)
对于可用的cmdshell
命令,请查看cmdshell.py中的SSHClient
类。
答案 2 :(得分:2)
检查它的可用ssh的方法是确保它的两个状态检查都通过。在Web UI上,它看起来像这样:
使用boto3(原始问题使用boto但它是5年前),我们可以这样做:
session = boto3.Session(...)
client = session.client('ec2')
res = client.run_instances(...) # launch instance
instance_id = res['Instances'][0]['InstanceId']
while True:
statuses = client.describe_instance_status(InstanceIds=[instance_id])
status = statuses['InstanceStatuses'][0]
if status['InstanceStatus']['Status'] == 'ok' \
and status['SystemStatus']['Status'] == 'ok':
break
print '.'
time.sleep(5)
print "Instance is running, you are ready to ssh to it"
答案 3 :(得分:1)
我最近遇到过这个问题。 “正确”的方法是首先启动close()然后重新打开连接。但是在旧版本中,close()被破坏了。
使用此版本或更高版本时,应修复: https://github.com/boto/boto/pull/412
“正确”方法:
newinstance = image.run(min_count=instancenum, max_count=instancenum, key_name=keypair, security_groups=security_group, user_data=instancename, instance_type=instancetype, placement=zone)
time.sleep(2)
newinstance.instances[0].add_tag('Name',instancename)
print "Waiting for public_dns_name..."
counter = 0
while counter < 70:
time.sleep(1)
conn.close()
conn = boto.ec2.connection.EC2Connection(ec2auth.access_key,ec2auth.private_key)
startedinstance = conn.get_all_instances(instance_ids=str(newinstance.instances[0].id))[0]
counter = counter + 1
if str(startedinstance.instances[0].state) == "running":
break
if counter == 69:
print "Timed out waiting for instance to start."
print "Added: " + startedinstance.instances[0].tags['Name'] + " " + startedinstance.instances[0].public_dns_name
答案 4 :(得分:0)
我最近查看了此代码,并对代码提出了建议, 您可以尝试“ wait_until_running()”,而不是运行while循环来检查实例是否正在运行。
以下是示例代码...
only screen
之后,尝试为ssh连接代码进行编码。