很多是转载的,也有自己的理解。
IPVS支持对连接的同步,两台IPVS设备可分别以MASTER或BACKUP运行,MASTER进程可将连接信息备份到BACKUP设备上,这样主设备死机时从设备可以无缝切换。
或者可以在IPVS设备上同时启动MASTER和BACKUP进程,使设备之间互为备份,实现IPVS设备的均衡。
IPVS同步实现在net/ipv4/ipvs/ip_vs_sync.c中.
同步信息块的格式如下,开始是4字节的信息头,后面是多个IPVS连接同步信息,每个块大小不固定,连接同步信息个数从0到多个:
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Count Conns | SyncID | Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| IPVS Sync Connection (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . |
| . |
| . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| IPVS Sync Connection (n) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
同步信息块用UDP协议,组播的方式发送。在应用层启动同步这个线程时(同步是在内核作的,通过应用层的指令启动),会传进来一个参数syncid.只有syncid相同的两台机器才会作为备份。也就是说对于backup的设备,只有syncid和master相同,才会记录master组播的connection mesg。启动同步线程时,会调用join_mcast_group加入到一个组播组里。
数据结构
#define SYNC_MESG_HEADER_LEN 4
信息头结构
struct ip_vs_sync_mesg {
__u8 nr_conns; // 连接数
__u8 syncid; // 同步ID
__u16 size; // 数据总长
/* ip_vs_sync_conn entries start here */
};
IPVS连接同步信息结构
struct ip_vs_sync_conn {
__u8 reserved;
// 连接基本信息
/* Protocol, addresses and port numbers */
__u8 protocol; /* Which protocol (TCP/UDP) */
__u16 cport;
__u16 vport;
__u16 dport;
__u32 caddr; /* client address */
__u32 vaddr; /* virtual address */
__u32 daddr; /* destination address */
// 连接的状态和标志
/* Flags and state transition */
__u16 flags; /* status flags */
__u16 state; /* state info */
// 后续可能有连接选项参数,就是TCP的序列号和确认号信息
/* The sequence options start here */
};
IPVS连接同步选项结构,,就是进入和发出发现TCP的序列号信息
struct ip_vs_sync_conn_options {
struct ip_vs_seq in_seq; /* incoming seq. struct */
struct ip_vs_seq out_seq; /* outgoing seq. struct */
};
连接数据控制块结构
struct ip_vs_sync_buff {
struct list_head list; // 形成队列
unsigned long firstuse;
//实际的同步信息
/* pointers for the message data */
struct ip_vs_sync_mesg *mesg;
unsigned char *head;
unsigned char *end;
};
ip_vs_sync_mesg的信息都存放在ip_vs_sync_buff中。其中,一个buff中存放一个ip_vs_sync_mesg,但是一个mesg中可以存放多个connection entry。通过head,end元素来控制mesg的容量,ip_vs_sync_buff在vmalloc时,它的大小就已经是固定的。另外,ip_vs_sync_mesg是同步时一次传输的单元,IPVS在同步时,会考虑MTU的大小,按照MTU的大小设定mesg的大小,使得mesg可以不用分片。以太网的MTU是1500。
IPVS同步进程是一个内核进程,是由IPVSADM通过命令启动的.
int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
{
struct ip_vs_sync_thread_data *tinfo;
struct task_struct **realtask, *task;
struct socket *sock;
<