gateway_update.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #!/bin/env python
  2. # coding=utf-8
  3. # edite panwang
  4. import docker
  5. import sys
  6. import requests
  7. import json
  8. import queue
  9. import threading
  10. import time
  11. from aliyunsdkcore import client
  12. from aliyunsdkecs.request.v20140526.DescribeNetworkInterfacesRequest import DescribeNetworkInterfacesRequest
  13. import gateway_config
  14. import utils
  15. # 从配置文件中获取应用程序名称和容器仓库地址
  16. apps = gateway_config.apps
  17. repository = gateway_config.repository
  18. registry = gateway_config.registry
  19. version = sys.argv[1] # 从命令行参数获取版本号
  20. class MyThread(threading.Thread):
  21. def __init__(self, func):
  22. threading.Thread.__init__(self)
  23. self.func = func
  24. def run(self):
  25. self.func()
  26. def checkHealth(ipadd):
  27. while True:
  28. health_url = 'http://%s:9000/healthcheck' % (ipadd)
  29. header = {"Content-Type": "application/json"}
  30. try:
  31. health_code = requests.get(health_url).status_code
  32. except Exception as e:
  33. continue # 如果请求失败,继续重试
  34. if health_code == 200:
  35. print("httpcode 200,开始挂载流量")
  36. return False # 健康检查通过,返回
  37. def update(instance_id):
  38. time.sleep(10) # 等待10秒钟
  39. global success_count
  40. ipadd = utils.get_ip_address(ecs_client, instance_id) # 使用 utils 获取实例的 IP 地址
  41. print("服务器信息:" + "%s/%s" % (instance_id, ipadd))
  42. client = docker.DockerClient(base_url='tcp://%s:2375' % (ipadd), timeout=60)
  43. # 尝试删除旧的容器
  44. try:
  45. id = client.containers.get(apps)
  46. id.remove(force=True)
  47. except Exception as e:
  48. print("容器不存在或者无法删除当前容器")
  49. # 尝试登录并启动新的容器
  50. try:
  51. # 使用 gateway_config 中的 Docker 登录配置
  52. docker_config = gateway_config.docker_config
  53. client.login(username=docker_config['username'], password=docker_config['password'],
  54. registry=docker_config['registry'])
  55. client.containers.run(registry.format(apps, version), detach=True, cap_add='SYS_PTRACE', network_mode='host', name=apps,
  56. volumes={'/datalog/': {'bind': '/datalog/', 'mode': 'rw'}})
  57. print("开始健康检查")
  58. checkHealth(ipadd)
  59. print("%s :权重修改中......" % (ipadd))
  60. weight_list = [(10, 5), (20, 5), (40, 5), (60, 5), (80, 5), (100, 5)]
  61. for server_group_id in gateway_config.server_group_id_list:
  62. utils.set_instance_weight_process_with_alb(alb_client, [server_group_id], [instance_id], weight_list)
  63. success_count += 1
  64. print("更新进度" + "%s/%s" % (success_count, total))
  65. except Exception as e:
  66. print(e)
  67. sys.exit()
  68. def pull_image():
  69. """从镜像仓库中拉取指定版本的镜像"""
  70. instanceId = q1.get()
  71. ipaddr = utils.get_ip_address(ecs_client, instanceId)
  72. cd_url = "tcp://{}:2375".format(ipaddr)
  73. client = docker.DockerClient(base_url=cd_url, timeout=30)
  74. try:
  75. client.images.pull(repository.format(apps), tag=version) #
  76. print(ipaddr, "pull images success ")
  77. return True
  78. except Exception as e:
  79. print(e, "images pull fail")
  80. return False
  81. if __name__ == '__main__':
  82. # 初始化 ECS 客户端
  83. ecs_client = utils.connect_client(access_key_id=gateway_config.ecs_client_params['access_key_id'],
  84. access_key_secret=gateway_config.ecs_client_params['access_key_secret'],
  85. region_id=gateway_config.ecs_client_params['region_id'])
  86. # 初始化 ALB 客户端
  87. alb_client = utils.connect_alb_client(gateway_config.alb_client_params['access_key_id'],
  88. gateway_config.alb_client_params['access_key_secret'],
  89. endpoint=gateway_config.alb_client_params['endpoint']
  90. )
  91. success_count = 0
  92. threads = []
  93. total = 0
  94. InstanceIDs = []
  95. q1 = queue.Queue()
  96. # 获取 ALB 下服务器组的实例 ID
  97. res = utils.get_instance_ids(alb_client=alb_client, server_group_id=gateway_config.server_group_id_list[0])
  98. total += len(res)
  99. InstanceIDs.extend(res)
  100. print(InstanceIDs)
  101. # 将实例 ID 放入队列中
  102. for instance_id in InstanceIDs:
  103. q1.put(instance_id)
  104. # 多线程预先拉取镜像
  105. for i in range(len(InstanceIDs)):
  106. thread = MyThread(pull_image)
  107. thread.start()
  108. threads.append(thread)
  109. for thread in threads:
  110. thread.join()
  111. # 更新每个实例
  112. for instanceID in InstanceIDs:
  113. for server_group_id in gateway_config.server_group_id_list:
  114. utils.set_instance_weight_process_with_alb(alb_client, [server_group_id], [instanceID],
  115. [(0, 20)]) # 设置初始权重为0
  116. update(instanceID)