LVS集群系统网络核心原理分析

发表于:2007-07-04来源:作者:点击数: 标签:
Inte .net 的快速增长使多媒体 网络 服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲,CPU、I/O处理能力很快会成为瓶颈。由于单台服务器的 性能 总是有限的,简单的提高硬件性能并不能真正解决这个问
 

Inte.net的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲,CPU、I/O处理能力很快会成为瓶颈。由于单台服务器的性能总是有限的,简单的提高硬件性能并不能真正解决这个问题。为此,必须采用多服务器和负载均衡技术才能满足大量并发访问的需要。Linux 虚拟服务器(Linux Virtual Servers,LVS) 使用负载均衡技术将多台服务器组成一个虚拟服务器。它为适应快速增长的网络访问需求提供了一个负载能力易于扩展,而价格低廉的解决方案

1.LVS结构与工作原理

LVS的结构如图1所示,它由前端的负载均衡器(Load Balancer,LB)和后端的真实服务器(Real Server,RS)群组成。RS间可通过局域网或广域网连接。LVS的这种结构对用户是透明的,用户只能看见一台作为LB的虚拟服务器(Virtual Server),而看不到提供服务的RS群。

如图1所示javascript:window.open(this.src);" style="CURSOR: pointer" onload="return imgzoom(this,550)">

当用户的请求发往虚拟服务器,LB根据设定的包转发策略和负载均衡调度算法将用户请求转发给RS。RS再将用户请求结果返回给用户。同请求包一样,应答包的返回方式也与包转发策略有关。

LVS的包转发策略有三种:

  • NAT (Network Address Translation)模式。LB收到用户请求包后,LB将请求包中虚拟服务器的IP地址转换为某个选定RS的IP地址,转发给RS;RS将应答包发给LB,LB将应答包中RS的IP转为虚拟服务器的IP地址,回送给用户。
  • IP隧道 (IP Tunneling)模式。LB收到用户请求包后,根据IP隧道协议封装该包,然后传给某个选定的RS;RS解出请求信息,直接将应答内容传给用户。此时要求RS和LB都要支持IP隧道协议。
  • DR(Direct Routing)模式。LB收到请求包后,将请求包中目标MAC地址转换为某个选定RS的MAC地址后将包转发出去,RS收到请求包后 ,可直接将应答内容传给用户。此时要求LB和所有RS都必须在一个物理段内,且LB与RS群共享一个虚拟IP。

2、IPVS软件结构与实现

LVS软件的核心是运行在LB上的IPVS,它使用基于IP层的负载均衡方法。IPVS的总体结构如图2所示,它主要由IP包处理、负载均衡算法、系统配置与管理三个模块及虚拟服务器与真实服务器链表组成。

如图2所示

2.1 LVS对 IP包的处理模式

IP包处理用Linux 2.4内核的Netfilter框架完成。一个数据包通过Netfilter框架的过程如图所示:

通俗的说,netfilter的架构就是在整个网络流程的若干位置放置了一些检测点(HOOK),而在每个检测点上上登记了一些处理函数进行处理(如包过滤,NAT等,甚至可以是用户自定义的功能)。

IP层的五个HOOK点的位置如下图所示(copy from ) :

如图3所示

  1. NF_IP_PRE_ROUTING:刚刚进入网络层的数据包通过此点(刚刚进行完版本号,校验和等检测),源地址转换在此点进行;
  2. NF_IP_LOCAL_IN:经路由查找后,送往本机的通过此检查点,INPUT包过滤在此点进行;
  3. NF_IP_FORWARD:要转发的包通过此检测点,FORWORD包过滤在此点进行;
  4. NF_IP_LOCAL_OUT:本机进程发出的包通过此检测点,OUTPUT包过滤在此点进行;
  5. NF_IP_POST_ROUTING:所有马上便要通过网络设备出去的包通过此检测点,内置的目的地址转换功能(包括地址伪装)在此点进行。

在IP层代码中,有一些带有NF_HOOK宏的语句,如IP的转发函数中有:

clearcase/" target="_blank" >cccccc border=1>
<-ipforward.c ip_forward()->  NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2,ip_forward_finish);//其中NF_HOOK宏的定义基本如下:<-/include/linux/netfilter.h->#ifdef CONFIG_NETFILTER#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)(list_empty(&nf_hooks[(pf)][(hook)])? (okfn)(skb): nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn)))#else /* !CONFIG_NETFILTER */#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)#endif /*CONFIG_NETFILTER*/ 

如果在编译内核时没有配置netfilter时,就相当于调用最后一个参数,此例中即执行ip_forward_finish函数;否则进入 HOOK点,执行通过nf_register_hook()登记的功能(这句话表达的可能比较含糊,实际是进入nf_hook_slow()函数,再由它执行登记的函数)。

NF_HOOK宏的参数分别为:

  1. pf:协议族名,netfilter架构同样可以用于IP层之外,因此这个变量还可以有诸如PF_INET6,PF_DECnet等名字。
  2. hook:HOOK点的名字,对于IP层,就是取上面的五个值;
  3. skb:顾名思义
  4. indev:进来的设备,以struct net_device结构表示;
  5. outdev:出去的设备,以struct net_device结构表示;
  6. okfn:是个函数指针,当所有的该HOOK点的所有登记函数调用完后,转而走此流程。

这些点是已经在内核中定义好的,除非你是这部分内核代码的维护者,否则无权增加或修改,而在此检测点进行的处理,则可由用户指定。像 packet filter,NAT,connection track这些功能,也是以这种方式提供的。正如netfilter的当初的设计目标--提供一个完善灵活的框架,为扩展功能提供方便。

如果我们想加入自己的代码,便要用nf_register_hook函数,其函数原型为:

int nf_register_hook(struct nf_hook_ops *reg)struct nf_hook_ops://结构struct nf_hook_ops{struct list_head list;/* User fills in from here down. */nf_hookfn *hook;int pf;int hooknum;/* Hooks are ordered in ascending priority. */int priority;};

其实,类似LVS的做法就是生成一个struct nf_hook_ops结构的实例,并用nf_register_hook将其HOOK上。其中list项要初始化为{NULL,NULL};由于一般在 IP层工作,pf总是PF_INET;hooknum就是HOOK点;一个HOOK点可能挂多个处理函数,谁先谁后,便要看优先级,即priority的指定了。netfilter_ipv4.h中用一个枚举类型指定了内置的处理函数的优先级:

enum nf_ip_hook_priorities {NF_IP_PRI_FIRST = INT_MIN,NF_IP_PRI_CONNTRACK = -200,NF_IP_PRI_MANGLE = -150,NF_IP_PRI_NAT_DST = -100,NF_IP_PRI_FILTER = 0,NF_IP_PRI_NAT_SRC = 100,NF_IP_PRI_LAST = INT_MAX,};

hook是提供的处理函数,也就是我们的主要工作,其原型为:

unsigned int nf_hookfn(unsigned int hooknum,       struct sk_buff **skb,       const struct net_device *in,       const struct net_device *out,       int (*okfn)(struct sk_buff *));

它的五个参数将由NFHOOK宏传进去。

以上是NetFillter编写自己模块时的一些基本用法,接下来,我们来看一下LVS中是如何实现的。

3.LVS中Netfiler的实现

利用Netfilter,LVS处理数据报从左边进入系统,进行IP校验以后,数据报经过第一个钩子函数NF_IP_PRE_ROUTING [HOOK1]进行处理;然后进行路由选择,决定该数据报是需要转发还是发给本机;若该数据报是发被本机的,则该数据经过钩子函数 NF_IP_LOCAL_IN[HOOK2]处理后传递给上层协议;若该数据报应该被转发,则它被NF_IP_FORWARD[HOOK3]处理;经过转发的数据报经过最后一个钩子函数NF_IP_POST_ROUTING[HOOK4]处理以后,再传输到网络上。本http://edu.itbulo.com/show/house/'>地产生的数据

原文转自:http://www.ltesting.net