如何在滴滴云 DC2 上搭建 ETCD 集群

简介

ETCD 是一个开源的分布式 Key-Value 存储,它采用 Raft 算法来保证数据的强一致性,故常常用来存取分布式系统中对一致性要求比较苛刻的配置信息,被广泛应用。它具有如下特点:

  • 简单:为用户提供了简单而友好的 API 接口(gRPC)
  • 安全:客户端认证授权自动支持 TLS
  • 快速:基准测试性能可达每秒 10000 写操作
  • 可靠:采用 Raft 算法实现的分布式一致

ETCD 被很多公司在生产环境中广泛使用。ETCD 也是Kubernetes、Locksmith、Vulcand、Doorman 等著名开源项目的核心组件。

ETCD 支持两种组建集群的方式,第一种方式是静态配置,第二种是服务发现。

静态配置一个 ETCD 集群需要提前知道集群的成员节点 IP 地址或主机名。在有些场景下,集群成员节点的 IP 地址无法提前知道,那么也可以通过服务发现的方式来启动集群。

一旦一个 ETCD 集群启动并运行起来后,添加和移除集群成员节点就需要通过运行时重新配置(Runtime Reconfiguration)的方式来完成。

在本文中,我们介绍基于静态配置组建 ETCD 集群的机制,静态配置集群也是生产环境中使用 ETCD 的常用方式。

基本环境要求

我们使用三个滴滴云 DC2 服务器(奇数个 quorum,5个或7个服务器更好)来搭建一个最小化的 ETCD 集群,服务器的主机名与 IP 地址信息如下:

  1. etcd-1: 10.255.1.211
  2. etcd-2: 10.255.1.40
  3. etcd-3: 10.255.1.181

登陆 DC2,查看三个服务器的 IP 与 Hostname 详细信息如下:

第一个服务器的 IP 与主机名信息

[dc2-user@etcd-1 ~]$ ip a | grep 'inet\b' | grep -v '127.0.0.1'
    inet 10.255.1.211/24 brd 10.255.1.255 scope global eth0
[dc2-user@etcd-1 ~]$ hostname
etcd-1

第二个服务器的 IP 与主机名信息

[dc2-user@etcd-2 ~]$ ip a | grep 'inet\b' | grep -v '127.0.0.1'
    inet 10.255.1.40/24 brd 10.255.1.255 scope global eth0
[dc2-user@etcd-2 ~]$ hostname
etcd-2

第三个服务器 IP 与主机名信息

[dc2-user@10-255-1-181 ~]$ ip a | grep 'inet\b' | grep -v '127.0.0.1'
    inet 10.255.1.181/24 brd 10.255.1.255 scope global eth0
[dc2-user@10-255-1-181 ~]$ hostname
etcd-3

另外,要求上面所有服务器上的防火墙配置开放 2380 与 2379 端口的访问,前者用于监听 ETCD 客户端请求,后者用于 ETCD 集群其他节点的通信。

配置 ETCD 集群

步骤1 :CD 到 home 目录:

[dc2-user@etcd-1 ~]$ cd ~
[dc2-user@etcd-1 ~]$ pwd
/home/dc2-user

步骤2 :从GitHub下载最近的 ETCD 发行版,并且解压。在写作本文时,最新的发行版为 3.3.10。

[dc2-user@etcd-1 ~]$ sudo wget "https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz"
[dc2-user@etcd-1 ~]$ ls
etcd-v3.3.10-linux-amd64.tar.gz
[dc2-user@etcd-1 ~]$ tar -zxvf etcd-v3.3.10-linux-amd64.tar.gz 

步骤3 :将解压得到的 ETCD 程序添加到系统可执行文件目录。

[dc2-user@etcd-1 ~]$ sudo mv etcd-v3.3.10-linux-amd64/etcd* /usr/local/bin/

这里步骤 1 至步骤 3 需要在所有服务器上执行。

在静态配置的情况下,因为我们已经知道集群成员节点的 IP 地址和集群规模,我们可以使用一个启动配置来组建集群,启动配置需设置 initial-cluster 标志。

每台机器需要配置如下环境变量:

ETCD_INITIAL_CLUSTER="etcd-1=http://10.255.1.211:2380,etcd-2=http://10.255.1.40:2380,etcd-3=http://10.255.1.181:2380"
ETCD_INITIAL_CLUSTER_STATE=new

或者配置如下的 ETCD 参数:

--initial-cluster etcd-1=http://10.255.1.211:2380,etcd-2=http://10.255.1.40:2380,etcd-3=http://10.255.1.181:2380 \
--initial-cluster-state new

注意这里 initial-cluster 指定的 URL 必须与 initial-advertise-peer-urls 指定的保持一致。

另外,在配置集群时还有个参数特别有用必须切记不要忘了设置,即 initial-cluster-token。将每个 initial-cluster-token 设置为唯一的值,可以防止人为失误的错误配置而导致一个节点加入两个集群的问题。

ETCD 监听 listen-client-urls 指定的地址来接受客户端请求,但是只有在 advertise-client-urls 中指定的地址才会能被集群其他成员、集群代理或客户端访问到。一个常见的错误是将 advertise-client-urls 配置为 localhost 或不配置而是用默认值,这会导致集群不能被其他机器的客户端访问到。

步骤4 :在每个服务器上,依次使用如下命令来启动 ETCD,使用上面我们提到的参数。

在 etcd-1 服务器上的启动命令如下:

[dc2-user@etcd-1 ~]$ etcd --name etcd-1 --initial-advertise-peer-urls http://10.255.1.211:2380 \
>   --listen-peer-urls http://10.255.1.211:2380 \
>   --listen-client-urls http://10.255.1.211:2379,http://127.0.0.1:2379 \
>   --advertise-client-urls http://10.255.1.211:2379 \
>   --initial-cluster-token etcd-cluster-on-didicloud \
>   --initial-cluster etcd-1=http://10.255.1.211:2380,etcd-2=http://10.255.1.40:2380,etcd-3=http://10.255.1.181:2380 \
>   --initial-cluster-state

在 etcd-2 服务器上的启动命令如下:

[dc2-user@etcd-2 ~]$ etcd --name etcd-2 --initial-advertise-peer-urls http://10.255.1.40:2380 \
>   --listen-peer-urls http://10.255.1.40:2380 \
>   --listen-client-urls http://10.255.1.40:2379,http://127.0.0.1:2379 \
>   --advertise-client-urls http://10.255.1.40:2379 \
>   --initial-cluster-token etcd-cluster-on-didicloud \
>   --initial-cluster etcd-1=http://10.255.1.211:2380,etcd-2=http://10.255.1.40:2380,etcd-3=http://10.255.1.181:2380 \
>   --initial-cluster-state new

在 etcd-3 服务器上的启动命令如下:

[dc2-user@etcd-3 ~]$ etcd --name etcd-3 --initial-advertise-peer-urls http://10.255.1.181:2380 \
>   --listen-peer-urls http://10.255.1.181:2380 \
>   --listen-client-urls http://10.255.1.181:2379,http://127.0.0.1:2379 \
>   --advertise-client-urls http://10.255.1.181:2379 \
>   --initial-cluster-token etcd-cluster-on-didicloud \
>   --initial-cluster etcd-1=http://10.255.1.211:2380,etcd-2=http://10.255.1.40:2380,etcd-3=http://10.255.1.181:2380 \
>   --initial-cluster-state new 

命令行参数 -initial-cluster 只在集群初次启动时生效。再次启动时可以不传这个参数。如果需要在运行时修改配置,请参考 ETCD 的运行时改配置帮助文档。

验证集群状态

ETCD 安装包内带有一个 etcdctl 命令行工具,可以用来获取集群状态信息。可以在任意集群节点上执行如下的命令检查集群状态。
检查集群是否健康:

[dc2-user@etcd-3 ~]$ etcdctl cluster-health
member dc6b4b48ae00bf8 is healthy: got healthy result from http://10.255.1.40:2379
member d6020117e8a2dc38 is healthy: got healthy result from http://10.255.1.181:2379
member e95ffbf99d4aae9c is healthy: got healthy result from http://10.255.1.211:2379
cluster is healthy

使用如下命令检查集群成员节点:

[dc2-user@etcd-3 ~]$ etcdctl member list
dc6b4b48ae00bf8: name=etcd-2 peerURLs=http://10.255.1.40:2380 
clientURLs=http://10.255.1.40:2379 isLeader=false
d6020117e8a2dc38: name=etcd-3 peerURLs=http://10.255.1.181:2380 
clientURLs=http://10.255.1.181:2379 isLeader=false
e95ffbf99d4aae9c: name=etcd-1 peerURLs=http://10.255.1.211:2380 
clientURLs=http://10.255.1.211:2379 isLeader=true
[dc2-user@etcd-3 ~]$ 

默认情况下,etcdctl 使用 ETCD v2 接口与服务端交互。你可以显示指定 ETCDCTL_API=3 来使用 etcd v3 版本的功能。
可以通过设置 Linux 系统环境变量来设置使用 etcd v3 版本功能,也可以在每次命令行运行时指定该环境变量。
现在我们往集群写入几个 key-value 键值对来验证一下。

[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl put name1 batman
OK
[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl put name2 ironman
OK
[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl put name3 superman
OK
[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl put name4 spiderman
OK
[dc2-user@etcd-3 ~]$ 

现在可以使用下面的命令读取刚才写入的键值。

[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl get name3
name3
superman
[dc2-user@etcd-3 ~]$ 

ETCD 还支持指定获取 key 范围或前缀批量读取。

[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl get name1 name4  
# 读取从name1到name4的所有key-value
name1
batman
name2
ironman
name3
superman
[dc2-user@etcd-3 ~]$ ETCDCTL_API=3 etcdctl get --prefix name 
# 列出所有以name为前缀的key-value
name1
batman
name2
ironman
name3
superman
name4
spiderman
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值