本章主要介绍 etcd 集群的搭建方式。

介绍

上文我们简单介绍了 etcd 的基本概念和使用场景,本文就来介绍如何搭建 etcd 集群。在生产环境中,为了整个集群的高可用,etcd 正常都会以集群方式部署,避免单点故障。引导 etcd 集群的启动有以下三种机制:

静态启动 etcd 集群要求每个成员都知道集群中的另一个成员。 在许多情况下,群集成员的 IP 可能未知,在这些情况下,可以在发现服务的帮助下引导 etcd 集群。

可以使用官方提供的工具来生成 etcd 集群的配置: http://play.etcd.io/install

这里我们将主要介绍静态方式启动 etcd 集群。

安装

由于 etcd 是基于 raft 分布式协议的集群,所以如果要组成一个集群,集群的数量需要奇数台。如果只有一个节点的话我们也可以通过不同的端口来进行模拟,比如这里我们在一台机器上来安装一个3节点的 etcd 伪集群,对应的配置如下所示:

这里我们在一台 CentOS7 系统的节点上来进行演示,首先下载 etcd 二进制包,直接从 github release 页面下载对应的包即可:

$ wget <https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz>
$ tar -xvf etcd-v3.4.13-linux-amd64.tar.gz
$ mkdir /tmp/etcd 
$ mv etcd-v3.4.13-linux-amd64/etcd /tmp/etcd/
$ mv etcd-v3.4.13-linux-amd64/etcdctl /tmp/etcd

etcd 安装完成后,启动3个不同的终端分别执行下面的3个命令来启动 etcd 集群:

# 确保 etcd 进程对数据目录具有写访问权
# 如果集群是新集群,则删除该目录;如果重新启动则保留该目录

# 启动第一个节点
$ /tmp/etcd/etcd --name s1 \\  # etcd 节点名称
  --data-dir /tmp/etcd/s1 \\  # 数据存储目录 
  --listen-client-urls <http://localhost:2379> \\  # 本节点访问地址
  --advertise-client-urls <http://localhost:2379> \\  # 用于通知其他 ETCD 节点,客户端接入本节点的监听地址
  --listen-peer-urls <http://localhost:2380> \\  # 本节点与其他节点进行数据交换的监听地址
  --initial-advertise-peer-urls <http://localhost:2380> \\  # 通知其他节点与本节点进行数据交换的地址
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \\  # 集群所有节点配置
  --initial-cluster-token tkn \\  # 集群唯一标识
  --initial-cluster-state new  # 节点初始化方式

# 启动第二个节点
$ /tmp/etcd/etcd --name s2 \\
  --data-dir /tmp/etcd/s2 \\
  --listen-client-urls <http://localhost:22379> \\
  --advertise-client-urls <http://localhost:22379> \\
  --listen-peer-urls <http://localhost:22380> \\
  --initial-advertise-peer-urls <http://localhost:22380> \\
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \\
  --initial-cluster-token tkn \\
  --initial-cluster-state new

# 启动第三个节点
$ /tmp/etcd/etcd --name s3 \\
  --data-dir /tmp/etcd/s3 \\
  --listen-client-urls <http://localhost:32379> \\
  --advertise-client-urls <http://localhost:32379> \\
  --listen-peer-urls <http://localhost:32380> \\
  --initial-advertise-peer-urls <http://localhost:32380> \\
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \\
  --initial-cluster-token tkn \\
  --initial-cluster-state new

正常启动完成后,我们可以使用 etcdctl 命令来查看集群的状态:

$ ETCDCTL_API=3 /tmp/etcd/etcdctl \\
  --endpoints localhost:2379,localhost:22379,localhost:32379 \\
  endpoint health
localhost:2379 is healthy: successfully committed proposal: took = 14.22105ms
localhost:22379 is healthy: successfully committed proposal: took = 13.058173ms
localhost:32379 is healthy: successfully committed proposal: took = 16.497453ms
$ ETCDCTL_API=3 /tmp/etcd/etcdctl \\
  --endpoints localhost:2379,localhost:22379,localhost:32379 \\ 
  endpoint status --write-out=table
+-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT     |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|  localhost:2379 | 7339c4e5e833c029 |  3.4.13 |   20 kB |      true |      false |        43 |          9 |                  9 |        |
| localhost:22379 | 729934363faa4a24 |  3.4.13 |   20 kB |     false |      false |        43 |          9 |                  9 |        |
| localhost:32379 |  b548c2511513015 |  3.4.13 |   20 kB |     false |      false |        43 |          9 |                  9 |        |
+-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

正常可以看到3个 etcd 节点都运行成功了,也可以查看当前集群的 LEADER 节点。如果这个时候我们把 2379 端口的进程杀掉,再来查看集群的状态: