iSCSI高可用性研究

iSCSI

iSCSI相对于FC,具有价格低,部署简单的优点,不需要购买专门的硬件设备,利用网络就可以非常的便捷的构建IPSAN,但也存在着很多的不足,例如易受工具,可用带宽低、缺乏高可用性的冗余机制。
目前来说,实现iSCSI高可用有两种方式,基于多路径和基于虚拟IP。基于多路径的实现可以分为MPIO(Multi-Path Input/Output,多路径输入输出)与MC/S(Multiple Connection per Session, 多重链接)。
iSCSI


多路径

MPIO和MC/S都是通过利用Initiator和Target端建立多条实体存取通道,通过轮询的存取方式,避免单一实体通道中断时,连带导致存取中断;也可以起到传输的均衡,避免传输负荷集中在单一实体通道上,但两种

多重路径 MPIO

MPIO允许一个iSCSI Initiator通过多个Session连如同一个iSCSI Target设备,以便利用多网卡或iSCSI HBA启用负载平衡与故障失效切换机制。

多重链接 MC/S

MC/S可允许在同一个Session中,在iSCSI Initiator与iSCSI Target间建立多个TCP/IP连接,同样也能让用户利用多张网卡或iSCSI HBA启用负载平衡与故障失效切换机制。
MPIO是在更高的网络堆栈层上运行(即在iSCSI层上的SCSI指令层),且多条存取路径间的负载平衡机制,是针对1个指定的独立逻辑驱动器(LUN)运作;而MC/S则是iSCSI中所定义的方法,是在iSCSI层上运作,具有更好的传输验证能力(Error Recovery Levels),另外MC/S的负载平衡是“同时”针对所有的逻辑驱动器运作,这点也与MPIO不同。

实现多路径存取的3种方式

iSCSI的底层是IP与以太网,理论上可直接从网卡实施,利用Port Trunking/Teaming/Link Aggregation的方式,将主机上的多张网卡捆绑在1个IP下,再连接到iSCSI存储设备上,搭配iSCSI存储设备传输埠上的对应设定,从而实现实体多路径连接。但问题在于,不是所有网卡都能支持这种方式。
另外也有一些厂家提供SAN管理的软件,可以建立多路径存取环境,但是大部分只支持特定厂家型号的iSCSI设备。
我们也可以跳过网卡这一层,也不需要使用路径管理软件,直接利用iSCSI Initiator软件配合iSCSI设备建立多路径存储,但不管是MPIO还是MC/S,都必须要满足一定条件:

  • iSCSI Initiator端需有多张网卡或网络端口连接到Target端
  • iSCSI Initiator软件需支持MPIO或MC/S
  • iSCSI Target设备需支持MPIO或MC/S

其中第一项是基本条件,主机若是没有2个以上的网络端口可用,自然也谈不上多路径存取,不过目前多数服务器都内建了至少2组网络端口,这点通常不会成为太大问题。
第2项条件则视不同环境而定,目前各主要操作系统厂商提供的iSCSI Initiator软件中,目前以Windows的支持较为齐全,如微软的iSCSI Initiator 2.06版以后就能支持MPIO与MC/S;Linux环境同样也能支持MPIO。
而就第3点来说,目前MPIO远比MC/S普及,大多数iSCSI存储设备都能支持MPIO。但能支持MC/S的产品就少了许多,在软件式的iSCSI Target方面,目前能支持的也不多,如微软的iSCSI Target、Sun的Solaris iSCSI Target都不支持。


虚拟IP实现高可用

多路径实现高可用特定是指网络环境异常下,iSCSI存取可通过多条通道。但是在分布式环境中,系统的故障不仅仅出现在网络中,很有可能会是系统故障或者磁盘故障,引起系统宕机,无法对外提供服务,即Taget端完全失去功能,这个场景下多路径无法实现高可用性,这时候就需要虚拟IP。

虚拟IP

不论用何种方式进行上网,都必须要有一个唯一的IP地址,事实上IP是硬件地址的一种抽象,简单的来说,MAC就是物理地址,IP就是逻辑地址。
虚拟IP就是非分配给真实主机的IP,也就是说对外提供服务器的主机除了有一个真实IP外还有一个虚IP,使用这两个IP的任何一个都可以连接到主机。

虚拟IP原理

ARP是地址解析协议,它的作用很简单,将一个IP地址转换为MAC地址,然后给传输层使用。每台主机中都有一个ARP高速缓存,存储同一个网络内的IP地址与MAC地址的对应关 系,以太网中的主机发送数据时会先从这个缓存中查询目标IP对应的MAC地址,会向这个MAC地址发送数据。操作系统会自动维护这个缓存。在Linux下可以使用arp命令操作ARP高速缓存。当备用主机得知主机无法对外提供服务时,他会将自己的ARP缓存发送出去,这样外界访问虚拟IP的时候,备用主机会变成主服务器,完成了主从机器的切换。

IP漂移

上述VIP切换过程就称为IP漂移

测试

测试机有三台机器,分别是:

  • server1: 192.168.74.128
  • server2: 192.168.74.129
  • server3: 192.168.74.130

在server2和server3设置虚拟IP:192.168.74.140,具体步骤如下:
执行ifconfig命令,查看网卡

1
2
3
4
5
6
7
8
9
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.74.129 netmask 255.255.255.0 broadcast 192.168.74.255
inet6 fe80::5cc6:76f6:7c44:c4e8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:e6:98:77 txqueuelen 1000 (Ethernet)
RX packets 825 bytes 82937 (80.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 578 bytes 72714 (71.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

添加虚拟IP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# ifconfig ens33:1 192.168.74.140 netmask 255.255.255.0 up
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.74.129 netmask 255.255.255.0 broadcast 192.168.74.255
inet6 fe80::5cc6:76f6:7c44:c4e8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:e6:98:77 txqueuelen 1000 (Ethernet)
RX packets 825 bytes 82937 (80.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 578 bytes 72714 (71.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.74.140 netmask 255.255.255.0 broadcast 192.168.74.255
ether 00:0c:29:e6:98:77 txqueuelen 1000 (Ethernet)

server1上实现一个脚本,不停的ping这个虚拟ip,整个测试的过程是,首先server2设置虚拟ip,启动server1不停的ping这个虚拟ip,然后将server2的虚拟ip关闭,从server3上启动虚拟ip,并向路由器发送arp包,查看是否可以ping通。
server1的脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import subprocess
import shlex
import time
cmd = "ping -c 1 192.168.74.140"
args = shlex.split(cmd)
def ping_server():
while True:
time.sleep(1)
subprocess.check_call(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print "The server is up!"
try:
ping_server();
except subprocess.CalledProcessError:
print "The server is down!"
print "Ping the server again after 10 seconds!"
time.sleep(10)
try:
ping_server();
except subprocess.CalledProcessError:
print "The server is down!"

server2关闭虚拟ip:

1
[root@localhost ~]# ifconfig ens33:1 192.168.74.140 netmask 255.255.255.0 down

server3开启虚拟ip,并广播arp包:

1
2
[root@localhost ~]# ifconfig ens33:1 192.168.74.140 netmask 255.255.255.0 up
[root@localhost ~]# arping -I ens33 -s 192.168.74.140 -b -c 1 192.168.74.0

测试结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost vip]# python python_ping.py
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!
The server is down!
Ping the server again after 10 seconds!
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!
The server is up!

结论:从结果可以看到,server2出现故障,server3可以接管server2,同时server3自身的实际ip是不会受到影响的,这就是ip漂移。

参考资料:
深入了解iSCSI的2种多路径访问机制
IP地址漂移的实现与原理
linux同一机器设置多个虚拟IP