32.10.共用地址冗余协议(CARP)

共用地址冗余协议 (CARP) 允许多个主机共享相同的 IP 地址和虚拟主机 ID (VHID),以便为一个或多个服务提供 高可用性。这意味着一个或多个主机可能会发生故障,而其他主机将透明地接管,以便用户不会看到服务故障。

除了共享 IP 地址之外,每个主机都有自己的 IP 地址用于管理和配置。共享 IP 地址的所有计算机都具有相同的 VHID。每个虚拟 IP 地址的 VHID 在网络接口的广播域中必须是唯一的。

使用 CARP 的高可用性是内置于 FreeBSD 中的,尽管配置它的步骤因 FreeBSD 版本的不同而略有不同。本节为 FreeBSD 10 之前和之后的版本提供相同的示例配置。

这个例子配置了三个主机的故障转移支持,它们都有独特的 IP 地址,但提供相同的网络内容。它有两个不同的主机,名为 hosta.example.orghostb.example.org,有一个共享备份,名为 hostc.example.org

这些计算机使用轮循机制 DNS 配置进行负载平衡。主计算机和备份计算机的配置相同,但其主机名和管理 IP 地址除外。这些服务器必须具有相同的配置并运行相同的服务。发生故障转移时,仅当备份服务器有权访问相同的内容时,才能正确应答对共享 IP 地址上的服务的请求。备份计算机有两个附加的 CARP 接口,每个接口对应于主内容服务器的 IP 地址。发生故障时,备份服务器将拾取故障主计算机的 IP 地址。

32.10.1. 在 FreeBSD 10 及更高版本上使用 CARP

通过在 /boot/loader.conf 中添加 carp.ko 内核模块的条目来启用对 CARP 的引导时支持:

  1. carp_load="YES"

要立即加载模块而不重新启动:

  1. # kldload carp

对于喜欢使用自定义内核的用户,在自定义内核配置文件中包含以下行,并按照配置 FreeBSD 内核中所述编译内核:

  1. device carp

主机名、管理 IP 地址和子网掩码、共享 IP 地址和 VHID 都是通过向 /etc/rc.conf 添加条目来设置的。此示例适用于 hosta.example.org

  1. hostname="hosta.example.org"
  2. ifconfig_em0="inet 192.168.1.3 netmask 255.255.255.0"
  3. ifconfig_em0_alias0="inet vhid 1 pass testpass alias 192.168.1.50/32"

下一组条目适用于 hostb.example.org。由于它表示第二个主服务器,因此它使用不同的共享 IP 地址和 VHID。但是,然而,与 pass 一起指定的密码必须是相同的,因为 CARP 只会监听和接受来自具有正确密码的机器的广告。

  1. hostname="hostb.example.org"
  2. ifconfig_em0="inet 192.168.1.4 netmask 255.255.255.0"
  3. ifconfig_em0_alias0="inet vhid 2 pass testpass alias 192.168.1.51/32"

第三台机器,hostc.example.org,被配置为处理来自任一主站的故障切换。这台机器配置了两个 CARPVHID,一个用于处理每个主控主机的虚拟 IP 地址。设置CARP通告 skew (advskew) 是为了确保备份主机的通告时间晚于主主机,因为当有多个备份服务器时,advskew 控制优先级的顺序。

  1. hostname="hostc.example.org"
  2. ifconfig_em0="inet 192.168.1.5 netmask 255.255.255.0"
  3. ifconfig_em0_alias0="inet vhid 1 advskew 100 pass testpass alias 192.168.1.50/32"
  4. ifconfig_em0_alias1="inet vhid 2 advskew 100 pass testpass alias 192.168.1.51/32"

配置了两个 CARPVHID 意味着如果任何一个主服务器变得不可用,hostc.example.org 将注意到。如果主服务器不能在备份服务器之前发布广告,备份服务器将获得共享的 IP 地址,直到主服务器再次变得可用。

注意
如果原来的主服务器再次可用,hostc.example.org 将不会自动释放虚拟 IP 地址给它。要做到这一点,必须启用抢占功能。该功能默认是禁用的,它通过 sysctl(8) 变量 net.inet.carp.preempt 来控制。管理员可以强制备份服务器将 IP 地址返回给主服务器。
# ifconfig em0 vhid 1 state backup

配置完成后,重新启动网络或重新启动每个系统。现已启用高可用性。

CARP 功能可以通过 carp(4) 手册页中记录的多个 sysctl(8)变量进行控制。其他操作可以通过使用 devd(8) 从 CARP 事件触发。

32.10.2. 在 FreeBSD 9 及更早版本上使用 CARP

这些版本的 FreeBSD 的配置与上一节中描述的配置类似,不同之处在于必须首先在配置中创建和引用 CARP 设备。

通过在 /boot/loader.conf 中加载 if_carp.ko 内核模块来启用对 CARP 的引导时支持:

  1. if_carp_load="YES"

要立即加载模块而不重新启动:

  1. # kldload carp

对于喜欢使用自定义内核的用户,在自定义内核配置文件中包含以下行,并按照 配置 FreeBSD 内核 中所述编译内核:

  1. device carp

接下来,在每个主机上,创建一个 CARP 设备:

  1. # ifconfig carp0 create

通过在 /etc/rc.conf 中添加必要的行来设置主机名、管理 IP 地址、共享 IP 地址和 VHID。由于使用的是虚拟 CARP 设备而不是别名,实际的子网掩码是 /24 而不是 /32。下面是 hosta.example.org 的条目。

  1. hostname="hosta.example.org"
  2. ifconfig_fxp0="inet 192.168.1.3 netmask 255.255.255.0"
  3. cloned_interfaces="carp0"
  4. ifconfig_carp0="vhid 1 pass testpass 192.168.1.50/24"

hostb.example.org

  1. hostname="hostb.example.org"
  2. ifconfig_fxp0="inet 192.168.1.4 netmask 255.255.255.0"
  3. cloned_interfaces="carp0"
  4. ifconfig_carp0="vhid 2 pass testpass 192.168.1.51/24"

第三台计算机 hostc.example.org 配置为处理来自任一主主机的故障转移:

  1. hostname="hostc.example.org"
  2. ifconfig_fxp0="inet 192.168.1.5 netmask 255.255.255.0"
  3. cloned_interfaces="carp0 carp1"
  4. ifconfig_carp0="vhid 1 advskew 100 pass testpass 192.168.1.50/24"
  5. ifconfig_carp1="vhid 2 advskew 100 pass testpass 192.168.1.51/24"
注意
在 GENERIC FreeBSD 内核中,抢占被禁用。如果在自定义内核中启用了抢占功能,hostc.example.org 可能不会将 IP 地址放回给原始内容服务器。管理员可以用命令强制备份服务器将 IP 地址返回给主服务器。
# ifconfig carp0 down && ifconfig carp0 up
这应该在对应于正确主机的 carp 接口上进行。

配置完成后,重新启动网络或重新启动每个系统。现已启用高可用性。