网卡绑定和负载均衡
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
配置:
[root@t20b003 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
USERCTL=no
[root@t20b003 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth2
DEVICE=eth2
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
USERCTL=no
[root@t20b003 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth3
DEVICE=eth3
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
USERCTL=no
[root@t20b003 ~]# cat /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
IPADDR=116.55.251.4
NETMASK=255.255.255.224
BONDING_OPTS="mode=6 miimon=100"
[root@t20b003 ~]# cat /etc/modprobe.d/bonding.conf
alias netdev-bond0 bonding
#BONDING_OPTS="mode=6 miimon=100" 可以放ifcfg-bond0上面
[root@t20b003 ~]# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)
Bonding Mode: adaptive load balancing
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 1
Permanent HW addr: f8:bc:12:44:0b:c9
Slave queue ID: 0
Slave Interface: eth2
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 1
Permanent HW addr: f8:bc:12:44:0b:ca
Slave queue ID: 0
Slave Interface: eth3
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 1
Permanent HW addr: f8:bc:12:44:0b:cb
Slave queue ID: 0
Bonding的模式一共有7种:
#defineBOND_MODE_ROUNDROBIN 0 (balance-rr模式)网卡的负载均衡模式
#defineBOND_MODE_ACTIVEBACKUP 1 (active-backup模式)网卡的容错模式,主备模式,只有一块网卡是active,另外一块是备的standby,这时如果交换机配的是捆绑,将不能正常工作,因为交换机往两块网卡发包,有一半包是丢弃的。
#defineBOND_MODE_XOR 2 (balance-xor模式)需要交换机支持
#defineBOND_MODE_BROADCAST 3 (broadcast模式)
#defineBOND_MODE_8023AD 4 (IEEE 802.3ad动态链路聚合模式)需要交换机支持
#defineBOND_MODE_TLB 5 自适应传输负载均衡模式
#defineBOND_MODE_ALB 6 网卡虚拟化方式
bonding模块的所有工作模式可以分为两类:多主型工作模式和主备型工作模式,balance-rr 和broadcast属于多主型工作模式而active-backup属于主备型工作模式。(balance-xor、自适应传输负载均衡模式(balance-tlb)和自适应负载均衡模式(balance-alb)也属于多主型工作模式,IEEE 802.3ad动态链路聚合模式(802.3ad)属于主备型工作模式
一、网卡的负载均衡模式(mode = BOND_MODE_ROUNDROBIN)
1)建立bond虚设备
建立一个ifcfg-bond0的设备,然后配置如下信息即可。
DEVICE=bond0
BOOTPR
OTO=static
IPADDR=172.16.64.208
NETMASK=255.255.224.0
ONBOOT=yes
TYPE=Ethernet
2)配置接口文件
由于使用一个虚拟的ip地址,所以,其他接口设备都不配置ip信息。
3)配置bonding工作方式
打开/etc/modprobe.conf文件,将bonding的工作模式配置为如下模式。
alias bond0bonding
optionsbond0 mode=0 arp_interval=500arp_ip_target=172.16.64.86
4)启动bonding
需要添加路由来制定发送规则,这个可以自定义添加。配置完后重启设备即可。
ifenslave bond0eth0 eth1
route add -net0/0 gw 172.16.64.254
bond0 Link encap:Ethernet HWaddr 00:14:10:70:00:25
inet addr:172.16.64.208 Bcast:172.16.95.255 Mask:255.255.224.0
inet6 addr: fe80::200:ff:fe00:0/64Scope:Link
UP BROADCAST RUNNING MASTERMULTICAST MTU:1500 Metric:1
RX packets:39335 errors:0 dropped:0overruns:0 frame:0
TX packets:3178 errors:0 dropped:0overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3020656 (2.8 MiB) TX bytes:269722 (263.4 KiB)
eth0 Link encap:Ethernet HWaddr 00:14:10:70:00:25
UP BROADCAST RUNNING SLAVEMULTICAST MTU:1500 Metric:1
RX packets:18208 errors:0 dropped:0overruns:0 frame:0
TX packets:5 errors:0 dropped:0overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1371589 (1.3 MiB) TX bytes:378 (378.0 b)
eth1 Link encap:Ethernet HWaddr 00:14:10:70:00:25
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
RX packets:21128 errors:0 dropped:0overruns:0 frame:0
TX packets:3174 errors:0 dropped:0overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:1649127 (1.5 MiB) TX bytes:269498 (263.1 KiB)
如上图所示,这种模式下bonding模块会将虚接口和所有的slave接口的MAC地址设置为一致。通过定时器,每个slave接口不断发送ARP包来不断更换交换机端口与MAC的对应关系。
这样使得每个网卡都在进行工作。这个ARP的发送规则是:
每arp_interval(MS)间隔向arp_ip_target发送arp请求。也可以向多个arp_ip_target发送arp请求。
观察交换机端口上所学习到的MAC地址,发现MAC会在两个端口上反复切换。
在BOND_MODE_ROUNDROBIN模式下,bonding对于发送和接收数据的处理逻辑是不一致的,对于数据的接收,bonding基本不做任何处理,纯粹依靠交换机端口与MAC的变化来实现交替接收数据。发送的话,交换机会根据数据的源MAC来学习端口和MAC之间的关系,所以bonding做到的就是选择不一样的网卡发送。
对于数据的发送,
static inline voidbond_set_mode_ops(struct net_device *bond_dev, int mode)
{
switch(mode) {
case BOND_MODE_ROUNDROBIN:
bond_dev->hard_start_xmit =bond_xmit_r
oundrobin;
break;
...
bond的发送函数被注册为bond_xmit_roundrobin。通过bond_xmit_roundrobin的实现可以发现
static int bond_xmit_roundrobin(structsk_buff *skb, struct net_device *bond_dev)
{
read_lock(&bond->curr_slave_lock);
slave = start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
bond_for_each_slave_from(bond, slave, i,start_at) {
if(IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
(slave->state ==BOND_STATE_ACTIVE)) {
res =bond_dev_queue_xmit(bond, skb, slave->dev);
write_lock(&bond->curr_slave_lock);
bond->curr_active_slave= slave->next;
write_unlock(&bond->curr_slave_lock);
break;
}
bond_xmit_roundrobin会通过curr_active_slave指针所指向的设备来进行发送,当然curr_active_slave会在调用bond_dev_queue_xmit完成实际的发送之后指向下一个slave设备。bond_dev_queue_xmit实际是调用通用的发送函数dev_queue_xmit来进行的,它传递给dev_queue_xmit的是一个skb,在传递之前skb->dev就被指定为了当前的slave设备,这样内核就会找到对应的真实网卡设备来进行发送,最后curr_active_slave指针的轮询切换,实现了bonding的负载均衡工作模式。
从这种模式可以看到,bonding实现了一个类似网卡驱动的模块,对应的bond0设备是一个纯粹的虚设备,数据发送虽然说经过了它,但通过一系列调用,转了一圈之后才回到真正的网卡设备那里进行发送,无疑会消耗一定的系统性能。
简单用100Mbps速率的UDP数据包测试了一下BOND_MODE_ROUNDROBIN模式。
测试过程中发现接收端会有较多的乱序包,观察交换机端口情况,端口之间的切换频率不规则,这个和交换机的配置或者性能应该有很大联系,有必要的话需要进一步研究。数据的正确性和时序性能否保证需要进一步仔细测试。
2、网卡的容错模式(mode =BOND_MODE_ACTIVEBACKUP)
容错模式的配置方法和负载均衡模式基本差不多,只不过修改一下/etc/modprobe.conf即可。
alias bond0 bonding
options bond0 mode=1 miimon=100
这里使用的是mii链路检测方式,与之前arp检测方式不同。当然这两种链路检测方式在各种mode下都是可以使用的,但要注意不能同时使用。
介绍一下bonding的mii检测实现。首先和arp-monitor一样,mii也是定时器触发
if(bond->params.miimon) { /* link checkinterval, in milliseconds. */
init_timer(mii_timer);
mii_timer->expires = jiffies + 1;
mii_timer->data = (unsigned long)bond_dev;
mii_timer->function = (void*)&bond_mii_monitor;
add_timer(mii_timer);
}
bond_mii_monitor函数其本质的原理就是检测网卡的链路状态,bonding定义网卡有4个链路状态:
BOND_LINK_UP: 正常状态(处于该状态的网卡是是潜在的发送数据包的候选者)
BOND_LINK_FAIL: 网卡出现故障,向状态BOND_LINK_DOWN 切换中
BOND_LINK_DOWN: 失效状态
BOND_LINK_BACK: 网卡恢复,向状态BOND_LINK_UP切换中
从上到下,表示了网卡链路从正常到失效再到恢复状态。bond_mii_monitor函数就是依次检查网卡的链路状态是否处于这些状态,然后通过标记do_failover变量来说明当前是否需要切换slave网卡。代码篇幅较大,但逻辑还是很清晰的,故此处不罗列了。
在BOND_MODE_ACTIVEBACKUP模式下,两块网卡其实有一块是不工作的,被设置为IFF_NOARP的状态。同时,bond虚设备,还有slave设备的MAC地址均一致,所以这张网卡不会被外界察觉存在。交换机也不存在想该端口发包的情况。当bond的mii检测发现当前的active设备失效了之后,会切换到这个备份设备上。
在bond_change_active_slave函数中
if (bond->params.mode ==BOND_MODE_ACTIVEBACKUP) {
if (old_active) {
bond_set_slave_inactive_flags(old_active);
}
if (new_active) {
bond_set_slave_active_flags(new_active);
}
}
这个就是在BOND_MODE_ACTIVEBACKUP模式下的切换逻辑,很简单,需要注意的是,在bond_set_slave_inactive_flags(old_active)中,需要将接口的状态设置为IFF_NOARP,不然交换机就可能会把数据包发送到一个错误的端口上。
BOND_MODE_ACTIVEBACKUP模式下的数据发送非常简单,可想而知curr_active_slave指针始终都指向当前可用的设备,所以直接发送就可以,没有之前BOND_MODE_ROUNDROBIN模式下slave设备切换的过程。
3、网卡虚拟化方式(mode = BOND_MODE_ALB)
经过考察,许多磁盘阵列设备采用了网卡虚拟化方式进行多网卡应用。实际就是Linux的bonding技术。它采用了mode = BOND_MODE_ALB的方式。
BOND_MODE_ALB的实现方式比较复杂,还有一些不理解的地方,就不做深入分析了。其核心思想可以用下图解释:
从这个图中可以看到,客户端A与服务器的传输使用的是MACA;而客户端B与服务器传输使用的是MAC B,但对于IP层来说,客户端A与B都与服务器X.X.X.X 的IP地址进行通讯,并不感知底层传输接口的变化。这样,服务器对于客户端整体上的工作模式就处于负载均衡
的状态。当然,这个过程的控制就是bonding模块所完成的。
通过测试发现两台客户端展现的arp表是一致的,如下(服务器端地址为172.16.64.208,服务器端首选接口的MAC为00-14-10-70-00-25)
CLIENT A
172.16.64.208 00-14-10-70-00-25 dynamic
CLIENT B
172.16.64.208 00-14-10-70-00-25 dynamic
通过抓包可以看到,两次回复的ARP应答的源MAC地址是不一样的,分别为
00-14-10-70-00-25和
00-14-10-70-00-26。
所以说,能够实现这种处理方法的原因就是bonding修改了ARP应答的源地址导致,使得外界并不感知服务器存在多网卡的状态,在网络上确定了IP和MAC的唯一对应关系,保证了上层业务传输的逻辑一致性。同时内部的处理又交给不同的网卡,实现了负载均衡。
另外,也给了我们一定的容错性,当一个接口失效后,bonding会迅速将另外一块网卡设置为首选slave设备,并修改其MAC地址。由于外界学习到的服务器MAC地址始终是不变的,所以链路的状态不会受很大影响。