分类: 系统运维
2009-04-04 11:18:39
NAT模式是IPVS最常用的一种模式。相比于TUN和DR模式,NAT模式更容易部署,仅仅是需要更改真实服务器的默认网关配置。
IPVS是基于Netfilter实现的。它注册了4个Netfilter钩子函数,其中与NAT模式相关的是ip_vs_in和ip_vs_out两个钩子函数。前者处理了客户端-〉服务器的数据包,后者则针对服务器-〉客户端的数据包。
ip_vs_in函数的处理流程非常清晰:
预校验--〉ip_vs_conn对象的查找或生成--〉更新统计信息--〉更新ip_vs_conn对象的状态--〉修改sk_buff并转发数据包--〉IPVS状态同步--〉结束
预校验的过程很简单,主要包括:
既然有数据包来了,必然有对应的ip_vs_conn对象。首先根据数据包的<源地址-源端口-目的地址-目的端口>,查找当前的 ip_vs_conn对象列表。如果没有找到的话,说明这是一个新连接,于是运行调度过程,找到一个合适的真实服务器,然后再生成一个新的 ip_vs_conn对象。这里先不对调度过程进行展开描述。
这里先看一下ip_vs_stats结构,其各个成员的作用很容易看出来:
|
这是一个专门用于统计的数据结构,每个ip_vs_service对象、每个ip_vs_dest对象都包含有这么一个结构,另外还有一个ip_vs_stats全局变量。
函数ip_vs_in_stats和ip_vs_out_stats分别统计两个方向的数据包流量,函数ip_vs_conn_stats用于统计新建连接数。
|
conns、inpkts、outpkts、inbytes和outbytes统计比较容易,只需简单的加1。但cps等统计起来就要复杂一些了,它是通过内核定时器来实现的。每个ip_vs_stats对象都对应有一个ip_vs_estimator结构:
|
所有的ip_vs_estimator结构形成一张链表,通过全局变量est_list可以遍历这个链表。定时器的时间间隔为2秒,对应的触发函数为:
|
以cps的统计为例,其计算过程很简单,cps = (rate+cps)/2,其中单位为2^10。
在TCP数据包处理过程中,每个ip_vs_conn对象对应于一个TCP连接,因此也必须有一个状态转换过程,才能够引导此TCP连接正常建立和终止。这个状态转换颇为复杂,在后续内容将IN/OUT结合一起,来看TCP连接的状态转换。
NAT模式下的数据包转发由ip_vs_nat_xmit函数完成。对sk_buff数据结构的操作不熟悉,略过。
先判断此ip_vs_conn对象是否需要进行主备机同步。首先当前IPVS必须是MASTER,并且此ip_vs_conn对象的状态为ESTABLISHED。另外,满足这些条件时,并非每个Packet转发的时候都进行同步,而是每50个Packet,才同步一次。
同步过程由函数ip_vs_sync_conn完成:
|
ip_vs_out函数处理 服务器-〉客户端 的数据包。相比于ip_vs_in函数,它要简单得多。这里不再描述。
IPVS支持TCP、UDP、AH和ESP四种协议。由于TCP协议的逻辑相对复杂一些,所以IPVS对TCP协议的特殊处理也更多。
IPVS针对TCP协议的处理主要是体现在TCP状态维护上,而TCP状态维护依赖于一个状态转换矩阵:
|
与NAT模式相关的为INPUT和OUTPUT两张表,其意思也较容易理解:
状态转换矩阵也可以用一张状态转换图来表示: