发现服务协议

在集群引导阶段发现其他 etcd 成员

发现服务协议通过一个共享的发现 URL,帮助新的 etcd 成员在集群引导阶段发现集群中的所有其他成员。

发现服务协议在集群引导阶段使用,不能用于运行时重新配置或集群监控。

该协议使用一个新的发现令牌来引导一个唯一的 etcd 集群。请记住,一个发现令牌只能代表一个 etcd 集群。一旦在此令牌上启动了发现协议,即使中途失败,也不得再用于引导另一个 etcd 集群。

本文其余部分将通过与自托管发现集群相对应的示例,逐步介绍发现过程。公共发现服务 discovery.etcd.io 的工作方式相同,但提供了更友好的界面,隐藏了复杂的 URL,自动生 UUID,并对过多请求提供一定的防护。本质上,公共发现服务仍然使用 etcd 集群作为数据存储,正如本文档所述。

协议工作流程

发现协议的核心思想是使用一个内部的 etcd 集群来协调新集群的引导。首先,所有新成员与发现服务交互,协助生成预期的成员列表。然后每个新成员使用此列表引导其服务器,其功能与 -initial-cluster 标志相同。

在以下示例流程中,我们将以 curl 格式列出协议的每一步,以便于理解。

按照惯例,etcd 发现协议使用键前缀 _etcd/registry。如果 http://example.com 托管了一个用于发现服务的 etcd 集群,则访问发现键空间的完整 URL 将为 http://example.com/v2/keys/_etcd/registry。我们将在示例中使用此 URL 作为前缀。

创建一个新的发现令牌

生成一个唯一令牌,用于标识新集群。这将在后续步骤中用作发现键空间中的唯一前缀。一种简单的方法是使用 uuidgen

UUID=$(uuidgen)

指定预期的集群大小

发现令牌需要指定一个预期的集群大小。发现服务使用该大小来判断是否已找到所有将初始组成集群的成员。

curl -X PUT http://example.com/v2/keys/_etcd/registry/${UUID}/_config/size -d value=${cluster_size}

通常集群大小为 3、5 或 7。更多详细信息请参阅最佳集群大小

启动 etcd 进程

给定发现 URL 后,可将其用作 -discovery 参数来启动 etcd 进程。每个 etcd 进程在指定 -discovery 参数时,都会在内部执行接下来的几个步骤。

注册自身

etcd 进程的第一步是将自身注册为发现 URL 中的一个成员。这通过在发现 URL 下创建一个以成员 ID 为名称的键来实现。

curl -X PUT http://example.com/v2/keys/_etcd/registry/${UUID}/${member_id}?prevExist=false -d value="${member_name}=${member_peer_url_1}&${member_name}=${member_peer_url_2}"

检查状态

它会检查发现 URL 中预期的集群大小和注册状态,并决定下一步操作。

curl -X GET http://example.com/v2/keys/_etcd/registry/${UUID}/_config/size
curl -X GET http://example.com/v2/keys/_etcd/registry/${UUID}

如果已注册的成员数量仍不足,它将等待剩余成员出现。

如果已注册成员的数量超过预期大小 N,则将前 N 个注册成员视为该集群的成员列表。如果当前成员在该列表中,则发现过程成功,它将通过成员列表获取所有对等节点信息;如果不在列表中,则发现过程失败,表示集群已满。

在 etcd 的实现中,成员可能在注册自身之前就检查集群状态,因此若集群已满,它可以快速失败。

等待所有成员

等待过程在etcd API 文档中有详细说明。

curl -X GET http://example.com/v2/keys/_etcd/registry/${UUID}?wait=true&waitIndex=${current_etcd_index}

它将持续等待,直到找到所有成员。

公共发现服务

CoreOS 公司在 https://discovery.etcd.io/ 上托管了一个公共发现服务,提供了一些便于使用的功能。

掩码密钥前缀

公共发现服务会将 https://discovery.etcd.io/${UUID} 重定向到后端的 etcd 集群,对应键位于 /v2/keys/_etcd/registry。它通过较短且易读的发现 URL 掩盖了实际的注册键前缀。

获取新令牌

GET /new

Sent query:
	size=${cluster_size}
Possible status codes:
	200 OK
	400 Bad Request
200 Body:
	generated discovery url

该服务中的生成流程包括从创建新发现令牌指定预期集群大小的各个步骤。

检查发现状态

GET /${UUID}

可以通过请求 UUID 的值来查看此发现令牌的状态,包括已注册的机器。

开源仓库

该仓库位于 https://github.com/coreos/discovery.etcd.io,可用于构建自定义的发现服务。


最后更新于 2025 年 6 月 3 日:递归地将 v3.6 的内容复制到 v3.7(a90b2a6)