alb_gateway_update_one.py 5.5 KB

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