123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- # #!/usr/bin/env python
- # #coding=utf-8
- import json
- import logging
- import time
- import requests
- import sys
- from aliyunsdkcore import client
- from aliyunsdkcore.client import AcsClient
- from aliyunsdkcore.acs_exception.exceptions import ClientException
- from aliyunsdkcore.acs_exception.exceptions import ServerException
- from aliyunsdkecs.request.v20140526.CreateInstanceRequest import CreateInstanceRequest
- from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
- from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
- from aliyunsdkecs.request.v20140526.RunInstancesRequest import RunInstancesRequest
- from aliyunsdkecs.request.v20140526.DescribeNetworkInterfacesRequest import DescribeNetworkInterfacesRequest
- from aliyunsdkslb.request.v20140515.AddBackendServersRequest import AddBackendServersRequest
- from aliyunsdkecs.request.v20140526.RunCommandRequest import RunCommandRequest
- logging.basicConfig(level=logging.INFO,
- format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
- datefmt='%a, %d %b %Y %H:%M:%S')
- # ##### 购买服务器权限
- # access key Id
- ak_id = "LTAI4GBWbFvvXoXsSVBe1o9f"
- # access key secret
- ak_secret = "kRAikWitb4kDxaAyBqNrmLmllMEDO3"
- # 设置地域
- region_id = "cn-hangzhou"
- clt = client.AcsClient(ak_id, ak_secret, region_id)
- # 获取批量创建ECS实例的数量, 取值范围:1-100, 默认值:1
- amount = int(sys.argv[1])
- # 使用的镜像信息
- image_id = "m-bp13xpsku1wo7qzic7zl"
- # 设置实例规格
- instance_type = "ecs.ic5.large"
- # 选择的交换机
- vswitch_id = "vsw-bp19lpjwtc6j0p0m9mdc2"
- # 当前VPC类型的安全组
- security_group_id = "sg-bp1irhrkr4vfj272hk4y"
- # 硬盘的大小,单位:G
- disk_size = "200"
- # 服务器命名
- instance_name = "ESS-rov-server-[1,2]"
- # 服务器所在区域
- zone_id = "cn-hangzhou-h"
- # 磁盘类型:云盘
- disk_category = "cloud_efficiency"
- # 密钥
- key_pair_name = "stuuudy"
- # 负载均衡ID
- slb_id_2 = "lb-bp1werfophtsjzfr76njm"
- # ##### 修改负载均衡权限
- AccessKey = 'LTAIuPbTPL3LDDKN'
- AccessSecret = 'ORcNedKwWuwVtcq4IRFtUDZgS0b1le'
- RegionId = 'cn-hangzhou'
- client = AcsClient(AccessKey, AccessSecret, RegionId)
- def build_request():
- """购买服务器参数配置"""
- request = RunInstancesRequest()
- request.set_ImageId(image_id)
- request.set_VSwitchId(vswitch_id)
- request.set_SecurityGroupId(security_group_id)
- request.set_ZoneId(zone_id)
- request.set_InstanceType(instance_type)
- # request.set_UserData(init_data)
- request.set_InstanceName(instance_name)
- request.set_SystemDiskSize(disk_size)
- request.set_SystemDiskCategory(disk_category)
- request.set_KeyPairName(key_pair_name)
- request.set_Tags([
- {
- "Key": "app",
- "Value": "rov-server"
- }
- ])
- return request
- def _send_request(request):
- """发送API请求"""
- request.set_accept_format('json')
- try:
- response_str = clt.do_action_with_exception(request)
- logging.info(response_str)
- response_detail = json.loads(response_str)
- return response_detail
- except Exception as e:
- logging.error(e)
- def check_instance_running(instance_ids):
- """检查服务器运行状态"""
- request = DescribeInstancesRequest()
- request.set_InstanceIds(json.dumps(instance_ids))
- response = _send_request(request)
- if response.get('Code') is None:
- instances_list = response.get('Instances').get('Instance')
- running_count = 0
- for instance_detail in instances_list:
- if instance_detail.get('Status') == "Running":
- running_count += 1
- return running_count
- def runCommand(instance_ids):
- """批量执行shell脚本:启动服务"""
- request = RunCommandRequest()
- request.set_accept_format('json')
- request.set_Type("RunShellScript")
- request.set_CommandContent("sh /home/sh/rov-server-start.sh")
- request.set_InstanceIds(instance_ids)
- response = clt.do_action_with_exception(request)
- logging.info(response)
- def healthCheck(instance_id):
- """服务健康检查 & 服务器挂载到负载均衡"""
- ipaddr = getIpaddr(instance_id)
- while True:
- health_url = 'http://%s:5001/healthcheck' %(ipaddr)
- try:
- http_code = requests.get(health_url).status_code
- except:
- logging.info("images is downloading")
- http_code = 0
- if http_code == 200:
- break
- else:
- time.sleep(20)
- # 服务预热60s, 服务刚启动时CPU很高
- time.sleep(60)
- # 挂载到负载均衡
- addBackendServers(slb_id_2, instance_id)
- def addBackendServers(slb_id, instance_id):
- """服务器挂载到负载均衡"""
- request = AddBackendServersRequest()
- request.set_accept_format('json')
- ipaddr = getIpaddr(instance_id)
- request.set_LoadBalancerId(slb_id)
- request.set_BackendServers([{"ServerId": instance_id, "Weight": "100", "Type": "ecs", "ServerIp": ipaddr}])
- response = client.do_action_with_exception(request)
- logging.info(response)
- def getIpaddr(instance_id):
- """根据 instance_id 获取实例IP地址"""
- request = DescribeNetworkInterfacesRequest()
- request.set_accept_format('json')
- request.set_InstanceId(instance_id)
- response = clt.do_action_with_exception(request)
- request_content = json.loads(response)
- ipaddr = request_content['NetworkInterfaceSets']['NetworkInterfaceSet'][0]['PrivateIpAddress']
- return ipaddr
- def _execute_request(request):
- response = _send_request(request)
- if response.get('Code') is None:
- instance_ids = response.get('InstanceIdSets').get('InstanceIdSet')
- running_amount = 0
- while running_amount < amount:
- time.sleep(10)
- running_amount = check_instance_running(instance_ids)
- logging.info(f"{instance_ids} is running")
- time.sleep(60)
- runCommand(instance_ids)
- for instance_id in instance_ids:
- healthCheck(instance_id)
- def create_multiple_instances():
- """创建ECS实例并启动"""
- request = build_request()
- request.set_Amount(amount)
- _execute_request(request)
- if __name__ == '__main__':
- logging.info("Start Create Instances")
- # 创建ECS实例并启动
- create_multiple_instances()
|