switch_lb.py
8.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
修改腾讯云七层负载均衡器的权重
@see doc: https://cloud.tencent.com/document/product/214/8978
"""
from qcloud.qcloud_api import QcloudApi
from yansible.inventory_reader import InventoryReader
import time, sys, os
"""
作用:切换负载均衡器的流量
依赖: inventory 文件
demo:
lbswitch = LBSwitch(secretId="AKID6dwppIHPO5qPv5GK", secretKey="ACJkH9mg0DBsQaW",
az1_lb_id="lb-dyh6eucn", az2_lb_id="lb-capto5b5", az3_lb_id="lb-capto5b5", az1_innerlb_id="lb-c26tgo5r")
# 全部流量切换到AZ1
ret = lbswitch.all_to_az1()
# 全部流量切换到AZ2
ret = lbswitch.all_to_az2()
"""
class LBSwitch:
def __init__(self, secretId, secretKey, az1_lb_id, az2_lb_id, az3_lb_id, az1_innerlb_id):
self.SecretId = secretId
self.SecretKey = secretKey
self.az1_lb_id = az1_lb_id
self.az2_lb_id = az2_lb_id
self.az3_lb_id = az3_lb_id
self.az1_innerlb_id = az1_innerlb_id
def all_to_az1(self):
"""
所有流量切换到az1
:return:
"""
inventory_reader = InventoryReader()
az1_nginxs = inventory_reader.get_inventory_ifo("az1", 'java-nginx')
print "get all java nginx: %s for az: %s" % (az1_nginxs, "az1")
az1_nginx_weight = {}
for az1_nginx in az1_nginxs:
az1_nginx_weight[az1_nginx] = 10
# az2 公网流量切换到az1
ret_az2 = self.modify_alb_weight(lb_id=self.az2_lb_id, domain="*.yoho.cn", ip_weight_dict=az1_nginx_weight)
print("switch all incoming request from az2 to az1 result: %s" % ret_az2)
# az1 公网流量、内部流量切换到az1
ret_az1 = self.modify_clb_weight(lb_id=self.az1_lb_id, ip_weight_dict=az1_nginx_weight)
ret_az1_inner = self.modify_alb_weight(lb_id=self.az1_innerlb_id, domain="*.yoho.yohoops.org",
ip_weight_dict=az1_nginx_weight)
print("switch all incoming request from az1 to az1 result: %s inner result: %s" % (ret_az1, ret_az1_inner))
return ret_az1 and ret_az1_inner and ret_az2
def all_to_az2(self):
"""
所有流量切换到AZ2
:return:
"""
inventory_reader = InventoryReader()
az2_nginx = inventory_reader.get_inventory_ifo("az2", 'java-nginx')
az2_nginx_weight = {}
for nginx in az2_nginx:
az2_nginx_weight[nginx] = 10
# az2 公网流量切换到az2
ret_az2 = self.modify_alb_weight(lb_id=self.az2_lb_id, domain="*.yoho.cn", ip_weight_dict=az2_nginx_weight)
print("switch all incoming request from az2 to az2 result: %s" % ret_az2)
# az1 公网流量、内部流量切换到az2
ret_az1 = self.modify_clb_weight(lb_id=self.az1_lb_id, ip_weight_dict=az2_nginx_weight)
ret_az1_inner = self.modify_alb_weight(lb_id=self.az1_innerlb_id, domain="*.yoho.yohoops.org", ip_weight_dict=az2_nginx_weight)
print("switch all incoming request from az1 to az2 result: %s inner lb:%s" % (ret_az1, ret_az1_inner))
return ret_az1 and ret_az2 and ret_az1_inner
def modify_clb_weight(self, lb_id, ip_weight_dict):
"""
修改传统负载均衡器的权重
@:param lb_id 负载均衡器的ID
@:param ip_weight_dict 需要设置权重的后端IP-权重字典, 格式为 {'ip': weight }
:return: True: 修改成功
"""
# 1.获取传统型负载均衡器的后端列表
# see details at: https://cloud.tencent.com/document/api/214/1259
instance_weight = {} # instance_id --> weight
api = QcloudApi(secretId=self.SecretId, secretKey=self.SecretKey)
lb_info = api.do_query(params={'Action': 'DescribeLoadBalancerBackends', 'loadBalancerId': lb_id}, req_url=QcloudApi.URLS_lb)
for backend in lb_info['backendSet']:
if backend['lanIp'] in ip_weight_dict.keys():
# setup the instance_id --> weight
instance_weight[backend['unInstanceId']] = ip_weight_dict[backend['lanIp']]
else:
instance_weight[backend['unInstanceId']] = 0
# 2.检查至少有一个weight不为0
if len(filter(lambda w: w != 0, instance_weight.values())) == 0:
sys.exit(" instance weight: %s is all zero. please check again!" % instance_weight)
# 3.修改权重: https://cloud.tencent.com/document/api/214/1264
modify_params = {'Action': 'ModifyLoadBalancerBackends', 'loadBalancerId': lb_id}
i = 1
for ins_id, ins_weight in instance_weight.iteritems():
modify_params['backends.%i.instanceId' % i] = ins_id
modify_params['backends.%i.weight' % i] = ins_weight
i = i + 1
api = QcloudApi(secretId=self.SecretId, secretKey=self.SecretKey)
rsp = api.do_query(params=modify_params, req_url=QcloudApi.URLS_lb)
return rsp['code'] == 0
def modify_alb_weight(self, lb_id, domain, ip_weight_dict):
"""
修改应用型负载均衡器上服务器的权重
@:param lb_id: 应用型负载均衡器ID
@:param domain: 应用型负载均衡器的domain
@:param ip_weight_dict: 需要设置权重的dict, 格式为 {'ip': weight }
@return list
"""
# 查询ALB的监听器信息
# see qcloud api details at: https://cloud.tencent.com/document/product/214/8987
instance_weight = {} # instance_id --> weight
instance_port = {} # instance_id --> port
listener_ids = {} # all linsters
api = QcloudApi(secretId=self.SecretId, secretKey=self.SecretKey)
lb_info = api.do_query(params={'Action': 'DescribeForwardLBBackends', 'loadBalancerId': lb_id}, req_url=QcloudApi.URLS_lb)
# listener : [http , https]
for listener in lb_info['data']:
for rule in listener['rules']:
if rule['domain'] == domain: # domain match
listener_ids[listener['listenerId']] = listener['protocolType']
for backend in rule['backends']:
instance_port[backend['unInstanceId']] = backend['port']
if backend['lanIp'] in ip_weight_dict.keys():
# setup the instance_id --> weight
instance_weight[backend['unInstanceId']] = ip_weight_dict[backend['lanIp']]
else:
instance_weight[backend['unInstanceId']] = 0
# 检查至少有一个weight
if len(filter(lambda w: w != 0, instance_weight.values())) == 0:
sys.exit(" instance weight: %s is all zero. please check again!" % instance_weight)
# 修改七层负载均衡器的权重
# see details at: https://cloud.tencent.com/document/product/214/8978
return_code = []
for lis_id in listener_ids.keys():
params = {'Action': 'ModifyForwardSeventhBackends', 'loadBalancerId': lb_id,
'listenerId': lis_id, 'domain': domain}
i = 1
for ins_id, ins_weight in instance_weight.iteritems():
params['backends.%i.instanceId' % i] = ins_id
params['backends.%i.weight' % i] = ins_weight
params['backends.%i.port' % i] = instance_port[ins_id]
i = i + 1
rsp = api.do_query(params, req_url=QcloudApi.URLS_lb)
print(u"response code: %s . success change domain: %s for listener : %s. wait for 10s" % (rsp['code'], domain, listener_ids[lis_id]))
return_code.append(rsp['code'])
time.sleep(10)
return return_code.count(0) == len(return_code)