etcd 集群运维

etcd 简介

etcd 是一个开源的、分布式的键值存储数据库,用于存储配置数据、服务注册和发现等。etcd 具有高可用性、强一致性和简单易用的特点,被广泛应用于各种分布式系统中。

etcd 基于 Raft 协议,通过复制日志文件的方式来保证数据的强一致性。

历史和发展

“etcd” 源于两个方面,unix 的“/etc”文件夹和分布式系统 (“D”istribute system) 的 D,组合在一起表示 etcd 是用于存储分布式配置的信息存储服务。

etcd 由 CoreOS 团队于 2013 年发起,最初是为了解决 Kubernetes 集群中配置数据存储和管理的问题。

etcd 的发展历程如下:

  • 2013 年 8 月: v0.1 版本实现了简单的 HTTP Get/Set/Delete/Watch API,但读数据一致性无法保证
  • 2013 年 12月: v0.2 版本,支持通过指定 consistent 模式,从 Leader 读取数据,并将 Test And Set 机制修正为 CAS(Compare And Swap),解决原子更新的问题,同时发布了新的 API 版本 v2
  • 2014 年 2 月: v0.3 版本,支持 Discovery API,Compare And Delete
  • 2014 年 6 月: Kubernetes v0.4 版本发布,使用 etcd v0.2
  • 2015 年 1 月: v2.0稳定版本, Raft 网络模块、存储抽象、插件化,支持 Quorum Read
  • 2015 年 7 月: Kubernetes v1.0.1 版本发布,第一个生产可用版本,使用 etcd v2.0。发布 v2.1,实现授权和鉴权 API
  • 2015 年 9 月: 改进client库,提升错误处理等能力
  • 2017 年 1 月: 发布 3.1版本,提供了一套全新的API,同时提供了gRPC接口,通过gRPC的proxy扩展并极大地提高ETCD的读取性能,支持每秒超过10000次的写入
  • 2018 年 11月: 项目进入CNCF的孵化项目
  • 2019 年 8 月: 发布 v3.4版本,该版本由Google、Alibaba等公司联合打造,进一步改进etcd的性能及稳定性
  • 2021 年 7 月: 发布 v3.5版本,支持Go Module版本号语义及模块化,提升了性能及稳定性,增强了集群运维能力

搭建 etcd 集群

这部分的手册是对官方文档的翻译,基于 v3.5 版本,更多内容可以参考官方的文档

概述

静态启动 etcd 集群需要每个成员都知道彼此的地址。然而,在很多情况下,成员的 IP 地址可能无法提前确定。这时,我们可以借助发现服务来引导 etcd 集群启动。

etcd 集群启动并运行后,可以通过运行时重新配置来添加或删除成员。

在接下的操作中,我们将创建一个三成员的集群

Name Address Hostname
infra0 10.0.1.10 infra0.example.com
infra1 10.0.1.11 infra1.example.com
infra2 10.0.1.12 infra2.example.com

静态启动

由于我们事先知道集群成员、它们的地址和集群大小,所以可以使用离线引导配置,通过设置 initial-cluster 标志来实现。每台机器将获得以下环境变量或命令行参数:

1
2
ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380"
ETCD_INITIAL_CLUSTER_STATE=new
1
2
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \
--initial-cluster-state new

请注意,initial-cluster 中指定的 URL 是用于通告的对等 URL,它们必须与相应节点上的 initial-advertise-peer-urls 值匹配。

如果出于测试目的使用相同配置启动多个集群(或创建和销毁单个集群),强烈建议为每个集群指定一个唯一的 initial-cluster-token 这样做可以使 etcd 为集群生成唯一的集群 ID 和成员 ID,即使它们具有完全相同的配置。这可以保护 etcd 免受跨集群交互的影响,而跨集群交互可能会损坏集群。

etcd 监听 listen-client-urls 以接受客户端流量。etcd 成员会将 advertise-client-urls 中指定的 URL 通告给其他成员、代理和客户端。请确保目标客户端可以访问 advertise-client-urls一个常见的错误是将 advertise-client-urls 设置为 localhost 或者将其保留为默认值,而这会导致远程客户端无法访问 etcd

在每一台机器上,通过下面的命令行参数来启动 etcd

1
2
3
4
5
6
7
$ etcd --name infra0 --initial-advertise-peer-urls http://10.0.1.10:2380 \
--listen-peer-urls http://10.0.1.10:2380 \
--listen-client-urls http://10.0.1.10:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://10.0.1.10:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \
--initial-cluster-state new
1
2
3
4
5
6
7
$ etcd --name infra1 --initial-advertise-peer-urls http://10.0.1.11:2380 \
--listen-peer-urls http://10.0.1.11:2380 \
--listen-client-urls http://10.0.1.11:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://10.0.1.11:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \
--initial-cluster-state new
1
2
3
4
5
6
7
$ etcd --name infra2 --initial-advertise-peer-urls http://10.0.1.12:2380 \
--listen-peer-urls http://10.0.1.12:2380 \
--listen-client-urls http://10.0.1.12:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://10.0.1.12:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \
--initial-cluster-state new

对于 etcd 后续运行,以 --initial-cluster 开头的命令行参数将被忽略。完成初始引导过程后,可以随时移除相关环境变量或命令行标志。如果之后需要变更配置(例如添加或移除集群成员),请参考运行时配置指南。


etcd 集群运维
https://blog.zhangliangliang.cc/post/etcd-cluster-operation-guide.html
作者
Bobby Zhang
发布于
2024年2月19日
许可协议