Etcd集群简介
随着CoreOS和Kubernetes等项目在开源社区日益火热,它们项目中都用到的etcd组件作为一个高可用强一致性的服务发现存储仓库,渐渐为开发人员所关注。在云计算时代,如何让服务快速透明地接入到计算集群中,如何让共享配置信息快速被集群中的所有机器发现,更为重要的是,如何构建这样一套高可用、安全、易于部署以及响应快速的服务集群,已经成为了迫切需要解决的问题,etcd为解决这类问题带来了福音。
我们此次在三个主机上搭建了一个包含三个Etcd节点的集群,实现了集群的动态扩展和收缩,并测试和验证了Etcd集群键——值存储的一致性和高可用性。本文主要参考了:https://github.com/coreos/etcd/blob/release-2.3/Documentation/docker_guide.md
拉取镜像ectd
从 https://quay.io/
获取etcd最新版本的镜像,本次拉取的是v2.3.7版本。首先拉取到本地:
1 | docker pull quay.io/coreos/etcd |
再给这个镜像打上 tag,并推送到 sofacloud 仓库
1 | docker tag quay.io/coreos/etcd:latest registry.abc.com/liuchang31/etcd:v2.3.7 |
搭建Etcd集群
这里采用的是DNS发现方式搭建的集群,也就是要求集群中的每台主机都可以做DNS的主机名到IP的查询。
我们选取的三台主机分别为:
1 | inf-platform55 |
在主机 inf-platform55 上新建一个 start.sh 文件,内容如下:
1 | docker run -d -v /home/work/docker/liuchang/etcd/ca-certificates/:/etc/ssl/certs \ |
对其他的两台主机 inf-platform56
,inf-platform57
进行相似的操作,注意要把 -name
、-advertise-client-urls
和 -initial-advertise-peer-urls
分别改成对于主机的主机名。
注意事项
docker 的运行参数中一定要包含 –data-dir 参数,并且将 -data-dir指定的文件夹挂载了本机的一个目录下保存。否则当一个etcd挂了之后,如果再重新启动它,将不能重新加入到之前的集群中了。
启动这个集群
将三个主机上的etcd节点关联起来,搭建成一个集群,它们保持全局的key/value存储一致性,在任意三个主机的任意一个上输入:
1 | etcdctl -C http://inf-platform55:2379, http://inf-platform56:2379, http://inf-platform57:2379 member list |
高可用的测试过程
这时候我们在 etcd 集群中的任意一台主机上输入:
1 | etcdctl member list |
可以看到集群的节点情况,并能看出哪个是leader节点。如下图所示:
我们先在 inf-platform55 机子上设置一个key/value,如下所示:
我们可以在 inf-platform56、inf-platform57 主机上获取这个key/value,如下所示:
从 etcdctl member list
的结果可以看到 inf-platform55 这台机子是leader。这时候我们将这台机器上的etcd镜像停掉。即在这台机子上输入:
1 | docker stop e83ef052029e (这是etcd镜像的id) |
然后登录到 inf-platform56 机器上,输入
1 | etcdctl cluster-health |
如图所示:
这时我们在 inf-platform56、inf-platform57 增加2个key/value存储:
1 | etcdctl set master http://inf-platform53 |
这时候因为 inf-platform55 已经挂掉,所以该机子上没有这2个key/value存储。过一段时间我们登陆 inf-platform55
这台机器重新运行 etcd 这个镜像,并查看这些 key/value
在这台机子挂掉的期间,新增的 key/value 仍然可以实现同步,这期间虽然发生了 leader 的选举变更,但保持了 key/value 的全局一致性,由此可见 etcd 搭建的集群是可以实现高可用的。
Etcd集群的扩展与收缩
etcd集群如果收缩很简单,直接在命令行输入
1 | etcdctl member remove ${memberID} |
$memberID 是你即将要删除节点的etcd的ID,etcd的扩展有一些地方需要注意一下,我在这里操作的时候遇到了不少坑。从上文写到现在,有一个文件夹很重要,几乎每个坑都与它有关,那就是-data-dir所声明的文件夹,注意要扩展一个etcd集群时,首先在集群内的任一台机器上输入
1 | etcdctl member add $etcd_name $peer_url |
- $etcd_name:新加入的etcd节点的名字
- $peer_url:一般为新加入的节点 IP:2380
这时候如果输入
1 | etcdctl member list |
会出现
这时候登陆到待加入集群的那个节点上,启动这个etcd服务器。有几点需要注意的是:首先是把本机的data-dir文件夹删掉,然后是start.sh如下
1 | docker run -d -v /home/work/docker/liuchang/etcd/ca-certificates/:/etc/ssl/certs \ |
把-initial-cluster-state 声明为existing,-initial-cluster-token要与之前的集群相同,并且在-initial-cluster中加入新的节点的IP:2380。如果启动失败多半是-data-dir文件的问题,将它删掉即可。