> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/handbook/di-35-zhang-gao-ji-wang-luo/35.11.-gong-yong-di-zhi-rong-yu-xie-yi-carp.md).

# 35.11.共用地址冗余协议（CARP）

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

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

使用 CARP 的高可用性内置于 FreeBSD 中，但配置步骤因 FreeBSD 版本而略有不同。本节提供 FreeBSD 10 之前以及 10 及之后版本的相同示例配置。

此示例为三台主机配置故障转移支持，所有主机都有唯一的 IP 地址，但提供相同的 Web 内容。它有两个不同的主节点，名为 `hosta.example.org` 和 `hostb.example.org`，以及一个共享备份 `hostc.example.org`。

这些机器通过 Round Robin DNS 配置实现负载均衡。主节点和备份机器的配置相同，只是主机名和管理 IP 地址不同。这些服务器必须具有相同的配置并运行相同的服务。当发生故障转移时，只有在备份服务器可以访问相同内容的情况下，才能正确响应共享 IP 地址上服务的请求。备份机器有两个额外的 CARP 接口，分别用于每个主节点内容服务器的 IP 地址。发生故障时，备份服务器将接管故障主节点机器的 IP 地址。

## 35.11.1. 使用 CARP

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

```sh
carp_load="YES"
```

要在不重启的情况下加载模块：

```sh
# kldload carp
```

对于偏好使用定制内核的用户，在定制内核配置文件中包含以下行，并按 [配置 FreeBSD 内核](/handbook/di-10-zhang-pei-zhi-freebsd-nei-he/10.1.-gai-shu.md) 中的说明编译内核：

```sh
device	carp
```

通过向 **/etc/rc.conf** 中添加条目来设置主机名、管理 IP 地址和子网掩码、共享 IP 地址以及 VHID。以下是 `hosta.example.org` 的示例：

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

下一组条目用于 `hostb.example.org`。由于它代表第二个主节点，因此使用不同的共享 IP 地址和 VHID。但是，使用 `pass` 指定的密码必须相同，因为 CARP 只会监听和接受来自具有正确密码的机器的通告。

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

第三台机器 `hostc.example.org` 配置为从任意主节点处理故障转移。该机器配置了两个 CARP VHIDs，每个用于处理一个主节点主机的虚拟 IP 地址。CARP 通告偏斜（`advskew`）设置为确保备份主机的通告比主节点稍后发出，因为 `advskew` 控制了当存在多个备份服务器时的优先级顺序。

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

配置两个 CARP VHIDs 后，`hostc.example.org` 将监控两个主节点的状态。如果主节点未能在备份服务器之前发送通告，备份服务器将接管共享 IP 地址，直到主节点重新可用。

> **注意**
>
> 如果原主节点重新上线，`hostc.example.org` 不会自动将虚拟 IP 地址归还给它。为实现这一点，必须启用抢占功能。该功能默认禁用，可以通过 [sysctl(8)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=8\&format=html) 变量 `net.inet.carp.preempt` 来控制。管理员可以强制备份服务器将 IP 地址归还给主节点：
>
> ```sh
> # ifconfig em0 vhid 1 state backup
> ```

完成配置后，可以重启网络服务或重启每台系统。高可用性现已启用。

CARP 功能可以通过多种 [sysctl(8)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=8\&format=html) 变量控制，详细信息请参阅 [carp(4)](https://man.freebsd.org/cgi/man.cgi?query=carp\&sektion=4\&format=html) 手册页。其他操作可以通过使用 [devd(8)](https://man.freebsd.org/cgi/man.cgi?query=devd\&sektion=8\&format=html) 从 CARP 事件触发。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/handbook/di-35-zhang-gao-ji-wang-luo/35.11.-gong-yong-di-zhi-rong-yu-xie-yi-carp.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
