贡献web根据负载弹性添加到loadblance的python脚本一份,适用于aws(亚马逊)书写并调试、优化差不多2天时间,写代码真TM累。此脚本需要在每台web上安装snmp协议,大家做运维的估计在服务器上都安装了,cacti的时候会用到。
#!/usr/bin/env python
#coding=utf-8
import boto
from boto.ec2.elb import ELBConnection
import commands
import random
import logging
import time
def show_elb_instance(name):
"""
show elb all instance
"""
loadlist = str(conn.get_all_load_balancers()).strip('[]').replace('LoadBalancer', '').replace(',', '').split(':')
loadlist = loadlist[1:]
for line in loadlist:
if line.strip() == name:
load_balancer = conn.get_all_load_balancers(load_balancer_names=[name])[0]
single_load_instances = [instance for instance in load_balancer.instances]
return single_load_instances
def show_elb_running_instance(name):
"""
show elb running instance
"""
single_load_instances = show_elb_instance(name)
reservations = ec2_connection.get_all_instances([i.id for i in single_load_instances])
instance_running = [r.tags['Name'] for r in reservations for r in r.instances]
return instance_running
def show_all_instance():
"""
show all instance
"""
ec2_reservations = ec2_connection.get_all_instances()
all_instance = []
for instance in ec2_reservations:
for inst in instance.instances:
all_instance.append(inst)
return all_instance
def show_machine_load(single_load_instances):
sum_minute_load = 0
sum_fiveminute_load = 0
numlist = []
reservations = ec2_connection.get_all_instances([i.id for i in single_load_instances])
instance_addresses = [r.public_dns_name for r in reservations for r in r.instances]
for ip in instance_addresses:
single_machine_load = commands.getoutput(
"snmpwalk -v 2c %s -c public .1.3.6.1.4.1.2021.10.1.3.1|awk '{print $4}'" % ip)
five_minute_load = commands.getoutput(
"snmpwalk -v 2c %s -c public .1.3.6.1.4.1.2021.10.1.3.2|awk '{print $4}'" % ip)
numlist.append(ip)
sum_minute_load += float(single_machine_load)
sum_fiveminute_load += float(five_minute_load)
return sum_minute_load / len(numlist), sum_fiveminute_load / len(numlist)
def add_machine_instance(key, pre_start_instancelist):
if len(pre_start_instancelist) == 1:
start_instance = pre_start_instancelist[0]
else:
start_instance = pre_start_instancelist[random.randint(0, len(pre_start_instancelist) - 1)]
print start_instance.tags['Name']
print "Pre start instance status is %s" % start_instance.state
print "Start instance id is %s:" % start_instance.id
start_instance.start()
print start_instance.state
i = 0
while True:
if str(start_instance.state) == 'running':
conn.register_instances(key, start_instance.id.split())
print "New machine has been add !"
break
else:
i += 1
time.sleep(5)
start_instance.update()
print start_instance.state
print str(start_instance.state)
if i > 30:
# logging
break
def del_machine_instance(key, pre_stop_instancelist):
for num in pre_stop_instancelist:
print num.tags['Name']
print "Pre stop instance status is %s" % num.state
print "Stop instance id is %s:" % num.id
num.stop()
k = 0
while True:
if str(num.state) == 'stopped':
conn.deregister_instances(key, num.id.split())
print "New machine has been delete !"
break
else:
k += 1
time.sleep(5)
num.update()
print num.state
if k > 30:
#logging
break
def main():
pre_start_instancelist = []
pre_stop_instancelist = []
running_instance_id = []
keeps_instance_id = []
all_instance = show_all_instance()
for key, value in elastic_cloud_configs.items():
single_elb_instance = show_elb_instance(key)
for inst2 in single_elb_instance:
running_instance_id.append(inst2.id)
single_load_instances = show_elb_instance(key)
avg_minute_load, avg_fiveminute_load = show_machine_load(single_load_instances)
for inst in all_instance:
if str(inst.tags['Name']).startswith(value['filters']) and str(inst.state) == 'stopped':
pre_start_instancelist.append(inst)
for n in value['keeps']:
if str(inst.tags['Name']) == n:
keeps_instance_id.append(inst.id)
pre_stop_instanceidlist = [i for i in running_instance_id if
i not in keeps_instance_id] #stop instance which not in keeps instance
for line in pre_stop_instanceidlist:
if line == inst.id:
pre_stop_instancelist.append(inst)
print avg_minute_load, avg_fiveminute_load
if avg_minute_load > float(value['maxload']) * 2 or avg_fiveminute_load > float(value['maxload']):
add_machine_instance(key, pre_start_instancelist)
instance_running = show_elb_running_instance(key)
print instance_running
if avg_minute_load < float(value['minload']):
del_machine_instance(key, pre_stop_instancelist)
instance_running = show_elb_running_instance(key)
print instance_running