作者:陆世亮
序言
etcd发现服务被用于etcd集群的启动,在集群的启动阶段,通过一个共享的发现url,发现服务协议有助于新的成员发现其它的集群成员,并且最终加入到集群中去。与etcd发现服务功能类似的还有dns发现服务,本文仅仅介绍etcd发现服务。
etcd发现服务协议仅仅只在集群的启动阶段使用,并且不能用于运行时配置重载或者集群监控。
该协议使用一个全新的发现令牌来启动一个单独的集群。需要明确的是,一个发现令牌只能代表一个etcd集群。只要基于该令牌的发现服务协议启动了,即使中途失效,也不能将该令牌用于其它集群的启动。
下文将通过例子来演示发现的流程,这些例子使用的是自己搭建的etcd发现集群。作为一项公共的etcd发现服务,discovery.etcd.io的流程也是一样的,但是多了一层过滤,以清除非法的url,自动生成 UUID,并且提供请求的过载保护。其核心机制正如白皮书中描述的一样,也是使用etcd集群来进行数据存储。
1.协议流程
etcd发现服务的理念是使用一个内部的etcd集群来协助新集群的启动。首先,所有的新成员与发现服务进行交互,以获取到期望的成员列表,接着每个成员使用该列表来启动etcd服务,这个流程和使用-initial-cluster标识的内部流程是一致的。
在下面的流程案例中,为了便于理解,本文以curl命令来演示协议的每个步骤。
按照约定,etcd的发现服务使用键名前缀_etcd/registry。如果位于http://example.com的主机运行着用于服务发现的etcd集群,对应于发现秘钥空间的完整url是http://example.com/v2/keys/_etcd/registry。在这个例子中,本文将使用这个url前缀。
1.1 生成一个新的发现令牌
生成一个独特的令牌,用于标识新的集群。在接下来的步骤中,该令牌在发现秘钥空间将作为一个独特的前缀。一个简单的方法是使用uuidgen环境变量作为令牌:
UUID=$(uuidgen)
1.2 指定预期的集群大小
用户需要为该令牌指定期望的集群大小。发现服务使用该大小值来判断集群的初始化成员是否都已经到位。
curl -X PUT http://example.com/v2/keys/_etcd/registry/${UUID}/_config/size -d value=${cluster_size}
通常集群的大小是3,5或者7。
1.3 启动etcd集群
在已知发现url的基础上,用户可以将其用于指定-discovery标识,并且启动etcd进程。如果指定了-discovery标识,每一个etcd进程都将遵循下面的几步操作。
1.4 自我注册
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}"
1.5 检查状态
发现服务会检查发现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个成员视为集群的成员。如果成员本身就在成员列表中,发现流程会成功执行,并且从成员列表中获取所有的对端url。如果成员不在成员列表中,发现服务会返回失败,告知集群已经满员。
在etcd的实现中,成员在注册自己之前可能会检查集群的状态。所以如果集群满员了,那么该成员的注册会很快失败。
1.6 等待所有成员出现
curl -X GET http://example.com/v2/keys/_etcd/registry/${UUID}?wait=true&waitIndex=${current_etcd_index}
该命令会一直等待,直到发现所有成员。
2. 公共发现服务
CoreOS Inc.在https://discovery.etcd.io/提供了一项公共的发现服务,该服务提供了一些易于使用的新特性。
2.1 掩盖键名前缀
公共服务会将请求https://discovery.etcd.io/${UUID}导向背后真正的集群,该集群的实际url位于/v2/keys/_etcd/registry。公共服务掩盖了注册的键名前缀,暴露给用户的是简洁的发现url。
2.2 获取新令牌
GET /new
http的query请求部分如下:
size=${cluster_size}
可能的响应如下:
200 OK
400 Bad Request
200状态码的实体数据部分包含:
最新生成的发现url
2.3 检查发现状态
GET /${UUID}
通过请求该UUID的值,用户可以检查该令牌的状态,包括哪些机器已经注册到该令牌。
2.4 开源仓库
该仓库位于https://github.com/coreos/discovery.etcd.io。用户可以使用它来部署自己的etcd发现服务。
小结
本文通过具体的操作流程与方法,对etcd的发现服务进行了介绍。
参考文献
ETCD v2参考手册中文版v0.1 陆世亮,陈永刚,赖东林 2016.8.19
本文来自网易实践者社区,经作者陆世亮权发布