def add(name, new_lbinfos): """ 增加 lb. """ # 检查集群是否存在. checkdict = { "name": name, } if not funcs.check(checkdict, check_exist=True): logger.error("No cluster:%s" % name) return False # 获取新增 lb. new_lbs = [i["hostname"] for i in new_lbinfos] if len(new_lbs) != len(set(new_lbs)): logger.error("Lb duplicates") return False # 检查新增 lb 是否已经存在. checkdict = {"lbs": new_lbs} if not funcs.check(checkdict, check_exist=False): logger.error("Some lbs exist") return False # 对所有 lb 安装 lvs fullnat. ret = funcs.lb_multi(new_lbs) fails = [i for i in ret if not i["result"]] if fails != []: message = "Some lbs install failed:%s" % \ ",".join(fails) logger.error(message) return False message = "All lbs install success:%s" % \ ",".join(new_lbs) logger.info(message) # 获取已有集群信息. key = "cluster:%s" % name _type = client.hget(key, "type") old_lbinfos = eval(client.hget(key, "lbinfos")) device = client.hget(key, "device") # 获取新的 lbinfos. lbinfos = copy.deepcopy(old_lbinfos) lbinfos.extend(new_lbinfos) del old_lbinfos # 配置 lb. for lbinfo in new_lbinfos: lb = lbinfo["hostname"] internalip = lbinfo["internalip"] internalnetmask = lbinfo["internalnetmask"] internalgateway = lbinfo["internalgateway"] # 如果 _type 是 extra, 需要公网 IP; # 如果 _type 是 internal, 不需要公网 IP. extraip = lbinfo.get("extraip", None) extranetmask = lbinfo.get("extranetmask", None) extragateway = lbinfo.get("extragateway", None) # 配置 IP. ret = funcs.ip(lb, _type, device, internalip, internalnetmask, internalgateway, extraip, extranetmask, extragateway) if not ret: return False # 配置 lip. _lips = lips.get(internalip, internalnetmask) ret = funcs.lips(lb, internalip, _lips) if not ret: logger.error("Cfg lb lips failed:%s" % lb) return False logger.info("Cfg lb lips success:%s" % lb) # 保存集群信息. client.hset(key, "lbinfos", lbinfos) logger.info("Lbs added:%s" % ",".join(new_lbs)) return True
def add(name, new_lbinfos): """ 增加 lb. """ # 检查集群是否存在. checkdict = { "name": name, } if not funcs.check(checkdict, check_exist=True): logger.error("No cluster:%s" % name) return False # 获取新增 lb. new_lbs = [i["hostname"] for i in new_lbinfos] if len(new_lbs) != len(set(new_lbs)): logger.error("Lb duplicates") return False # 检查新增 lb 是否已经存在. checkdict = { "lbs": new_lbs } if not funcs.check(checkdict, check_exist=False): logger.error("Some lbs exist") return False # 对所有 lb 安装 lvs fullnat. ret = funcs.lb_multi(new_lbs) fails = [ i for i in ret if not i["result"]] if fails != []: message = "Some lbs install failed:%s" % \ ",".join(fails) logger.error(message) return False message = "All lbs install success:%s" % \ ",".join(new_lbs) logger.info(message) # 获取已有集群信息. key = "cluster:%s" % name _type = client.hget(key, "type") old_lbinfos = eval(client.hget(key, "lbinfos")) device = client.hget(key, "device") # 获取新的 lbinfos. lbinfos = copy.deepcopy(old_lbinfos) lbinfos.extend(new_lbinfos) del old_lbinfos # 配置 lb. for lbinfo in new_lbinfos: lb = lbinfo["hostname"] internalip = lbinfo["internalip"] internalnetmask = lbinfo["internalnetmask"] internalgateway = lbinfo["internalgateway"] # 如果 _type 是 extra, 需要公网 IP; # 如果 _type 是 internal, 不需要公网 IP. extraip = lbinfo.get("extraip", None) extranetmask = lbinfo.get("extranetmask", None) extragateway = lbinfo.get("extragateway", None) # 配置 IP. ret = funcs.ip(lb, _type, device, internalip, internalnetmask, internalgateway, extraip, extranetmask, extragateway) if not ret: return False # 配置 lip. _lips = lips.get(internalip, internalnetmask) ret = funcs.lips(lb, internalip, _lips) if not ret: logger.error("Cfg lb lips failed:%s" % lb) return False logger.info("Cfg lb lips success:%s" % lb) # 保存集群信息. client.hset(key, "lbinfos", lbinfos) logger.info("Lbs added:%s" % ",".join(new_lbs)) return True
def generate(_type, lbinfos, vip2ws, vipnets, device): """ 生成和传输 keepalived 配置. """ j2_env = Environment(loader=FileSystemLoader(LVS_TEMPLATE_DIR), trim_blocks=True) # 各个模板文件名. keepalived_template = "keepalived.conf" sub_keepalived_template = "sub_keepalived.conf" zebra_template = "zebra.conf" ospfd_template = "ospfd.conf" # 建立存放 lvs 临时配置文件基目录. # lb 的配置文件分别几个部分, 一个是 keepalived.conf 主配置 # 文件, 这个文件需要引用每个 VIP 的配置, 额外还需要 ospfd.conf # 和 zebra.conf 配置. 对于 VIP 配置, 所有 lb 都是一样的, # keepalived.conf 主配置文件、 ospfd.conf 和 zebra.conf # 则每个 lb 都不一样. # 基目录下目录结构这么存放: # lbcommon 里面存 每个 lb 都一样的 VIP 配置; # 对于 每个 lb 建立一个目录, 下面有两个子目录, 分别是: # keepalived 和 ospfd, keepalived 下面是 keepalived.conf, # ospfd 下面是 ospfd.conf 和 zebra.conf. # 比如: # ./lbcommon/xxx.xxx.xxx.xxx.conf # ./$lb/ospfd/ospfd.conf # ./$lb/ospfd/zebra.conf # ./$lb/keepalived/keepalived.conf now = time.strftime("%Y%m%d%H%I%M%S") base_dir = LVS_CFG_TMP_DIR + "/" + now os.mkdir(base_dir) # 拿到 lb 和 vip. lbs = [i["hostname"] for i in lbinfos] vips = [i["vip"] for i in vip2ws] try: for lbinfo in lbinfos: lb = lbinfo["hostname"] internalip = lbinfo["internalip"] internalnetmask = lbinfo["internalnetmask"] internalgateway = lbinfo["internalgateway"] routerid = lbinfo["routerid"] ospfnet = lbinfo["ospfnet"] if _type == "extra": extraip = lbinfo["extraip"] extranetmask = lbinfo["extranetmask"] extragateway = lbinfo["extragateway"] _lips = lips.get(internalip, internalnetmask) # 对每个 lb 创建临时目录. lb_dir = base_dir + "/" + lb lb_keepalived_dir = lb_dir + "/keepalived" lb_osfpd_dir = lb_dir + "/ospfd" os.mkdir(lb_dir) os.mkdir(lb_keepalived_dir) os.mkdir(lb_osfpd_dir) # 对于 lb 生成配置. with open(lb_keepalived_dir + "/keepalived.conf", 'w') as f: f.writelines( j2_env.get_template(keepalived_template).render( lips=_lips, vips=vips, lb=lb.split(".")[0] ) ) with open(lb_osfpd_dir + "/zebra.conf", 'w') as f: f.writelines( j2_env.get_template(zebra_template).render( lb=lb ) ) with open(lb_osfpd_dir + "/ospfd.conf", 'w') as f: f.writelines( j2_env.get_template(ospfd_template).render( lb=lb, routerid=routerid, device=device, ospfnet=ospfnet, vipnets=vipnets ) ) # 创建公共临时目录. lb_common_dir = base_dir + "/lbcommon" os.mkdir(lb_common_dir) # 获取 ports 和 wss. for vip in vips: for i in vip2ws: if vip == i["vip"]: if "ports" not in i: ports = [ {"sport": 80, "dport": 80, "synproxy": 1, "persistence_timeout": 50 }, {"sport": 443, "dport": 443, "synproxy": 1, "persistence_timeout": 50 } ] else: ports = list() for j in i["ports"]: if "synproxy" not in j: j["synproxy"] = 1 elif "persistence_timeout" not in j: j["persistence_timeout"] = 50 ports.append(j) wss = i["wss"] break # 把 wss 解析成 IP. wss_ip = utils.dns_resolv(wss) if not wss_ip: message = "Some ws dns resolv failed, wss:%s" % wss logger.error(message) return False # 生成公共的 VIP 配置. with open(lb_common_dir + "/" + vip + ".conf", 'w') as f: f.writelines( j2_env.get_template(sub_keepalived_template).render( vip=vip, ports=ports, wss=wss_ip ) ) message = "Make keepalived cfg success" logger.info(message) except Exception, e: message = "Make keepalived cfg failed:%s" % e logger.error(message) return False