1、Keepalived及VRRP原理介绍
keepalived:即在linux中vrrp协议的实现
http://www.keepalived.org/
什么是Keepalived?
Keepalived是一个用C语言编写的路由软件。该项目的主要目标是为Linux系统和基于Linux的基础架构提供简单而强大的负载均衡和高可用性设施。负载均衡框架依赖于众所周知且广泛使用的Linux虚拟服务器(IPVS)内核模块,提供Layer4负载均衡。Keepalived实现了一组检查程序,以根据其运行状况动态地和自适应地维护和管理负载均衡的服务器池。另一方面,VRRP实现了高可用性协议。VRRP是路由器故障转移的基础。此外,Keepalived为VRRP有限状态机实现了一组挂钩,提供低级和高速协议交互。Keepalived框架可以单独使用,也可以一起使用,以提供灵活的基础架构。
VRRP:Virtual Router Redundancy Protocol 虚拟路由器冗余协议
Linux Cluster 三种Linux集群
LB: lvs, nginx 负载均衡集群
HA:keepalived, heartbeat, corosync, cman 高可用集群
HP:高性能集群
分布式存储:HDFS 大规模并行应用处理用到
分布式计算:YARN batch: MapReduce
in-memory: spark
stream: storm keepalived高可用实现方案
Acitve/Passive 活动节点/备用节点
把LVS与nginx作为负载均衡器所需要的配置
lvs: vip, ipvs rules
nginx: vip, nginx service
vip和ipvs rules或者vip和nginx service被称为resource,即高可用资源
HA Service: resources 高可用服务有可能是由很多资源组成
每个主机的配置是一样的,除了IP不同,所以主节点挂掉后副节点就会把IP抢过来继续工作,所以争夺的资源焦点是IP,当然还有其他,比如存储。
假如两个高可用集群为LAMP高可用,分为一主一从,又用到了共享存储,存储分为结构化数据(mysql)和非结构化数据(存储在文件系统上)。当主节点访问MySQL时,恰巧主节点宕机,然后副节点就把IP夺过来,然后开始访问MySQL,MySQL是可以处理并发访问控制的。但是文件系统被访问前必须挂载到主机上,如果主机点访问文件系统上的数据时宕机了,那么副节点再访问文件系统上的数据该如何处理?同时访问文件系统数据的主节点的进程和副节点的进程不再同一个主机上,不存在并发控制,又该怎么处理?
这是需要找一个服务,这个服务要能自行解决并发访问控制能力。此时这里使用的是独立的存储,比如本身具有并发访问控制能力的分布式文件系统就可以解决问题。
谁是活动节点谁可以挂载,即便是多个节点同时挂载也没有问题,因为并发访问控制在后端访问器内部有共享的控制功能。
所以对于高可用集群来讲,他们争用的资源是IP和存储,因为服务只需要按需求自行配置好就可以了,所以服务不是争用资源。 ntp: network time protocol/chrony //网络时间协议 https://www.ntppool.org/en/use.html
以某一个主机的时间为准确时间,然后其他主机通过ntp协议进行时钟同步
# ntpdate -u cn.pool.ntp.org //cn:China
vrrp:virtual route redundent protocol 虚拟路由冗余协议
keepalived是vrrp协议在Linux上的实现
把两个物理路由器构建成一个虚拟路由器,虚拟路由器的地址可以想象成客户端所指向的网关的地址。
VRRP协议介绍 http://www.h3c.com/cn/d_200802/335873_30003_0.htm VRRP技术白皮书
1、相关术语
虚拟路由器:由一个Master路由器和多个Backup路由器组成。主机将虚拟路由器当作默认网关。
VRID(virtual route ID):虚拟路由器的标识。有相同VRID的一组路由器构成一个虚拟路由器。
Master路由器:虚拟路由器中承担报文转发任务的路由器。
Backup路由器:Master路由器出现故障时,能够代替Master路由器工作的路由器。
虚拟IP地址:虚拟路由器的IP地址。一个虚拟路由器可以拥有一个或多个IP地址。
IP地址拥有者:接口IP地址与虚拟IP地址相同的路由器被称为IP地址拥有者。
虚拟MAC地址:一个虚拟路由器拥有一个虚拟MAC地址。虚拟MAC地址的格式为00-00-5E-00-01-{VRID}。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址。
如何解决VIP从一个master迁移到另一个另一个backup的问题?因为当VIP在master点时,此时局域网内的客户端存储的是VIP所在的master的MAC地址,而当master宕机,VIP迁移到backup节点时,局域网内的客户端保留的VIP所对应的MAC地址依然是master的MAC地址,这时局域网内的客户端向外发送信息时还是会去找master。
解决办法两个:
1.arp欺骗:
每一主机在局域网中都会自动不断接收网络中的各种广播信息,尤其是arp的解析广播信息,并且收到一个arp解析广播信息后,主机都会与自己的arp缓存做比对。例如一个主机在局域网内广播1.1.1.1对应的MAC地址是多少,1.1.1.1这个主机收到广播后就会广播响应,此时在同一局域网内的其他主机也可以收到主机1.1.1.1的回应,其他主机就会把1.1.1.1的回应广播与自己arp缓存进行对比,如果MAC不一致,这个主机就做修改。鉴于此方法,任何时刻当VIP从一个主机迁移到另一个主机时,那么转移到的主机(A)就来一个自问自答的arp广播,即主机(比如是A)会广播问:A主机IP对应的MAC地址是什么,这时A再回答具体是什么,那么在同一个局域网中的其他主机听到这个arp广播后就会自动更新A的IP所对应的MAC地址
2.VMAC:virtual MAC是使用物理MAC,最终还要结合arp欺骗
优先级:VRRP根据优先级来确定虚拟路由器中每台路由器的地位。
非抢占方式:如果Backup路由器工作在非抢占方式下,则只要Master路由器没有出现故障,Backup路由器即使随后被配置了更高的优先级也不会成为Master路由器。
抢占方式:如果Backup路由器工作在抢占方式下,当它收到VRRP报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的Master路由器的优先级高,就会主动抢占成为Master路由器;否则,将保持Backup状态。
# tcpdump -i eth0 host 192.168.184.142 2、虚拟路由器简介
VRRP将局域网内的一组路由器划分在一起,形成一个VRRP备份组,它在功能上相当于一台虚拟路由器,使用虚拟路由器号进行标识。以下使用虚拟路由器代替VRRP备份组进行描述。
虚拟路由器有自己的虚拟IP地址和虚拟MAC地址,它的外在表现形式和实际的物理路由器完全一样。局域网内的主机将虚拟路由器的IP地址设置为默认网关,通过虚拟路由器与外部网络进行通信。
虚拟路由器是工作在实际的物理路由器之上的。它由多个实际的路由器组成,包括一个Master路由器和多个Backup路由器。Master路由器正常工作时,局域网内的主机通过Master与外界通信。当Master路由器出现故障时,Backup路由器中的一台设备将成为新的Master路由器,接替转发报文的工作,如图2所示。 3、VRRP工作过程
VRRP的工作过程为:
(1)虚拟路由器中的路由器根据优先级选举出Master。Master路由器通过发送欺骗ARP报文,将自己的虚拟MAC地址通知给与它连接的设备或者主机,从而承担报文转发任 务;(假如路由器的优先级一样,就根据主机的IP地址大小进行选择,IP地址大的是master)
(2)Master路由器周期性发送VRRP报文,以公布其配置信息(优先级等)和工作状况;
(3)如果Master路由器出现故障,虚拟路由器中的Backup路由器将根据优先级重新选举新的Master;因为可能会有多个Backup路由器。
(4)虚拟路由器状态切换时,Master路由器由一台设备切换为另外一台设备,新的Master路由器只是简单地发送一个携带虚拟路由器的MAC地址和虚拟IP地址信息的欺骗
ARP报文,这样就可以更新与它连接的主机或设备中的ARP相关信息。网络中的主机感知不到Master路由器已经切换为另外一台设备。
(5)Backup路由器的优先级高于Master路由器时,由Backup路由器的工作方式(抢占方式和非抢占方式)决定是否重新选举Master。
由此可见,为了保证Master路由器和Backup路由器能够协调工作,VRRP需要实现以下功能: Master路由器的选举;
Master路由器状态的通告;
同时,为了提高安全性,VRRP还提供了认证功能;
4、Master路由器的选举
VRRP根据优先级来确定虚拟路由器中每台路由器的角色(Master路由器或Backup路由器)。优先级越高,则越有可能成为Master路由器。
初始创建的路由器工作在Backup状态,通过VRRP报文的交互获知虚拟路由器中其他成员的优先级: 如果VRRP报文中Master路由器的优先级高于自己的优先级,则路由器保持在Backup状态;
如果VRRP报文中Master路由器的优先级低于自己的优先级,采用抢占工作方式的路由器将抢占成为Master状态,周期性地发送VRRP报文,采用非抢占工作方式的路由 器仍保持Backup状态;
如果在一定时间内没有收到VRRP报文,则路由器切换为Master状态。 VRRP优先级的取值范围为0到255(数值越大表明优先级越高),可配置的范围是1到254,优先级0为系统保留给路由器放弃Master位置时候使用,255则是系统保留给IP地址拥有者使用。当路由器为IP地址拥有者时,其优先级始终为255。因此,当虚拟路由器内存在IP地址拥有者时,只要其工作正常,则为Master路由器。
5、认证方式
VRRP提供了三种认证方式: 无认证:不进行任何VRRP报文的合法性认证,不提供安全性保障。
简单字符认证:在一个有可能受到安全威胁的网络中,可以将认证方式设置为简单字符认证。发送VRRP报文的路由器将认证字填入到VRRP报文中,而收到VRRP报文的路由 器会将收到的VRRP报文中的认证字和本地配置的认证字进行比较。如果认证字相同,则认为接收到的报文是合法的VRRP报文;否则认为接收到的报文是一个非法报文。
MD5认证:在一个非常不安全的网络中,可以将认证方式设置为MD5认证。发送VRRP报文的路由器利用认证字和MD5算法对VRRP报文进行加密,加密后的报文保存在 Authentication Header(认证头)中。收到VRRP报文的路由器会利用认证字解密报文,检查该报文的合法性。
利用多台物理路由器构建为一个虚拟路由器后,在Master不宕机的情况下,如何充分利用Bachup路由器?
假如物理路由器R2优先级较高,那么在R2不宕机的情况下,VIP会始终配置在R2上,此时R1是闲置的。为了避免R1限制,可以在R1上再配置一个VIP1,并且此时R1的VIP1优先级要高于R2的VIP2。因此局域网内部的主机有一半网关指向R1的VIP1,一半指向R2的VIP2,此时就是负载均衡了。此时如果R1故障,那么就把R1的VIP1迁移到R2上,对于Linux主机来讲,一个接口配置多个IP很正常,同样R2故障也可以把R2的VIP2迁移到R1上。这对客户端是透明的,因为VIP和网关都没有改变。
问题是如何将两个VIP对应于各自不同的优先级不一样?做两组虚拟路由设备
对于第一个虚拟路由设备来讲,有R1和R2两个物理路由器组成,其中所需要流动的IP是R1的VIP1,在第一组虚拟路由设备上R1的优先级高于R2。
再配置一个虚拟路由实例进程,依然包含R1和R2两个路由器,这个虚拟路由使用的IP地址是R2上的VIP2,而相对于VIP2来讲,R2的VIP2优先级高于R1的VIP1。这就是两个虚拟路由实例。而且在两个虚拟路由实例上,他们需要用到的调配资源和各自节点(R1和R2)的优先级不一样,从而在R1和R2都正常时,R1配置在VIP1,R2配置在VIP2,所以负载均衡。如果R1故障,原先在虚拟设备1上时优先级高,故障后虚拟路由器1上的R1的优先级降低,此时虚拟路由器1上的R1的优先级就没有虚拟路由器2上的R1的优先级高了。因此R1的VIP1就转到R2上,对于虚拟路由2来讲,本来R2就是Master,即使R1故障,也没什么问题,所以虚拟路由2中R1的VIP1就不再迁移到R2上了。
以上描述就是双主模型的高可用
IP流动:
另外假如是LVS中的NAT模型的话,director主机上是有外网网卡和内网网卡的,此时如果要像上面流动的话,就需要外网网卡和内网网卡同时流动,因为后端的RS的网关是指向director的内网网卡的,而DR模型在director宕机后迁移到其他主机时,只需要流动外网网卡就可以,因为RS的网关不需要指向内网网卡,而是直接发送给客户端。同时nginx方向代理也在同一局域网内也是不需要的,因为向后端服务器发请求的就是nginx代理服务器本身,是全新构建报文,因此后端服务器响应报文是直接相应给nginx服务器的,不是响应给客户端的。但是如果nginx的内网地址与各real server不在同一网段,也不需要流动,因为只要有地址就可以。
在生产环境中,可能需要做IP虚拟地址组。
keepalived功能与作用:解决了ipvs不具备的高可用和健康状态检测的功能。 就是vrrp协议在Linux主机上以守护进程方式的实现;
能够根据配置文件自动生成ipvs规则;
对各RS做健康状态检测;
核心组件: vrrp stack
checkers
ipvs wrapper --> ipvs
外围组件: http://blog.51cto.com/ixdba/1639562
Scheduler - I/O Multiplexer:调度器,keepalived本身也需要实现并发控制
Memory Mngt:实现内存空间管理,keepalived在运行时需要追踪会话保持,健康状态检测等
Control Plane Configuration file Parser:配置文件分析器的主控工具,可以在配置文件发生改变时,可以reload,让配置文件生效,类似于nginx的Master 的主控进程。
core components核心组件:
VRRP Stack:主要是VRRP的实现,其他功能都是辅助性的。Checkers和VRRP Stack各是子进程
Checkers:健康状态检测,可以在TCP层检测、可以基于HTTP协议做检测等。
IPVS wrapper:可以根据配置文件实现IPVS规则。但如果实现keepalived的高可用是nginx而不是LVS,此时IPVS wrapper规则就没有用了,因为不需要
keepalived对后面的upstream做健康状态检测,因为nginx自己可以做,那么此时Checkers也没有作用了,这就只用到了keepalived的VRRP Stack。
Netlink Reflector:实现各种功能包括VRRP Stack功能的一个可以跟内核功能中的Netlink进行交互的一个组件。
WatchDog:内部自我救赎的高可用监控机制,自动监控VRRP进程是否运行正常,如果在监控后发现某个进程没有运行就自动把这个进程启动起来。
配置和使用Keepalived (在centos6.4后被收录到发行版中)
1、安装查看配置信息
# yum info keepalived
# yum install keepalived
# rpm -ql keepalived
/etc/keepalived //主程序
/etc/keepalived/keepalived.conf //主配置文件
/etc/sysconfig/keepalived //服务环境配置文件
/usr/bin/genhash
/usr/lib/systemd/system/keepalived.service //启动服务时依赖的脚本
/usr/libexec/keepalived
/usr/sbin/keepalived
...
# cat /usr/lib/systemd/system/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=syslog.target network-online.target
[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/sysconfig/keepalived //环境配置文件,再启动服务之前会首先载入此文件
ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS //启动服务载入$KEEPALIVED_OPTIONS变量,而此变量是在/etc/sysconfig/keepalived定义的
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
# cat /etc/sysconfig/keepalived
# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp -P Only run with VRRP subsystem.
# --check -C Only run with Health-checker subsystem.
# --dont-release-vrrp -V Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs -I Dont remove IPVS topology on daemon stop.
# --dump-conf -d Dump the configuration data.
# --log-detail -D Detailed log messages.
# --log-facility -S 0-7 Set local syslog facility (default=LOG_DAEMON)
#
KEEPALIVED_OPTIONS="-D"
# cat /etc/keepalived/keepalived.conf
配置文件的组成部分:
- GLOBAL CONFIGURATION 全局配置端
- VRRPD CONFIGURATION VRRP守护进程
- vrrp instance 虚拟路由器实例
- vrrp synchonization group 同步组,即同时配置两个VIP和同步进退时,把他们当作两个虚拟路由器同步进退
- LVS CONFIGURATION
! Configuration File for keepalived global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval
vrrp_gna_interval
} vrrp_instance VI_1 { //配置VRRP实例
state MASTER
interface eth0
virtual_router_id
priority
advert_int
authentication {
auth_type PASS
auth_pass
}
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
} virtual_server 192.168.200.100 { //配置LVS的虚拟服务即为ipvs生成规则,如果是nginx就用不到此功能
delay_loop
lb_algo rr
lb_kind NAT
persistence_timeout
protocol TCP real_server 192.168.201.100 {
weight
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
} virtual_server 10.10.10.2 {
delay_loop
lb_algo rr
lb_kind NAT
persistence_timeout
protocol TCP sorry_server 192.168.200.200 real_server 192.168.200.2 {
weight
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout
nb_get_retry
delay_before_retry
}
} real_server 192.168.200.3 {
weight
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
} virtual_server 10.10.10.3 {
delay_loop
lb_algo rr
lb_kind NAT
persistence_timeout
protocol TCP real_server 192.168.200.4 {
weight
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout
nb_get_retry
delay_before_retry
}
} real_server 192.168.200.5 {
weight
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
}
利用keepalived流动一个VIP,在提供LVS的高可用以及实现对LVS后端的real server做健康状态检测,最后实现高可用nginx
1、Keepalived及VRRP原理介绍的更多相关文章
- keepalived的工作原理
keepalived的工作原理 首先简单介绍一下vrrp协议 vrrp协议 用来实现路由器冗余的协议: Vrrp协议是为了消除在静态缺省路由环境下路由器单点故障引起的网络失效而设计的主备模式的协议,使 ...
- LVS负载均衡IP隧道模式原理介绍以及配置实战
LVS 基本工作原理 当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间 PREROUTING 链首先会接收到用户请求,判断目标 IP 确定是本机 IP,将数 ...
- LVS负载均衡NAT模式原理介绍以及配置实战
LVS基本原理 流程解释: 当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间 PREROUTING 链首先会接收到用户请求,判断目标 IP 确定是本机 IP ...
- 03 Yarn 原理介绍
Yarn 原理介绍 大纲: Hadoop 架构介绍 YARN 产生的背景 YARN 基础架构及原理 Hadoop的1.X架构的介绍 在1.x中的NameNodes只可能有一个,虽然可以通过Se ...
- 04 MapReduce原理介绍
大数据实战(上) # MapReduce原理介绍 大纲: * Mapreduce介绍 * MapReduce2运行原理 * shuffle及排序 定义 * Mapreduce 最早是由googl ...
- Android Animation学习(一) Property Animation原理介绍和API简介
Android Animation学习(一) Property Animation介绍 Android Animation Android framework提供了两种动画系统: property a ...
- [转]MySQL主从复制原理介绍
MySQL主从复制原理介绍 一.复制的原理 MySQL 复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新.删除等等).每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以 ...
- 分布式文件系统FastDFS原理介绍
在生产中我们一般希望文件系统能帮我们解决以下问题,如:1.超大数据存储:2.数据高可用(冗余备份):3.读/写高性能:4.海量数据计算.最好还得支持多平台多语言,支持高并发. 由于单台服务器无法满足以 ...
- 内存分析_.Net内存原理介绍
内存原理介绍 1. .Net应用程序中的内存 1.1.Net内存类型 Windows使用一个系统:虚拟寻址系统.这个系统的作用是将程序可用的内存地址映射到硬件内存中的实际地址上.其实际结果 ...
随机推荐
- Java8函数式编程探秘
引子 将行为作为数据传递 怎样在一行代码里同时计算一个列表的和.最大值.最小值.平均值.元素个数.奇偶分组.指数.排序呢? 答案是思维反转!将行为作为数据传递. 文艺青年的代码如下所示: public ...
- Hive 数仓中常见的日期转换操作
(1)Hive 数仓中一些常用的dt与日期的转换操作 下面总结了自己工作中经常用到的一些日期转换,这类日期转换经常用于报表的时间粒度和统计周期的控制中 日期变换: (1)dt转日期 to_date(f ...
- mybatis源码解析7---MappedStatement初始化过程
上一篇我们了解到了MappedStatement类就是mapper.xml中的一个sql语句,而Configuration初始化的时候会加载所有的mapper接口类,而本篇再分析下是如何将mapper ...
- 大数据自学6-Hue集成环境操作Hbase
上一章讲过,Hue集成环境是可以直接操作Hbase,但是公司的环境一直报错,虽然也可以透过写代码访问Hbase,但是看到Hue环境中无法访问,还是觉得不爽,因此决定再花些力气找找原因. 找原因要先查L ...
- Spring Boot 中使用 @ConfigurationProperties 注解
@ConfigurationProperties 主要作用:绑定 application.properties 中的属性 例如: @Configuration public class DataSou ...
- Django之连接远程mysql数据库
1.创建Django项目(test) 进入配置文件settings.py 192.168.83.129:所需要远程连接数据库的ip地址 2.进入到远程连接的主机,修改/etc/mysql/mysql. ...
- dubbo原理
1,观察DubboBeanDefinitionParser 的构造方法,给它打一个断点,发现其前一步在DubboNamespaceHandler 应用启动会连续调此方法 DubboBeanDefini ...
- Eclipse Luna在线安装Maven时报错:Java heap space
问题描述: 在线安装Maven插件时发生了:Java heap space 问题截图:
- spring框架入门之一
一.什么是Spring框架 1.什么是Spring Spring框架是个一个全栈的框架.意思就是使用Spring的框架可以开发web层,service层还有dao层. 本质:Spring就是一个对象的 ...
- EDK II之驱动程序与硬件平台的初始化简介
本文旨在简单介绍一下UEFI中驱动程序的加载方式(这里涉及的模块指的是符合UEFI Driver Model的模块): 在UEFI中,当一个驱动模块被加载时,在模块入口点只会安装EFI_DRIVER_ ...