如何检查是否与AWS实例建立了SSH连接

时间:2013-03-21 20:03:20

标签: python ssh amazon-web-services amazon-ec2 boto

我正在尝试使用boto通过SSH连接到Amazon EC2实例。我知道在创建实例后的一段时间后可以建立ssh连接。所以我的问题是:

  • 我可以以某种方式检查SSH是否在实例上? (如果是这样,怎么样?)
  • 或者如何检查boto.manage.cmdshell.sshclient_from_instance()的输出?我的意思是,例如,如果输出打印出Could not establish SSH connection,而不是再试一次。

这就是我到目前为止所尝试的,但没有运气:

if instance.state == 'running':
    retry = True
    while retry:
        try:
            print 'Connecting to ssh'
            key_path = os.path.join(os.path.expanduser('~/.ssh'), 'secret_key.pem')
            cmd = boto.manage.cmdshell.sshclient_from_instance(instance,
                                                               key_path,
                                                               user_name='ec2-user')

            print instance.update()
            if cmd:
                retry = False
        except:
            print 'Going to sleep'
            time.sleep(10)

SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
Could not establish SSH connection

当然一切正常,因为我可以在一段时间后启动相同的代码并获得连接,并且可以使用cmd.shell()

2 个答案:

答案 0 :(得分:7)

消息“SSH连接被拒绝,将在5秒后重试”来自boto:http://code.google.com/p/boto/source/browse/trunk/boto/manage/cmdshell.py

最初,'running'只是暗示实例已经开始启动。只要sshd未启动,就会拒绝与端口22的连接。因此,如果sshd在“运行”状态的前25秒内没有出现,那么你所观察到的绝对是可以预期的。

由于在sshd完全出现时无法预测,并且如果您不想通过定义一个长时间不变的等待时间而浪费时间,您可以实现自己的轮询代码,例如: 1到5秒的间隔检查端口22是否可达。仅当它调用boto.manage.cmdshell.sshclient_from_instance()

测试特定主机的某个TCP端口是否可访问的简单方法是通过socket模块:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    s.connect(('hostname', 22))
    print "Port 22 reachable"
except socket.error as e:
    print "Error on connect: %s" % e
s.close()

答案 1 :(得分:0)

我分为两部分,一部分检查实例是否正在运行,然后另一部分检查实例是否可达

# Get instance status till it is running
status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
instance_status=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceState.Name)
echo $instance_status
while [ ${instance_status:1:-1} != running ]
do
    status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
    instance_status=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceState.Name)
    echo $instance_status
done

# Get instance reachability till it is ready 
status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
instance_reachability=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceStatus.Status)
echo $instance_reachability
while [ ${instance_reachability:1:-1} != ok ]
do
    status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
    instance_reachability=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceStatus.Status)
    echo $instance_reachability
done