123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #!/bin/env python
- #coding=utf-8
- #edite panwang
- import docker
- import sys
- import requests
- import json
- import queue
- import threading
- from aliyunsdkcore import client
- from aliyunsdkecs.request.v20140526.DescribeNetworkInterfacesRequest import DescribeNetworkInterfacesRequest
- from aliyunsdkcore.request import CommonRequest
- from aliyunsdkslb.request.v20140515.DescribeLoadBalancerAttributeRequest import DescribeLoadBalancerAttributeRequest
- import time
- AccessKey = 'LTAIuPbTPL3LDDKN'
- AccessSecret = 'ORcNedKwWuwVtcq4IRFtUDZgS0b1le'
- RegionId = 'cn-hangzhou'
- version = sys.argv[1]
- slbIDs = ['lb-bp1jtzhp9krunyv3mim2q','lb-bp1mfk1gmd47twfh6bgwv']
- #slbIDs = ['lb-bp136gme0r0n02aew4vjc','lb-bp1mfk1gmd47twfh6bgwv']
- apps = 'piaoquan-gateway'
- repository = 'registry-vpc.cn-hangzhou.aliyuncs.com/stuuudy/{}'.format(apps)
- registry = 'registry-vpc.cn-hangzhou.aliyuncs.com/stuuudy/{}:{}'.format(apps, version)
- clt = client.AcsClient (AccessKey, AccessSecret, RegionId)
- class MyThread (threading.Thread):
- def __init__(self, func):
- threading.Thread.__init__ (self)
- self.func = func
- def run(self):
- self.func ()
- def checkHealth(ipadd):
- while True:
- health_url = 'http://%s:9000/healthcheck' %(ipadd)
- header = {"Content-Type":"application/json"}
- try:
- health_code = requests.get(health_url).status_code
- except Exception as e:
- continue
- if health_code == 200:
- print("httpcode 200,开始挂载流量")
- return False
- #服务更新完之后逐步修改服务器的权重值,直接加载100会出现502。权重值每次增加10,每2s修改一次
- def setInstanceWeightProcess(slb_id, instance_id):
- for i in range(1,6):
- weight = i*20
- setWeight(slb_id,instance_id,weight)
- print("当前权重: ", weight)
- time.sleep(5)
- #设置权重 instance_id :服务器id,weight:权重值
- def setWeight(slb_id,instance_id ,weight):
- BackendServers = [{"ServerId": instance_id, "Weight": weight}]
- request = CommonRequest ()
- request.set_accept_format ('json')
- request.set_domain ('slb.aliyuncs.com')
- request.set_version ('2014-05-15')
- request.set_method ('POST')
- request.set_action_name ('SetBackendServers')
- request.add_query_param ('BackendServers', BackendServers)
- request.add_query_param ('LoadBalancerId', slb_id)
- try:
- response = clt.do_action (request)
- except Exception as e:
- print (e)
- def getInstanceId(slb_id):
- request = DescribeLoadBalancerAttributeRequest()
- request.set_accept_format('json')
- request.set_LoadBalancerId(slb_id)
- response = clt.do_action_with_exception(request)
- return json.loads (response)
- #获取实例IP地址
- def getIpadd(instance_id):
- 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 update(instance_id):
- time.sleep(10)
- global success_count
- ipadd = getIpadd(instance_id)
- print("服务器信息:" + "%s/%s" %(instance_id, ipadd))
- client = docker.DockerClient(base_url='tcp://%s:2375' %(ipadd),timeout=60 )
- try:
- #更新前移除旧的容器
- id = client.containers.get(apps)
- id.remove(force = True)
- except Exception as e:
- print("容器不存在或者无法删除当前容器")
- try:
- #登录镜像仓库
- client.login(username='stuuudys' ,password='Qingqu@2019', registry='registry-vpc.cn-hangzhou.aliyuncs.com')
- #启动一个容器
- client.containers.run(registry, detach = True, cap_add = 'SYS_PTRACE', network_mode = 'host', name = apps,volumes={'/datalog/': {'bind': '/datalog/', 'mode': 'rw'}})
- print("开始健康检查")
- checkHealth(ipadd)
- print("%s :权重修改中......" %(ipadd))
- for slbID in slbIDs:
- setInstanceWeightProcess(slbID, instance_id)
- success_count = success_count + 1
- print("更新进度" + "%s/%s" %(success_count, total))
- except Exception as e:
- print(e)
- sys.exit()
- #容器启动失败立即退出更新
- def pull_image():
- instanceId = q1.get()
- ipaddr = getIpadd(instanceId)
- cd_url = "tcp://{}:2375".format(ipaddr)
- client = docker.DockerClient(base_url=cd_url, timeout=30)
- try:
- client.images.pull(repository, tag=version)
- print(ipaddr, "pull images success ")
- return True
- except Exception as e:
- print(e, "images pull fail")
- return False
- if __name__ == '__main__':
- #更新完成计数
- success_count = 0
- threads = []
- res = getInstanceId (slbIDs[0])
- #slb下服务器总数
- total = len(res["BackendServers"]["BackendServer"])
- InstanceIDs = []
- q1 = queue.Queue()
- if res["BackendServers"]["BackendServer"]:
- for i in range ((len (res["BackendServers"]["BackendServer"]))):
- InstanceID = res["BackendServers"]["BackendServer"][i]["ServerId"]
- InstanceIDs.append(InstanceID)
- q1.put(InstanceID)
- print(InstanceIDs)
- #多线程预先pull images
- for i in range (len(InstanceIDs)):
- thread = MyThread (pull_image)
- thread.start ()
- threads.append(thread)
- for thread in threads:
- thread.join ()
- #单线程更新
- for instanceID in InstanceIDs:
- for slbID in slbIDs:
- setWeight(slbID,instanceID,0)
- update(instanceID)
|