|  | @@ -0,0 +1,180 @@
 | 
	
		
			
				|  |  | +#!/bin/env python
 | 
	
		
			
				|  |  | +#coding=utf-8
 | 
	
		
			
				|  |  | +#edite  panwang
 | 
	
		
			
				|  |  | +#旧版发布脚本 添加到git
 | 
	
		
			
				|  |  | +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-bp1mfk1gmd47twfh6bgwv", "lb-bp1jtzhp9krunyv3mim2q", "lb-bp1jijiyb925dk26ofm8h","lb-bp19a14ptmw1b7nwejvej","lb-bp15xf7asp620927z3lgr","lb-bp1i24x4sdfjbbuo8n1be","lb-bp153yk5n4szt6q8wzloy","lb-bp1s5c004pwnfu1beebye"]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +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)
 | 
	
		
			
				|  |  | +
 |