如何检查与AWS实例的SSH连接是否建立
我正在尝试通过 boto
连接到亚马逊的 EC2 实例,使用的是 SSH。因为我知道在实例创建后过一段时间才能建立 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 个回答
1
我有两个部分,一个是用来检查这个实例是否在运行,另一个是用来检查这个实例是否可以访问。
# 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
7
“SSH连接被拒绝,将在5秒后重试”的信息来自boto库:http://code.google.com/p/boto/source/browse/trunk/boto/manage/cmdshell.py
一开始,‘运行中’只是表示这个实例已经开始启动了。只要sshd
(SSH守护进程)还没有启动,连接到22号端口的请求就会被拒绝。所以,如果在‘运行中’状态的前25秒内sshd
没有启动,你看到的情况是完全正常的。
因为我们无法准确预测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()