关于lightsail
- Amazon Lightsail 以经济实惠的月度价格提供易于使用的虚拟专用服务器 (VPS) 实例、容器、存储、数据库等。
- lightsail 和国内公有云厂商的轻量应用服务器类似,都是通过 计算+存储+网络 的方式以套餐的方式进行售卖。相比云服务器而言,多出了一些应用镜像,价格相对较低,可以说是对开发者相当友好了。
需求背景
- 如果只是一台机器的话,很多操作大家都可以在aws的lightsail控制台完成。但是如果是多台,甚至几百台机器的话管理上就是一个大问题了。
- 本文会描述两个场景:创建机器的时候需要开服务器的端口,lightsail不支持多台机器共用一个端口规则,如果是多台机器的话需要一台一台的去设置。各位,请不要质疑我的判断。这个过程会非常痛苦,亲身经历一个小时大概只能设置几十台。不仅考验手速,也很考验大家的网络质量。
具体实现
- 如果只是设置几十台机器也还好,搞一个小时就能过去。但是如果是几百甚至上千台,这个真的要把人搞奔溃了。而且除了改端口的规则之外,还有有一个新的需求:aws的lightsail 虽然和国内云服务商的轻量应用服务器很类似,但是cpu这里是不太一样的,国内 阿里云、腾讯云 都保证cpu是100%性能,但是lightsail 的cpu并不是100%,它会有一个基准的cpu性能,具体取决于 lightsail 的规格,超出的时候会消耗cpu积分,如果cpu积分消耗殆尽机器很容易死机。要从几百台机器中找到死机的机器也是一件很痛苦的事情了。
- 好在aws有提供api接口,我们可以借助api批量去开通lightsail实例的端口,以及检测它们的运行状态。
环境准备
- 这里使用aws提供的python工具包Boto3,python版本需要是3.7或以上。
- 还需要安装aws configure用来配置AK,AK可以在aws的控制台去创建。
用到的接口
- GetInstances:用来获取账号下对应地域的实例列表,当实例列表大于20个时,需要注意下响应的 nextPageToken 这个分页参数
- OpenInstancePublicPorts:用于开启lightsail实例的端口
- RebootInstance:用于重启指定机器
import boto3
import json
from botocore.config import Config
import telnetlib
def get_config(region_name):
return Config(region_name=region_name)
def get_client(region_name):
return boto3.client('lightsail', config=get_config(region_name))
def open_ports(client, instance_name):
client.open_instance_public_ports(
portInfo={
'fromPort': 1024,
'toPort': 65535,
'protocol': 'tcp',
'cidrs': [
'0.0.0.0/0',
],
'ipv6Cidrs': [
'::/0',
]
},
instanceName=instance_name
)
client.open_instance_public_ports(
portInfo={
'fromPort': 1024,
'toPort': 65535,
'protocol': 'udp',
'cidrs': [
'0.0.0.0/0',
],
'ipv6Cidrs': [
'::/0',
]
},
instanceName=instance_name
)
client.open_instance_public_ports(
portInfo={
'fromPort': -1,
'toPort': -1,
'protocol': 'icmp',
'cidrs': [
'0.0.0.0/0',
]
},
instanceName=instance_name
)
def get_instances_list(client, result, instances):
if('nextPageToken' in result):
instances += result['instances']
result = client.get_instances(pageToken = result['nextPageToken'])
return get_instances_list(client, result, instances)
else:
return instances + result['instances']
def reboot_instace(client, instance_name):
client.reboot_instance(instanceName=instance_name)
def check_ssh_port(instace_ip):
try:
telnetlib.Telnet(host=instace_ip, port="22", timeout=3)
return True
except:
return False
if __name__ == '__main__':
regions = [
# 'eu-west-1',
# 'eu-west-2',
# 'eu-west-3',
# 'eu-central-1',
# 'ca-central-1',
# 'us-east-1',
# 'eu-north-1',
# 'us-east-2',
# 'ap-south-1',
# 'us-west-2',
# 新加坡
'ap-southeast-1',
# 首尔
# 'ap-northeast-2',
# 东京
# 'ap-northeast-1',
# 'ap-southeast-2'
]
count = 0
for i in range(0, len(regions)):
client = get_client(regions[i])
result = client.get_instances()
instances = get_instances_list(client, result, [])
count += len(instances)
for i in range(0, len(instances)):
instance_name = instances[i]['name']
instance_ip = instances[i]['publicIpAddress']
# print(instance_name)
print(instance_ip)
# 判断实例22端口状态,如果不通就重启服务器
# status = check_ssh_port(instance_ip)
# print('端口状态: '+ str(status))
# if(status == False):
# reboot_instace(client, instance_name)
# 打开实例指定端口
open_ports(client, instances[i]['name'])
print('账号下一共 '+str(count) +' 个实例')
- 相关链接:
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lightsail.html
https://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/Welcome.html