ess_instance_rov_server_new.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. # #!/usr/bin/env python
  2. # #coding=utf-8
  3. import json
  4. import logging
  5. import time
  6. import requests
  7. import sys
  8. from aliyunsdkcore import client
  9. from aliyunsdkcore.client import AcsClient
  10. from aliyunsdkcore.acs_exception.exceptions import ClientException
  11. from aliyunsdkcore.acs_exception.exceptions import ServerException
  12. from aliyunsdkecs.request.v20140526.CreateInstanceRequest import CreateInstanceRequest
  13. from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
  14. from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
  15. from aliyunsdkecs.request.v20140526.RunInstancesRequest import RunInstancesRequest
  16. from aliyunsdkecs.request.v20140526.DescribeNetworkInterfacesRequest import DescribeNetworkInterfacesRequest
  17. from aliyunsdkslb.request.v20140515.AddBackendServersRequest import AddBackendServersRequest
  18. from aliyunsdkecs.request.v20140526.RunCommandRequest import RunCommandRequest
  19. from aliyunsdkcore.request import CommonRequest
  20. from aliyunsdkecs.request.v20140526.SendFileRequest import SendFileRequest
  21. logging.basicConfig(level=logging.INFO,
  22. format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
  23. datefmt='%a, %d %b %Y %H:%M:%S')
  24. # ##### 购买服务器权限
  25. # access key Id
  26. ak_id = "LTAI4GBWbFvvXoXsSVBe1o9f"
  27. # access key secret
  28. ak_secret = "kRAikWitb4kDxaAyBqNrmLmllMEDO3"
  29. # 设置地域
  30. region_id = "cn-hangzhou"
  31. clt = client.AcsClient(ak_id, ak_secret, region_id)
  32. # 获取批量创建ECS实例的数量, 取值范围:1-100, 默认值:1
  33. amount = int(sys.argv[1])
  34. # 使用的镜像信息
  35. image_id = "m-bp1e5jx8eqhq22l91xw7"
  36. # 设置实例规格
  37. instance_type = "ecs.ic5.large"
  38. # 选择的交换机
  39. vswitch_id = "vsw-bp19lpjwtc6j0p0m9mdc2"
  40. # 当前VPC类型的安全组
  41. security_group_id = "sg-bp1irhrkr4vfj272hk4y"
  42. # 硬盘的大小,单位:G
  43. disk_size = "200"
  44. # 服务器命名
  45. instance_name = "ESS-rov-server-[1,2]"
  46. # 服务器所在区域
  47. zone_id = "cn-hangzhou-h"
  48. # 磁盘类型:云盘
  49. disk_category = "cloud_efficiency"
  50. # 密钥
  51. key_pair_name = "stuuudy"
  52. # 负载均衡ID
  53. slb_id_2 = "lb-bp1werfophtsjzfr76njm"
  54. # ##### 修改负载均衡权限
  55. AccessKey = 'LTAIuPbTPL3LDDKN'
  56. AccessSecret = 'ORcNedKwWuwVtcq4IRFtUDZgS0b1le'
  57. RegionId = 'cn-hangzhou'
  58. client = AcsClient(AccessKey, AccessSecret, RegionId)
  59. # server_start
  60. start_target_dir = '/home/sh'
  61. start_name = 'rov_server_start_new.sh'
  62. start_content = """#!/bin/bash
  63. docker login --username=stuuudys --password=Qingqu@2019 registry.piaoquantv.com
  64. docker run -d -it --network=host --name=rov-server registry.piaoquantv.com/piaoquan/rov-server:latest
  65. """
  66. def build_request():
  67. """购买服务器参数配置"""
  68. request = RunInstancesRequest()
  69. request.set_ImageId(image_id)
  70. request.set_VSwitchId(vswitch_id)
  71. request.set_SecurityGroupId(security_group_id)
  72. request.set_ZoneId(zone_id)
  73. request.set_InstanceType(instance_type)
  74. # request.set_UserData(init_data)
  75. request.set_InstanceName(instance_name)
  76. request.set_SystemDiskSize(disk_size)
  77. request.set_SystemDiskCategory(disk_category)
  78. request.set_KeyPairName(key_pair_name)
  79. request.set_Tags([
  80. {
  81. "Key": "ecs",
  82. "Value": "rov-server.prod"
  83. }
  84. ])
  85. return request
  86. def _send_request(request):
  87. """发送API请求"""
  88. request.set_accept_format('json')
  89. try:
  90. response_str = clt.do_action_with_exception(request)
  91. logging.info(response_str)
  92. response_detail = json.loads(response_str)
  93. return response_detail
  94. except Exception as e:
  95. logging.error(e)
  96. def check_instance_running(instance_ids):
  97. """检查服务器运行状态"""
  98. request = DescribeInstancesRequest()
  99. request.set_InstanceIds(json.dumps(instance_ids))
  100. response = _send_request(request)
  101. if response.get('Code') is None:
  102. instances_list = response.get('Instances').get('Instance')
  103. running_count = 0
  104. for instance_detail in instances_list:
  105. if instance_detail.get('Status') == "Running":
  106. running_count += 1
  107. return running_count
  108. def runCommand(instance_ids):
  109. """批量执行shell脚本:启动服务"""
  110. request = RunCommandRequest()
  111. request.set_accept_format('json')
  112. request.set_Type("RunShellScript")
  113. request.set_CommandContent("sh /home/sh/rov_server_start_new.sh")
  114. request.set_InstanceIds(instance_ids)
  115. response = clt.do_action_with_exception(request)
  116. logging.info(response)
  117. def healthCheck(instance_id):
  118. """服务健康检查 & 服务器挂载到负载均衡"""
  119. ipaddr = getIpaddr(instance_id)
  120. while True:
  121. health_url = 'http://%s:5001/healthcheck' %(ipaddr)
  122. try:
  123. http_code = requests.get(health_url).status_code
  124. except:
  125. logging.info("images is downloading")
  126. http_code = 0
  127. if http_code == 200:
  128. break
  129. else:
  130. time.sleep(20)
  131. # 服务预热60s, 服务刚启动时CPU很高
  132. time.sleep(60)
  133. # 挂载到负载均衡
  134. addBackendServers(slb_id_2, instance_id)
  135. def setWeight(slb_id, instance_id, weight):
  136. """
  137. 设置slb权重
  138. :param slb_id: slb_id
  139. :param instance_id: 服务器id
  140. :param weight: 权重值
  141. :return: None
  142. """
  143. BackendServers = [{"ServerId": instance_id, "Weight": weight}]
  144. request = CommonRequest()
  145. request.set_accept_format('json')
  146. request.set_domain('slb.aliyuncs.com')
  147. request.set_version('2014-05-15')
  148. request.set_method('POST')
  149. request.set_action_name('SetBackendServers')
  150. request.add_query_param('BackendServers', BackendServers)
  151. request.add_query_param('LoadBalancerId', slb_id)
  152. try:
  153. response = client.do_action_with_exception(request)
  154. except Exception as e:
  155. logging.error(e)
  156. def addBackendServers(slb_id, instance_id):
  157. """服务器挂载到负载均衡"""
  158. request = AddBackendServersRequest()
  159. request.set_accept_format('json')
  160. ipaddr = getIpaddr(instance_id)
  161. request.set_LoadBalancerId(slb_id)
  162. request.set_BackendServers([{"ServerId": instance_id, "Weight": "0", "Type": "ecs", "ServerIp": ipaddr}])
  163. response = client.do_action_with_exception(request)
  164. logging.info(response)
  165. for i in range(1, 6):
  166. time.sleep(5)
  167. weight = i * 20
  168. logging.info(f"instance_id: {instance_id}, weight: {weight}")
  169. setWeight(slb_id=slb_id, instance_id=instance_id, weight=weight)
  170. def getIpaddr(instance_id):
  171. """根据 instance_id 获取实例IP地址"""
  172. request = DescribeNetworkInterfacesRequest()
  173. request.set_accept_format('json')
  174. request.set_InstanceId(instance_id)
  175. response = clt.do_action_with_exception(request)
  176. request_content = json.loads(response)
  177. ipaddr = request_content['NetworkInterfaceSets']['NetworkInterfaceSet'][0]['PrivateIpAddress']
  178. return ipaddr
  179. def send_file_to_ecs(instance_id_list, target_dir, name, content):
  180. request = SendFileRequest()
  181. request.set_Content(content)
  182. request.set_TargetDir(target_dir)
  183. request.set_Name(name)
  184. request.set_Overwrite(True)
  185. request.set_InstanceIds(instance_id_list)
  186. response = clt.do_action_with_exception(request)
  187. def _execute_request(request):
  188. response = _send_request(request)
  189. if response.get('Code') is None:
  190. instance_ids = response.get('InstanceIdSets').get('InstanceIdSet')
  191. running_amount = 0
  192. while running_amount < amount:
  193. time.sleep(10)
  194. running_amount = check_instance_running(instance_ids)
  195. logging.info(f"{instance_ids} is running")
  196. time.sleep(60)
  197. send_file_to_ecs(instance_id_list=instance_ids,
  198. target_dir=start_target_dir, name=start_name, content=start_content)
  199. runCommand(instance_ids)
  200. for instance_id in instance_ids:
  201. healthCheck(instance_id)
  202. def create_multiple_instances():
  203. """创建ECS实例并启动"""
  204. request = build_request()
  205. request.set_Amount(amount)
  206. _execute_request(request)
  207. if __name__ == '__main__':
  208. logging.info("Start Create Instances")
  209. # 创建ECS实例并启动
  210. create_multiple_instances()