搭建 ETCD 动态发现服务

搭建 ETCD 动态发现服务

最近考虑将原来的单体服务拆解成微服务,需要用到分布式存储,第一个想到的就是 ETCD,毕竟 Kubernetes 等大型开源项目都用它。

搭建 ETCD 集群遇到的问题

根据 ETCD 官方文档介绍,集群的发现大致分为两种,一种是静态发现,也就是在创建集群前需要明确固定集群节点的 IP 或 Host,但这种方式在云原生中是不可取的。

所以我接着研究动态发现这种方式,这种方式需要一个 ETCD 集群或单个节点,来保存发现令牌和集群大小。看到这里你也许会跟我一样觉得这是一个鸡生蛋蛋生鸡的问题,不要着急,CoreOS Inc.提供了一个公共的 Discovery 服务: https://discovery.etcd.io/。同时该服务也已经在 GitHub 上开源了,项目地址:https://github.com/coreos/discovery.etcd.io。

但是 CoreOS Inc. 的这个项目已经打包不维护了,在 ETCD 的项目中有个 https://github.com/etcd-io/discoveryserver。 这个提供了自己构建 Docker 镜像的方法。

准备工作

Discovery Server 是需要一个已存在的 ETCD 集群或单节点来存储发现令牌的,所以我们需要先起一个单节点的 ETCD 容器,这里我用的是 bitnami/etcd:3.5.1 这个镜像。

创建网络

1
docker create network services

启动 ETCD 容器

1
2
3
4
5
6
7
docker run -d --name etcd \
--network services \
-p 2379:2379 \
-p 2380:2380 \
--env ALLOW_NONE_AUTHENTICATION=yes \
--env ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379 \
bitnami/etcd:3.5.1

启动 Discovery Server

1
2
3
4
5
6
7
docker run -d --name discovery \
--network services \
-p 8087:8087 \
-e DISC_ADDR=:8087 \
-e DISC_HOST=http://localhost:8087 \
-e DISC_ETCD=http://etcd:2379 \
betterde/discovery:latest

配置说明

  • DISC_ADDR: 服务启动后监听的地址和端口,如果不指定 IP 则可以是 :8087
  • DISC_HOST: 定义服务所处理的 URL,这里我理解的是像 Nginx 的 server_name 一样。
  • DISC_ETCD: 定义 ETCD 服务的 URL

我这里用的是我自己基于 https://github.com/etcd-io/discoveryserver 这个项目构建的景象,当然你也可以直接使用 betterde/discovery,它是完全公开的。

获取发现令牌

1
2
3
4
curl -X PUT localhost:8087/new?size=3

# 如下所示的到一个带有发现令牌的 Token
http://localhost:8087/5c689d7b17d78fd0bd5de1791fa58734

这里的 size=3 是设置集群节点数量的,如果不设置默认则为 3。

这时候我们看一下 ETCD 里发生了什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
ETCDCTL_API=3 etcdctl --endpoints http://localhost:2379 get / --prefix

# 下面是我请求获取发现令牌后,Discovery Server 在 ETCD 中创建的 Key/Value

/discovery.etcd.io/registry/001/k//5c689d7b17d78fd0bd5de1791fa58734/

/discovery.etcd.io/registry/002/k//5c689d7b17d78fd0bd5de1791fa58734/_config/

/discovery.etcd.io/registry/003/k//5c689d7b17d78fd0bd5de1791fa58734/_config/size
5
/discovery.etcd.io/registry/act
create
/discoverygc/2021-11-20T09:09:48Z/5c689d7b17d78fd0bd5de1791fa58734

可以看到 Discovery Server 已经正确的向 ETCD 里写入了发现令牌等相关数据。

这里我发现一个问题,就是 ETCD 官方文档说:

By convention the etcd discovery protocol uses the key prefix _etcd/registry. If http://example.com hosts an etcd cluster for discovery service, a full URL to discovery keyspace will be http://example.com/v2/keys/_etcd/registry. We will use this as the URL prefix in the example.

但是从 ETCD 存储的结果上来看,Key 有点出入,目前猜测可能是因为版本迭代,文档没有更新。如果有知道的大佬可以指正。

好了,关于 Discovery Server 的内容就到这里了。下一期,继续更新 ETCD 集群的部署遇到的坑。

评论