一篇文章带你了解 etcd 的基本操作以及集群配置🤪

一篇文章带你了解 etcd 的基本操作以及集群配置🤪

ETCD 基本操作

etcd

etcd(读作et-see-dee)是一种开源的分布式统一键值存储,用于分布式系统或计算机集群的共享配置、服务发现和的调度协调etcd 有助于促进更加安全的自动更新,协调向主机调度的工作,并帮助设置容器的覆盖网络。 etcd 是许多其他项目的核心组件。

安装

  • 1、第一种方式就是通过 github 安装,可自行在一下网站下载

Releases · etcd-io/etcd (github.com)

  • 2、 通过命令安装

mac brew install etcd

添加环境变量

安装完成后需要将 etcd 的目录添加到环境变量中,这样就可以调用 etcd 命令操作。

add path

执行以下命令查看是否生效: etcd --version

输出:

shell 复制代码
etcd --version
etcd Version: 3.5.10
Git SHA: 0223ca52b
Go Version: go1.20.10
Go OS/Arch: darwin/amd64

启动 etcd 服务

shell 复制代码
./etcd

输出:

基础使用

设置值 etcdctl put

shell 复制代码
etcdctl put greeting "hello world"

获取值 etcdctl get

shell 复制代码
etcdctl get greeting

授权 auth

  • 设置环境变量 ETCDCTL_API=3 ENDPOINTS=localhost:2379
shell 复制代码
export ETCDCTL_API=3
ENDPOINTS=localhost:2379
  • 添加角色: etcd 可以通过添加用户,添加角色,角色授权,将用户添加到角色进行权限管控:
shell 复制代码
# 添加 root 角色
etcdctl --endpoints=${ENDPOINTS} role add root
  • 获取角色信息
shell 复制代码
etcdctl --endpoints=${ENDPOINTS} role get root
Role root
KV Read:
KV Write:
  • 添加 root 成员 / 获取成员信息
shell 复制代码
# 添加成员 root
etcdctl --endpoints=${ENDPOINTS} user add root

# 设置密码
Password of root:
Type password of root again for confirmation:
User root created

# 查看用户信息
etcdctl --endpoints=${ENDPOINTS} user get root
User: root
Roles:
  • 成员授权角色
shell 复制代码
# 将 root 用户授权给 root 角色
etcdctl --endpoints=${ENDPOINTS} user grant-role root root

# 用户 root 授权 root 成功
Role root is granted to user root
  • 添加新的角色,授权角色的权限
shell 复制代码
etcdctl --endpoints=${ENDPOINTS} role add role0
etcdctl --endpoints=${ENDPOINTS} role grant-permission role0 readwrite foo
etcdctl --endpoints=${ENDPOINTS} user add user0
etcdctl --endpoints=${ENDPOINTS} user grant-role user0 role0
  • 启用角色授权
shell 复制代码
# 最后需要启用 etcd 的auth 功能
etcdctl --endpoints=${ENDPOINTS} auth enable
Authentication Enabled
  • 使用新添加的成员user0来操作etcd
shell 复制代码
etcdctl --endpoints=${ENDPOINTS} --user=user0:123 put foo bar
etcdctl --endpoints=${ENDPOINTS} get foo
#权限被拒绝,用户名为空,因为请求未发出身份验证请求
etcdctl --endpoints=${ENDPOINTS} --user=user0:123 get foo
#user0可以读取关键字foo
etcdctl --endpoints=${ENDPOINTS} --user=user0:123 get foo1

etcd 集群配置

我们需要准备 3 台虚拟机器,并分别配置 IP:具体怎么弄大家可自行查询

192.168.2.128

192.168.2.129

192.168.2.130

在每个 etcd 节点上,指定集群成员:

shell 复制代码
TOKEN=token-01
CLUSTER_STATE=new
NAME_1=machine-1
NAME_2=machine-2
NAME_3=machine-3
HOST_1=192.168.2.128
HOST_2=192.168.2.129
HOST_3=192.168.2.130
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380

在每台计算机上运行以下命令:

shell 复制代码
# For machine 1
THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
etcd --data-dir=data.etcd 
	--name ${THIS_NAME} \
	--initial-advertise-peer-urls http://${THIS_IP}:2380 \
	--advertise-client-urls http://${THIS_IP}:2379 \
  --listen-client-urls http://${THIS_IP}:2379 \
	--listen-peer-urls http://${THIS_IP}:2380 \
	--initial-cluster ${CLUSTER} \
	--initial-cluster-state ${CLUSTER_STATE} \
  --initial-cluster-token ${TOKEN}

# For machine 2
THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
etcd --data-dir=data.etcd \ 
		 --name ${THIS_NAME} \
		 --initial-advertise-peer-urls http://${THIS_IP}:2380 \
		 --advertise-client-urls http://${THIS_IP}:2379 \
		 --listen-client-urls http://${THIS_IP}:2379 \
		 --listen-peer-urls http://${THIS_IP}:2380 \
		 --initial-cluster ${CLUSTER} \
		 --initial-cluster-state ${CLUSTER_STATE} \
		 --initial-cluster-token ${TOKEN}

# For machine 3
THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
etcd --data-dir=data.etcd \ 
		--name ${THIS_NAME} \
		--initial-advertise-peer-urls http://${THIS_IP}:2380 
		--advertise-client-urls http://${THIS_IP}:2379
    --listen-client-urls http://${THIS_IP}:2379 \
		--listen-peer-urls http://${THIS_IP}:2380 \
		--initial-cluster ${CLUSTER} \
		--initial-cluster-state ${CLUSTER_STATE} \
		--initial-cluster-token ${TOKEN}

参数说明:

listen-client-urlslisten-peer-urls 指定 etcd 服务器绑定到的本地地址以接受传入连接。要侦听所有接口的端口,请指定 0.0.0.0 为侦听 IP 地址。

advertise-client-urlsinitial-advertise-peer-urls 指定 etcd 客户端或其他 etcd 成员用于联系 etcd 服务器的地址。播发地址必须可从远程计算机访问。不要公布生产设置的地址, localhost 0.0.0.0 因为这些地址无法从远程计算机访问。

连接etcd

要使用 etcdctl 连接到 etcd:

shell 复制代码
export ETCDCTL_API=3
HOST_1=192.168.2.128
HOST_2=192.168.2.129
HOST_3=192.168.2.130
ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379

etcdctl --endpoints=$ENDPOINTS member list

如何访问 etcd

访问 etcd 集群指南

put要写入的命令:

shell 复制代码
etcdctl --endpoints=$ENDPOINTS put foo "Hello World!"

get要从 etcd 中读取:

shell 复制代码
etcdctl --endpoints=$ENDPOINTS get foo
etcdctl --endpoints=$ENDPOINTS --write-out="json" get foo

如何模糊查询(按前缀获取值)

按前缀提取 etcd 键的指南

shell 复制代码
etcdctl --endpoints=$ENDPOINTS put web1 value1
etcdctl --endpoints=$ENDPOINTS put web2 value2
etcdctl --endpoints=$ENDPOINTS put web3 value3

etcdctl --endpoints=$ENDPOINTS get web --prefix

我们只需要在查询的关键字后面加上 --prefix 参数即可

删除key

删除 etcd 密钥的方法

shell 复制代码
etcdctl --endpoints=$ENDPOINTS put key myvalue
etcdctl --endpoints=$ENDPOINTS del key

etcdctl --endpoints=$ENDPOINTS put k1 value1
etcdctl --endpoints=$ENDPOINTS put k2 value2
etcdctl --endpoints=$ENDPOINTS del k --prefix

查看返回的结果 4,也就是我们删除了 4 个相关的 key

我们在来查看下:

shell 复制代码
❯ etcdctl --endpoints=$ENDPOINTS get web --prefix
❯

结果为空,也就是我们完全删除了相关的 key

事务中进行多次写入

事务性写入方法:

txn要将多个请求包装到一个事务中,请执行以下操作:

shell 复制代码
etcdctl --endpoints=$ENDPOINTS put user1 bad
etcdctl --endpoints=$ENDPOINTS txn --interactive

compares:
value("user1") = "bad"

success requests (get, put, delete):
del user1

failure requests (get, put, delete):
put user1 good

事务解析:

启动事务:etcdctl --endpoints=$ENDPOINTS txn --interactive

输入条件:value("user1") = "bad"

如果条件满足:执行 success 下面的命令,del user1 删除 user1

如果条件不满足:执行 failure 的条件, 设置 put user1 good user1 的值为 good

监听 key 值

使用 watch获得未来变更的通知:

shell 复制代码
etcdctl --endpoints=$ENDPOINTS watch stock1
etcdctl --endpoints=$ENDPOINTS put stock1 1000

etcdctl --endpoints=$ENDPOINTS watch stock --prefix
etcdctl --endpoints=$ENDPOINTS put stock1 10
etcdctl --endpoints=$ENDPOINTS put stock2 20

如何创建租约

etcd 中创建租约的指南, 那什么是 etcd 的租约?

etcdleaseclientetcd server 之间存在一个约定,内容是 etcd server 保证在约定的有效期内(TTL),不会删除你关联到此 Lease 上的 key-value

若你未在有效期内续租,那么 etcd server 就会删除 Lease 和其关联的 key-value

shell 复制代码
# 生成一个 300s 的 lease 租约
etcdctl --endpoints=$ENDPOINTS lease grant 300
# lease 2be7547fbc6a5afa granted with TTL(300s)

# 给sample绑定租约
etcdctl --endpoints=$ENDPOINTS put sample value --lease=2be7547fbc6a5afa
etcdctl --endpoints=$ENDPOINTS get sample

# 给 2be7547fbc6a5afa 相关联的 key 续租
etcdctl --endpoints=$ENDPOINTS lease keep-alive 2be7547fbc6a5afa
# 删除租约 2be7547fbc6a5afa 
etcdctl --endpoints=$ENDPOINTS lease revoke 2be7547fbc6a5afa
# 300s 后我们在获取 sample 查看他的值
etcdctl --endpoints=$ENDPOINTS get sample

etcd 如何创建锁

在etcd中创建分布式锁

lock对于分布式锁:

shell 复制代码
etcdctl --endpoints=$ENDPOINTS lock mutex1

# 在另外一个terminal 执行获取锁的命令,则发生阻塞,知道其他客户端释放锁
etcdctl --endpoints=$ENDPOINTS lock mutex1

如何在 etcd 集群中进行 leader 选举

在 etcd 集群中进行 leader 选举的指南

elect for leader election:

shell 复制代码
etcdctl --endpoints=$ENDPOINTS elect one p1

# 在另外的一个 terminal 中执行下面相同的命令,会发生阻塞
etcdctl --endpoints=$ENDPOINTS elect one p2

ps:为什么会阻塞?出于什么原因考虑?选举究竟是个什么意思?需要思考!!!

如何检查集群状态

etcd 集群状态检查指南

为每台计算机指定初始群集配置:

etcdctl --write-out=table --endpoints**=$ENDPOINTS endpoint status

+--------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | +--------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | 192.168.2.128:2379 | 40ac7c5d0c1eee16 | 3.5.0 | 33 kB | true | false | 6 | 64 | 64 | | | 192.168.2.129:2379 | b13e39e86b04f6e7 | 3.5.0 | 25 kB | false | false | 6 | 64 | 64 | | | 192.168.2.130:2379 | 8e9d8b8febceee50 | 3.5.0 | 29 kB | false | false | 6 | 64 | 64 | | +--------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

如何保存数据库

snapshot 要保存 etcd 数据库的时间点快照:

快照只能从一个 etcd 节点请求,因此 --endpoints flag 应该只包含一个端点。

shell 复制代码
ENDPOINTS=$HOST_1:2379
etcdctl --endpoints=$ENDPOINTS snapshot save my.db

Snapshot saved at my.db

使用etcdctl --endpoints=192.168.2.128 snapshot status my.db --write-out=table 查看快照的状态

diff 复制代码
+---------+----------+------------+------------+
|  HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+---------+----------+------------+------------+
| c55e8b8 |        9 |         13 | 25 kB      |
+---------+----------+------------+------------+

如何添加和删除成员

member 要添加、删除、更新成员资格:

shell 复制代码
NAME_4=etcd-node-4
HOST_4=192.168.2.131 # new member
etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379 \
	member add ${NAME_4} \
	--peer-urls=http://${HOST_4}:2380

在新节点的机器执行

shell 复制代码
THIS_NAME=${NAME_4}
THIS_IP=${HOST_4}
etcd --data-dir=data.etcd --name ${THIS_NAME} \
	--initial-advertise-peer-urls http://${THIS_IP}:2380 \
	--listen-peer-urls http://${THIS_IP}:2380 \
	--advertise-client-urls http://${THIS_IP}:2379 \
	--listen-client-urls http://${THIS_IP}:2379 \
	--initial-cluster ${CLUSTER} \
	--initial-cluster-state ${CLUSTER_STATE} \
	--initial-cluster-token ${TOKEN}
相关推荐
掘金-我是哪吒31 分钟前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
茶馆大橘2 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
58沈剑2 小时前
80后聊架构:架构设计中两个重要指标,延时与吞吐量(Latency vs Throughput) | 架构师之路...
架构
想进大厂的小王5 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
九卷技术录5 小时前
(微服务)服务治理:几种开源限流算法库/应用软件介绍和使用
微服务·服务治理·限流算法
阿伟*rui6 小时前
认识微服务,微服务的拆分,服务治理(nacos注册中心,远程调用)
微服务·架构·firefox
ZHOU西口6 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
嚣张农民8 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
梓羽玩Python8 小时前
推荐一款用了5年的全能下载神器:Motrix!全平台支持,不限速下载网盘文件就靠它!
程序员·开源·github
deephub8 小时前
Tokenformer:基于参数标记化的高效可扩展Transformer架构
人工智能·python·深度学习·架构·transformer