【ETCD】ETCD常用命令
ETCD常用命令摘要 本文介绍了ETCD集群管理的常用命令和基本配置方法。主要包括: 环境准备:配置3节点openEuler系统集群(IP:192.168.93.101-103),关闭防火墙和SELinux,设置主机名等基础环境配置。 命令基础:ETCD提供了命令行客户端工具etcdctl,可通过etcdctl command --help获取命令帮助。 常用命令: 查看版本:etcdctl ve
·
ETCD常用命令
资源列表
| 操作系统 | 配置 | 主机名 | IP |
|---|---|---|---|
| openEuler | 2C4G | etcd1 | 192.168.93.101 |
| openEuler | 2C4G | etcd2 | 192.168.93.102 |
| openEuler | 2C4G | etcd3 | 192.168.93.103 |
基础环境
- 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
- 关闭内核安全机制
setenforce 0
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
- 修改主机名
hostnamectl set-hostname etcd1
hostnamectl set-hostname etcd2
hostnamectl set-hostname etcd3
一、集群管理命令
- etcd是一个命令行的客户端,它提供了一些命令,可以方便我们在对服务进行测试或者手动修改数据库内容。etcd命令基本用法如下所示:
etcdctl [global options] command [command options] [args...]
- 具体的命令选项可以通过etcd command --help 来获取相关帮助
二、环境变量
- 如果遇到使用了TLS加密的集群,通常每条指令都需要指定证书路径和etcd节点地址,可以把相关命令行参数添加在环境变量中,在
.bashrc添加以下内容。 - 本次实验不采用TLS
[root@etcd1 ~]# cat ~/.bashrc
HOST_1=https://192.168.93.101:2379
HOST_2=https://192.168.93.102:2379
HOST_3=https://192.168.93.103:2379
ENDPOINTS=${HOST_1},${HOST_2},${HOST_3}
# 如果需要使用原生命令,在命令开头加一个\ 例如:\etcdctl command
alias etcdctl="etcdctl --endpoints=${ENDPOINTS} --cacert=/root/cfssl/etcd/ca.pem --cert=/root/cfssl/etcd/client.pem --key=/root/cfssl/etcd/client-key.pem"
alias etcdctljson="etcdctl --endpoints=${ENDPOINTS} --cacert=/root/cfssl/etcd/ca.pem --cert=/root/cfssl/etcd/client.pem --key=/root/cfssl/etcd/client-key.pem --write-out=json"
alias etcdctltable="etcdctl --endpoints=${ENDPOINTS} --cacert=/root/cfssl/etcd/ca.pem --cert=/root/cfssl/etcd/client.pem --key=/root/cfssl/etcd/client-key.pem --write-out=table"
三、ETCD常用命令
- etcd的常用命令有很多,但不限于获取、删除、查看。
3.1、查看etcd版本
[root@etcd1 ~]# etcdctl version
etcdctl version: 3.4.23
API version: 3.4
3.2、查看etcd结群节点信息
[root@etcd1 ~]# etcdctl member list -w table
+------------------+---------+-------+----------------------------+----------------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+-------+----------------------------+----------------------------+------------+
| 3d33f92152eaee46 | started | etcd3 | http://192.168.93.103:2380 | http://192.168.93.103:2379 | false |
| 5abc4e842d3ab1d6 | started | etcd2 | http://192.168.93.102:2380 | http://192.168.93.102:2379 | false |
| f416c4d7e7853c3a | started | etcd1 | http://192.168.93.101:2380 | http://192.168.93.101:2379 | false |
+------------------+---------+-------+----------------------------+----------------------------+------------+
3.3、查看集群健康状态
[root@etcd1 ~]# cat ~/.bashrc
HOST_1=http://192.168.93.101:2379
HOST_2=http://192.168.93.102:2379
HOST_3=http://192.168.93.103:2379
ENDPOINTS=${HOST_1},${HOST_2},${HOST_3}
# 如果需要使用原生命令,在命令开头加一个\ 例如:\etcdctl command
alias etcdctl="etcdctl --endpoints=${ENDPOINTS}"
[root@etcd1 ~]# etcdctl endpoint status -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 20 kB | true | false | 2 | 8 | 8 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 20 kB | false | false | 2 | 8 | 8 | |
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 20 kB | false | false | 2 | 8 | 8 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
[root@etcd1 ~]# etcdctl endpoint health -w table
+----------------------------+--------+------------+-------+
| ENDPOINT | HEALTH | TOOK | ERROR |
+----------------------------+--------+------------+-------+
| http://192.168.93.101:2379 | true | 1.591124ms | |
| http://192.168.93.103:2379 | true | 1.987456ms | |
| http://192.168.93.102:2379 | true | 8.935062ms | |
+----------------------------+--------+------------+-------+
3.4、查看告警事件
- 如果内部出现了问题,会触发告警,可以通过命令查看告警引起的原因,命令如下所示:
etcdctl alarm <subcommand> [flags]
- 常用的子命令主要有两个:
# 查看所有告警
etcdctl alarm list
# 解除所有告警
etcdctl alarm disarm
3.5、添加成员
- 当集群部署完成后,后续可能需要进行节点扩缩容,就可以使用member命令管理节点。先查看当前集群信息。
[root@etcd1 ~]# etcdctl endpoint status --cluster -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 20 kB | false | false | 2 | 8 | 8 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 20 kB | false | false | 2 | 8 | 8 | |
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 20 kB | true | false | 2 | 8 | 8 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
- 在启动新的etcd节点前,先向etcd集群声明添加节点的peer-urls和节点名称
[root@etcd1 ~]# etcdctl member add etcd4 --peer-urls=http://192.168.93.104:2380
Member dd2947c31edb0d2 added to cluster b59d820ff8caf3f4
ETCD_NAME="etcd4"
ETCD_INITIAL_CLUSTER="etcd4=http://192.168.93.104:2380,etcd3=http://192.168.93.103:2380,etcd2=http://192.168.93.102:2380,etcd1=http://192.168.93.101:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.93.104:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"
- 接下来新开启一台etcd服务器,IP地址为
192.168.93.104,节点名称是etcd4.
# 以下是 etcd4 的配置文件
# 注意此时 etcd4 要加入的集群是一个已经存在的集群, 所以initial-cluster-state 字段需要设置为 existing 表示加入现有集群
[root@etcd5 ~]# cat /etc/etcd/etcd.conf
# 节点名称
name: "etcd4"
# 数据存储目录
data-dir: "/data/etcd"
# 对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点
advertise-client-urls: "http://192.168.93.104:2379"
# 监听客户端请求的地址列表
listen-client-urls: "http://192.168.93.104:2379,http://127.0.0.1:2379"
# 监听URL,用于节点之间通信监听地址
listen-peer-urls: "http://192.168.93.104:2380"
# 服务端之间通讯使用的地址列表,该节点同伴监听地址,这个值会告诉集群中其他节点
initial-advertise-peer-urls: "http://192.168.93.104:2380"
# etcd启动时,etcd集群的节点地址列表
initial-cluster: "etcd1=http://192.168.93.101:2380,etcd2=http://192.168.93.102:2380,etcd3=http://192.168.93.103:2380,etcd4=http://192.168.93.104:2380"
# etcd集群的初始集群令牌
initial-cluster-token: 'etcd-cluster'
# etcd集群初始化的状态,new代表新建集群,existing表示加入现有集群
initial-cluster-state: 'existing'
# 启动 etcd4
[root@etcd4 ~]# systemctl start etcd
# etcd4 启动后, 查看集群节点信息
[root@etcd1 ~]# etcdctl endpoint status --cluster -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.104:2379 | dd2947c31edb0d2 | 3.4.23 | 20 kB | false | false | 2 | 12 | 12 | |
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 20 kB | false | false | 2 | 12 | 12 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 20 kB | false | false | 2 | 12 | 12 | |
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 20 kB | true | false | 2 | 12 | 12 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
3.6、更新成员
- 当 etcd 节点故障,启动 etcd 时报错
member count is unqueal。如果有保留的数据目录吓下得文件时,可以通过使用member update命令,在保留 etcd 数据得情况下初始化集群数据,重新构建一个新的 etcd 集群节点。 - 模拟192.168.93.101:2380节点故障,但数据目录文件有备份,启动一个新得节点,地址为:192.168.93.105:2380。
# 停用旧节点
[root@etcd4 ~]# systemctl stop etcd.service
# 把 etcd4 得数据 scp 到 etcd5 节点
[root@etcd4 ~]# scp -r /data/ root@192.168.93.105:/
# 更新节点地址
[root@etcd5 ~]# cat /etc/etcd/etcd.conf
# 节点名称
name: "etcd4"
# 数据存储目录
data-dir: "/data/etcd"
# 对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点
advertise-client-urls: "http://192.168.93.105:2379"
# 监听客户端请求的地址列表
listen-client-urls: "http://192.168.93.105:2379,http://127.0.0.1:2379"
# 监听URL,用于节点之间通信监听地址
listen-peer-urls: "http://192.168.93.105:2380"
# 服务端之间通讯使用的地址列表,该节点同伴监听地址,这个值会告诉集群中其他节点
initial-advertise-peer-urls: "http://192.168.93.105:2380"
# etcd启动时,etcd集群的节点地址列表
initial-cluster: "etcd1=http://192.168.93.101:2380,etcd2=http://192.168.93.102:2380,etcd3=http://192.168.93.103:2380,etcd4=http://192.168.93.105:2380"
# etcd集群的初始集群令牌
initial-cluster-token: 'etcd-cluster'
# etcd集群初始化的状态,new代表新建集群,existing表示加入现有集群
initial-cluster-state: 'existing'
# 启动新节点
[root@etcd5 ~]# systemctl daemon-reload
[root@etcd5 ~]# systemctl start etcd.service
- 执行更新member操作,指定新的节点地址
# ID 为 104
[root@etcd1 ~]# etcdctl member update dd2947c31edb0d2 --peer-urls=http://192.168.93.105:2380
Member dd2947c31edb0d2 updated in cluster b59d820ff8caf3f4
- 查看集群节点信息,节点信息更新完成。
[root@etcd1 ~]# etcdctl endpoint status --cluster -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.105:2379 | dd2947c31edb0d2 | 3.4.23 | 20 kB | false | false | 2 | 14 | 14 | |
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 20 kB | false | false | 2 | 14 | 14 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 20 kB | false | false | 2 | 14 | 14 | |
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 20 kB | true | false | 2 | 14 | 14 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
3.7、删除成员
- 主要用法如下所示:
etcdctl member remove <memberID> [flags]
- 模拟192.168.93.105:2380节点下线操作
# 停止 etcd 5的节点
[root@etcd5 ~]# systemctl stop etcd.service
- 执行删除操作
# dd2947c31edb0d2 为 etcd5 的 ID
[root@etcd1 ~]# etcdctl member remove dd2947c31edb0d2
Member dd2947c31edb0d2 removed from cluster b59d820ff8caf3f4
[root@etcd1 ~]# etcdctl endpoint status --cluster -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 20 kB | false | false | 4 | 21 | 21 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 20 kB | false | false | 4 | 21 | 21 | |
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 20 kB | true | false | 4 | 21 | 21 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
四、数据库操作命令
4.1、增加(put)
- 添加一个键值对,基本用法如下所示
etcdctl put [options] <key> <value> [flags]
- 常用参数如下所示:
| 参数 | 功能描述 |
|---|---|
| –perv-kv | 输出修改前的键值 |
- 注意事项:
- 其中value接受从stdin的输入内容
- 如果value是以横线-开始,将会被视为flag,如果不希望出现这种情况,可以使用两个横线代替–
- 若键已经存在,则进行更新并覆盖原有值,若不存在,则进行添加
[root@etcd1 ~]# etcdctl put name wzh
OK
[root@etcd1 ~]# etcdctl put location -- -shanghai
OK
[root@etcd1 ~]# etcdctl put foo1 bar1
OK
[root@etcd1 ~]# etcdctl put foo2 bar2
OK
[root@etcd1 ~]# etcdctl put foo3 bar3
OK
4.2、查询(get)
- 查询键值对,基本用法如下所示
etcdctl get [options] <key> [range_end] [flags]
- 常用参数如下所示
| 参数 | 功能描述 |
|---|---|
| –hex | 以十六进制形式输出 |
| –limit number | 设置是输出结果的最大值 |
| –prefix | 根据prefix进行匹配key |
| –order | 对输出结果进行排序,ASCEND或DESCEND |
| –sort-by | 按给定字段排序,CREATE,KEYMODIFY,VALUE,VERSION |
| –print-value-only | 仅输出value值 |
| –from-key | 按byte进行比较,获取大于等于指定key的结果 |
| –keys-only | 仅获取keys |
- 示例
# 获取键值
[root@etcd1 ~]# etcdctl get name
name
wzh
# 只获取值
[root@etcd1 ~]# etcdctl get location --print-value-only
-shanghai
# 批量取从 foo1-foo3 的值, 不包括 foo3
[root@etcd1 ~]# etcdctl get foo1 foo3 --print-value-only
bar1
bar2
# 批量获取前缀为 foo 的值
[root@etcd1 ~]# etcdctl get --prefix foo --print-value-only
bar1
bar2
bar3
# 批量获取符合前缀的两个值
[root@etcd1 ~]# etcdctl get --prefix --limit=2 foo --print-value-only
bar1
bar2
# 批量获取前缀为 foo 的值, 并排序
[root@etcd1 ~]# etcdctl get --prefix foo --print-value-only --order DESCEND
bar3
bar2
bar1
4.3、删除(del)
- 删除键值,基本用法如下所示
etcdctl del [options] <key> [range_end] [flags]
- 常用参数如下所示
| 参数 | 功能描述 |
|---|---|
| –prefix | 根据prefix进行匹配删除 |
| –prev-kv | 输出删除的键值 |
| –form-key | 按byte进行比较,删除大于指定key的结果 |
- 示例
# 删除name的键值
[root@etcd1 ~]# etcdctl del name
1
# 删除从foo1到foo3且不包含foo3的键值
[root@etcd1 ~]# etcdctl del foo1 foo3
2
# 删除前缀为foo的所有键值
[root@etcd1 ~]# etcdctl del --prefix foo
1
4.4、更新(put覆盖)
- 若键值已经存在,则进行更新并覆盖原有值,若不存在,则进行添加
4.5、查询键历史记录查询
- etcd在每次键值变更时,都会记录变更信息,便于我们查看键变更记录
4.6、监听命令
- watch是监听或前缀发生改变的事件流,只要用法如下所示:
etcdctl watch [options] [key or prefix] [range_end] [--] [exec-command arg1 arg2 ...] [flags]
- 示例如下所示:
# 对某个 key 监听操作, 当 key1 发生改变时, 会返回最新值
[root@etcd1 ~]# etcdctl watch name
# 监听 key 前缀
[root@etcd1 ~]# etcdctl watch name --prefix
# 监听到改变后执行相关操作
[root@etcd1 ~]# etcdctl watch name -- etcdctl get age
4.6、监听单个建
# 启动监听命令
[root@etcd1 ~]# etcdctl watch foo
# 另一个控制台执行新增命令
[root@etcd1 ~]# etcdctl put foo bar
OK
# 观察控制台监听输出
[root@etcd1 ~]# etcdctl watch foo
PUT
foo
bar
# 另一个控制台执行删除命令
[root@etcd1 ~]# etcdctl del foo
1
# 观察控制台监听输出
[root@etcd1 ~]# etcdctl watch foo
PUT
foo
bar
DELETE
foo
4.7、同时监听多个建
# 监听前缀为 foo 的建
[root@etcd1 ~]# etcdctl watch --prefix foo
# 另一个控制台执行操作
[root@etcd1 ~]# etcdctl put foo1 bar1
OK
[root@etcd1 ~]# etcdctl put foo2 bar2
OK
[root@etcd1 ~]# etcdctl del foo1
1
# 观察控制台输出
[root@etcd1 ~]# etcdctl watch --prefix foo
PUT
foo1
bar1
PUT
foo2
bar2
DELETE
foo1
# 监听指定的多个建
[root@etcd1 ~]# etcdctl watch -i
watch name
watch location
# 另一个控制台执行操作
[root@etcd1 ~]# etcdctl put name wzh
OK
[root@etcd1 ~]# etcdctl del name
1
[root@etcd1 ~]# etcdctl put location shanghai
OK
# 观察控制台输出
[root@etcd1 ~]# etcdctl watch -i
watch name
watch location
PUT
name
wzh
DELETE
name
PUT
location
shanghai
五、租约命令
- 租约具有生命周期,需要为租约授予一个TTL(生命周期),将租约绑定到key上,则key的生命周期与租约一直,可续约,可撤销租约,类似于redis为建设置过期时间。其主要用法如下所示:
etcdctl lease <subcommand> [flags]
5.1、添加租约
- 主要用法如下所示:
etcdctl lease grant <ttl> [flags]
- 示例
# 设置 60 秒后过期时间
[root@etcd1 ~]# etcdctl lease grant 60
lease 3c3a9a4cb7661512 granted with TTL(60s)
# 把 foo 和租约绑定, 设置为60秒后过期
[root@etcd1 ~]# etcdctl put --lease=3c3a9a4cb7661512 foo bar
OK
# 租约期内查询键值
[root@etcd1 ~]# etcdctl get foo
foo
bar
# 租约期外查询键值(没有任何回显)
[root@etcd1 ~]# etcdctl get foo
5.2、查看租约
- 查看租约信息,以便租约或查看租约是否仍然存在或者已过期。
- 查看租约详情主要用法如下所示:
etcdctl lease timetolive <leaseID> [options] [flags]
- 示例
# 添加一个 50 秒的租约
[root@etcd1 ~]# etcdctl lease grant 50
lease 3c3a9a4cb7661518 granted with TTL(50s)
# 将 name 键绑定到 3c3a9a4cb7661518 租约上
[root@etcd1 ~]# etcdctl put --lease=3c3a9a4cb7661518 name wzh
OK
# 查看所有租约列表
[root@etcd1 ~]# etcdctl lease list
found 1 leases
3c3a9a4cb7661518
# 查看租约详情, remaining: 剩余时间 keys: 获取租约绑定的 key
[root@etcd1 ~]# etcdctl lease timetolive --keys 3c3a9a4cb7661518
lease 3c3a9a4cb7661518 granted with TTL(50s), remaining(16s), attached keys([name])
5.3、租约续约
- 通过刷新TTL值来保持续约的有效,使其不会过期。
- 示例如下所示:
etcdctl lease keep-alive [options] <leaseID> [flags]
- 示例如下所示
# 设置 60 秒后过期租约
[root@etcd1 ~]# etcdctl lease grant 60
lease 3c3a9a4cb766151c granted with TTL(60s)
# 把 name 和租约绑定, 设置成功后 60 秒后过期
[root@etcd1 ~]# etcdctl put --lease=3c3a9a4cb766151c name wzh
OK
# 自动定时执行续约, 续约成功后每次租约为 60 秒
[root@etcd1 ~]# etcdctl lease keep-alive 3c3a9a4cb766151c
lease 3c3a9a4cb766151c keepalived with TTL(60)
lease 3c3a9a4cb766151c keepalived with TTL(60)
......
5.4、删除租约
-
通过租约ID撤销租约,撤销租约将删除其所有绑定的key。
-
主要用法如下所示:
etcdctl lease revoke <leaseID> [flags]
- 示例如下所示
# 设置 600 秒后过期租约
[root@etcd1 ~]# etcdctl lease grant 600
lease 3c3a9a4cb766151f granted with TTL(600s)
# 把 foo 和租约绑定, 600 秒后过期
[root@etcd1 ~]# etcdctl put --lease=3c3a9a4cb766151f foo bar
OK
# 查看租约详情
[root@etcd1 ~]# etcdctl lease timetolive --keys 3c3a9a4cb766151f
lease 3c3a9a4cb766151f granted with TTL(600s), remaining(574s), attached keys([foo])
# 删除租约
[root@etcd1 ~]# etcdctl lease revoke 3c3a9a4cb766151f
lease 3c3a9a4cb766151f revoked
# 查案续约详情
[root@etcd1 ~]# etcdctl lease timetolive --keys 3c3a9a4cb766151f
lease 3c3a9a4cb766151f already expired
# 获取键值(无任何返回)
[root@etcd1 ~]# etcdctl get foo
5.5、多key同一租约
- 一个租约支持绑定多个key
[root@etcd1 ~]# etcdctl lease grant 60
lease 3c3a9a4cb7661525 granted with TTL(60s)
[root@etcd1 ~]# etcdctl put --lease=3c3a9a4cb7661525 foo1 bar1
OK
[root@etcd1 ~]# etcdctl put --lease=3c3a9a4cb7661525 foo2 bar2
OK
[root@etcd1 ~]# etcdctl lease timetolive --keys 3c3a9a4cb7661525
lease 3c3a9a4cb7661525 granted with TTL(60s), remaining(29s), attached keys([foo1 foo2])
-
租约过期后,所有key值都会被删除,因此:
- 当租约只绑定一个key时,想删除这个key,最好的办法是撤销它的租约,而不是直接删除这个key。
- 当租约没有绑定key时,应主动把它撤销掉,单纯删除key后,续约操作持续进行,会造成内存泄漏。
-
直接删除key的演示:
# 设置租约并绑定 zoo1
[root@etcd1 ~]# etcdctl lease grant 60
lease 3c3a9a4cb766152a granted with TTL(60s)
[root@etcd1 ~]# etcdctl --lease=3c3a9a4cb766152a put zoo1 val1
OK
[root@etcd1 ~]# etcdctl del zoo1
1
# 单纯删除 key 后, 续约操作持续进行, 会造成内存泄漏
[root@etcd1 ~]# etcdctl lease keep-alive 3c3a9a4cb766152a
lease 3c3a9a4cb766152a keepalived with TTL(60)
lease 3c3a9a4cb766152a keepalived with TTL(60)
......
- 撤销key的续约演示
# 设置租约并绑定 zoo1
[root@etcd1 ~]# etcdctl lease grant 60
lease 3c3a9a4cb766152e granted with TTL(60s)
[root@etcd1 ~]# etcdctl --lease=3c3a9a4cb766152e put zoo1 val1
OK
# 续约
[root@etcd1 ~]# etcdctl lease keep-alive 3c3a9a4cb766152e
lease 3c3a9a4cb766152e keepalived with TTL(60)
lease 3c3a9a4cb766152e expired or revoked.
# 另一个控制台执行
[root@etcd1 ~]# etcdctl lease revoke 3c3a9a4cb766152e
lease 3c3a9a4cb766152e revoked
# 续约撤销并退出
[root@etcd1 ~]# etcdctl lease keep-alive 3c3a9a4cb766152e
lease 3c3a9a4cb766152e keepalived with TTL(60)
lease 3c3a9a4cb766152e expired or revoked.
# 返回为空
[root@etcd1 ~]# etcdctl get zoo1
六、备份恢复命令
- 主要用于管理节点的快照,其主要用法如下所示:
etcdctl snapshot <subcommand> [flags]
6.1、生成快照
- 其主要用法如下所示:
etcdctl snapshot save <filename> [flags]
- 示例如下所示:
etcdctl snapshot save etcd-snapshot.db
6.2、查看快照
- 其主要用法如下所示:
etcdctl snapshot status <filename> [flags]
- 示例如下所示:
etcdctl snapshot status etcd-snapshot.db -w table
6.3、恢复快照
- 其主要用法如下所示:
etcdctl snapshot restore <filename> [options] [flags]
6.4、备份恢复演示
- 新建一个名为name 的key
[root@etcd1 ~]# etcdctl put name wzh
OK
[root@etcd1 ~]# etcdctl get name
name
wzh
[root@etcd1 ~]# etcdctl endpoint status -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 33 kB | true | false | 2 | 45 | 45 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 25 kB | false | false | 2 | 45 | 45 | |
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 29 kB | false | false | 2 | 45 | 45 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
- 生成快照,创建名为snap.db的备份文件
[root@etcd1 ~]# etcdctl snapshot save snap.db --endpoints=http://192.168.93.101:2379
{"level":"info","ts":1762233834.5750756,"caller":"snapshot/v3_snapshot.go:119","msg":"created temporary db file","path":"snap.db.part"}
{"level":"info","ts":"2025-11-04T13:23:54.575+0800","caller":"clientv3/maintenance.go:200","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":1762233834.5759904,"caller":"snapshot/v3_snapshot.go:127","msg":"fetching snapshot","endpoint":"http://192.168.93.101:2379"}
{"level":"info","ts":"2025-11-04T13:23:54.576+0800","caller":"clientv3/maintenance.go:208","msg":"completed snapshot read; closing"}
{"level":"info","ts":1762233834.5780404,"caller":"snapshot/v3_snapshot.go:142","msg":"fetched snapshot","endpoint":"http://192.168.93.101:2379","size":"33 kB","took":0.002909912}
{"level":"info","ts":1762233834.57811,"caller":"snapshot/v3_snapshot.go:152","msg":"saved","path":"snap.db"}
- 查看备份文件详情
[root@etcd1 ~]# ls -lh snap.db
-rw------- 1 root root 33K 11月 4 13:23 snap.db
[root@etcd1 ~]# etcdctl snapshot status snap.db -w table
+--------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+--------+----------+------------+------------+
| 28ac4c | 30 | 36 | 33 kB |
+--------+----------+------------+------------+
- 把快照文件传到其他节点
[root@etcd1 ~]# scp snap.db root@192.168.93.102:/root
[root@etcd1 ~]# scp snap.db root@192.168.93.103:/root
- 停止所有节点的etcd服务,并删除数据目录
# 所有节点都要执行
systemctl stop etcd
# 删除数据
rm -rf /data/etcd/
- 在所有节点上开始恢复数据
# etcd1
[root@etcd1 ~]# etcdctl snapshot restore snap.db --name=etcd1 --data-dir=/data/etcd --initial-cluster=etcd1=http://192.168.93.101:2380,etcd2=http://192.168.93.102:2380,etcd3=http://192.168.93.103:2380 --initial-advertise-peer-urls=http://192.168.93.101:2380
{"level":"info","ts":1762234209.7733314,"caller":"snapshot/v3_snapshot.go:296","msg":"restoring snapshot","path":"snap.db","wal-dir":"/data/etcd/member/wal","data-dir":"/data/etcd","snap-dir":"/data/etcd/member/snap"}
{"level":"info","ts":1762234209.7786083,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"3d33f92152eaee46","added-peer-peer-urls":["http://192.168.93.103:2380"]}
{"level":"info","ts":1762234209.778708,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"5abc4e842d3ab1d6","added-peer-peer-urls":["http://192.168.93.102:2380"]}
{"level":"info","ts":1762234209.7787428,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"f416c4d7e7853c3a","added-peer-peer-urls":["http://192.168.93.101:2380"]}
{"level":"info","ts":1762234209.7882888,"caller":"snapshot/v3_snapshot.go:309","msg":"restored snapshot","path":"snap.db","wal-dir":"/data/etcd/member/wal","data-dir":"/data/etcd","snap-dir":"/data/etcd/member/snap"}
# etcd2
[root@etcd2 ~]# etcdctl snapshot restore snap.db --name=etcd2 --data-dir=/data/etcd --initial-cluster=etcd1=http://192.168.93.101:2380,etcd2=http://192.168.93.102:2380,etcd3=http://192.168.93.103:2380 --initial-advertise-peer-urls=http://192.168.93.102:2380
{"level":"info","ts":1762234209.7753522,"caller":"snapshot/v3_snapshot.go:296","msg":"restoring snapshot","path":"snap.db","wal-dir":"/data/etcd/member/wal","data-dir":"/data/etcd","snap-dir":"/data/etcd/member/snap"}
{"level":"info","ts":1762234209.7921374,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"3d33f92152eaee46","added-peer-peer-urls":["http://192.168.93.103:2380"]}
{"level":"info","ts":1762234209.7922328,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"5abc4e842d3ab1d6","added-peer-peer-urls":["http://192.168.93.102:2380"]}
{"level":"info","ts":1762234209.7922487,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"f416c4d7e7853c3a","added-peer-peer-urls":["http://192.168.93.101:2380"]}
{"level":"info","ts":1762234209.7970464,"caller":"snapshot/v3_snapshot.go:309","msg":"restored snapshot","path":"snap.db","wal-dir":"/data/etcd/member/wal","data-dir":"/data/etcd","snap-dir":"/data/etcd/member/snap"}
# etcd3
[root@etcd3 ~]# etcdctl snapshot restore snap.db --name=etcd3 --data-dir=/data/etcd --initial-cluster=etcd1=http://192.168.93.101:2380,etcd2=http://192.168.93.102:2380,etcd3=http://192.168.93.103:2380 --initial-advertise-peer-urls=http://192.168.93.103:2380
{"level":"info","ts":1762234209.7737963,"caller":"snapshot/v3_snapshot.go:296","msg":"restoring snapshot","path":"snap.db","wal-dir":"/data/etcd/member/wal","data-dir":"/data/etcd","snap-dir":"/data/etcd/member/snap"}
{"level":"info","ts":1762234209.7843802,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"3d33f92152eaee46","added-peer-peer-urls":["http://192.168.93.103:2380"]}
{"level":"info","ts":1762234209.7845335,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"5abc4e842d3ab1d6","added-peer-peer-urls":["http://192.168.93.102:2380"]}
{"level":"info","ts":1762234209.7845669,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"b59d820ff8caf3f4","local-member-id":"0","added-peer-id":"f416c4d7e7853c3a","added-peer-peer-urls":["http://192.168.93.101:2380"]}
{"level":"info","ts":1762234209.7922416,"caller":"snapshot/v3_snapshot.go:309","msg":"restored snapshot","path":"snap.db","wal-dir":"/data/etcd/member/wal","data-dir":"/data/etcd","snap-dir":"/data/etcd/member/snap"}
- 所有节点重启etcd服务
systemctl restart etcd
- 查看验证
[root@etcd1 ~]# etcdctl endpoint status -w table --endpoints=http://192.168.93.101:2379,http://192.168.93.102:2379,http://192.168.93.103:2379
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.93.101:2379 | f416c4d7e7853c3a | 3.4.23 | 33 kB | true | false | 2 | 8 | 8 | |
| http://192.168.93.102:2379 | 5abc4e842d3ab1d6 | 3.4.23 | 33 kB | false | false | 2 | 8 | 8 | |
| http://192.168.93.103:2379 | 3d33f92152eaee46 | 3.4.23 | 33 kB | false | false | 2 | 8 | 8 | |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
- 重启etcd后,仍能正常获取name的值,并且节点ID未发生改变
七、用户管理命令
- etcd默认是没有开启访问控制的,如果开启外网访问etcd的话就需要考虑访问控制的问题,etcd提供了两种访问控制的方式:
- 基于身份验证的访问控制
- 基于证书的访问控制
- 从v3.2版本开始,如果使用参数-- client-cert-auth=true启动etcdu武器,则客户端的TLS证书红的“通用名称(CN)”字段将用作etcd用户。在这种情况下,公用名将对用户进行身份验证,并且客户端不需要密码。如果同时传递了–client-cert-auth=true且客户端提供了CN,并且客户端提供了用户名和密码,则将优先考虑基于用户名和密码的身份验证。
- etcd有一个特殊用户root和一个特殊角色root:
- root用户:root用户是etcd角色的超级管理员,拥有etcd的所有权限,在开启角色认证之前必须要先建立好root用户
- root角色:具有该root角色的用户既具有全局读写访问权限,具有更新集群的身份验证配置和权限。此外,该root角色还授予常规集群维护的特权,包括修改集群成员资格,对存储进行碎片整理以及拍摄快照。
- etcd的权限资源:
- Users:user用来设置身份认证(user:passwd),一个用户可以拥有多个角色,每个角色被分配一定的权限(只读、只写、可读写),用户分为root用户和非root用户。
- Roles:角色用来关联权限,角色主要三类:
- root角色:默认创建root用户时即创建了root角色,该角色拥有所有权限;
- guest角色:默认自动创建,主要用于非认证使用。普通角色,由root用户创建角色,并分配指定权限。
- Permissions:权限分为只读、只写、可读写三种权限,权限即对指定目录或key的读写权限。
- 如果没有指定任何验证方式,即未显示指定以什么用户进行访问,那么会默认会设置为guest角色。默认情况下guest也是具有全局访问权限的。
7.1、用户管理
- 其主要用法如下所示:
etcdctl user <subcommand> [flags]
- 其主要子命令主要如下所示:
| 子命令 | 常用用法 | 功能描述 |
|---|---|---|
| add | etcdctl user add < user name or user:password > [options] [flags] | 添加新用户 |
| delete | etcdctl user delete < user name > [flags] | 删除用户 |
| list | etcdctl user list [flags] | 列出所有用户 |
| get | etcdctl user get < user name [options] [flags] | 获取用户详细信息 |
| passwd | etcdctl user passwd < user name > [options] [flags] | 修改密码 |
| grant-role | etcdctl user grant-role < user name > < role name > [flags] | 赋予用户角色 |
| revoke-role | etcdctl user revoke-role < user name > < role name > [flags] |
7.2、角色管理
- 其主要用法如下所示:
etcdctl role <subcommand> [flags]
- 其主要子命令主要如下所示:
| 子命令 | 常用用法 | 功能描述 |
|---|---|---|
| add | etcdctl role add < role name [flags] | 添加角色 |
| delete | etcdctl role delete [flags] | 删除角色 |
| list | etcdctl role list [flags] | 列出所有角色 |
| get | etcdctl role get [flags] | 获取角色详情 |
| grant-permission | etcdctl role grant-permission [options] < role name > < permission tye > < < key > > [endkey] [flags] | 把key操作权限授予一个角色 |
| revoke-permission | etcdctl role revoke-permission < role name > < key > [endkey] [flags] |
7.3、开启root身份验证
- 在开启身份验证后,注意事项如下所示:
- 开启身份验证:所有etcdctl命令操作都需要指定用户参数–user,参数值为用户名:密码
- 开启证书验证:所有etcdctl命令操作都需要添加证书参数–cacert
- 开启root身份验证的步骤如下所示:
# 添加 root 用户, 密码为 123456
[root@etcd1 ~]# etcdctl user add root:123456
User root created
# 开启身份验证, 开启为 enable, 取消为 disable
[root@etcd1 ~]# etcdctl auth enable --user=root:123456
{"level":"warn","ts":"2025-11-04T15:45:30.570+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-a1a91c15-df9d-4e6f-80d3-7f388e9188f4/127.0.0.1:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: authentication is not enabled"}
{"level":"warn","ts":"2025-11-04T15:45:30.575+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-a1a91c15-df9d-4e6f-80d3-7f388e9188f4/127.0.0.1:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: root user does not have root role"}
Authentication Enabled
# 开启身份验证后, 直接获取键值报错
[root@etcd1 ~]# etcdctl get name
{"level":"warn","ts":"2025-11-04T15:47:25.710+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-09b2c5c3-3be4-45f9-8465-cb85c80dfc80/127.0.0.1:2379","attempt":0,"error":"rpc error: code = InvalidArgument desc = etcdserver: user name is empty"}
Error: etcdserver: user name is empty
# 添加用户信息访问
[root@etcd1 ~]# etcdctl get name --user=root:123456
name
wzh
7.4、角色授权
- 在开启了root身份验证后,就可以对普通用户和角色操作了
7.4.1、用户增删改查
# 添加普通
[root@etcd1 ~]# etcdctl user add test:123 --user=root:123456
User test created
# 用户用户信息
[root@etcd1 ~]# etcdctl user get test --user=root:123456
User: test
Roles:
# 查看所有用户
[root@etcd1 ~]# etcdctl user list --user=root:123456
root
test
# 修改用户密码
[root@etcd1 ~]# etcdctl user passwd test --user=root:123456
Password of test:
Type password of test again for confirmation:
Password updated
# 删除用户
[root@etcd1 ~]# etcdctl user delete test --user=root:123456
User test deleted
7.4.2、用户角色绑定
# 增加普通用户
[root@etcd1 ~]# etcdctl user add test:123 --user=root:123456
User test created
# 添加角色
[root@etcd1 ~]# etcdctl role add test-role --user=root:123456
Role test-role created
# 将角色绑定给指定用户
[root@etcd1 ~]# etcdctl user grant-role test test-role --user=root:123456
Role test-role is granted to user test
# 查看用户信息
[root@etcd1 ~]# etcdctl user get test --user=root:123456
User: test
Roles: test-role
7.4.3、角色授权
- 权限分为:只读(read),只写(write)和读写(readwrite)权限
# 使用 test 用户获取 name 值会报错, 权限拒绝
[root@etcd1 ~]# etcdctl get name --user=test:123
{"level":"warn","ts":"2025-11-04T16:00:59.605+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-af949a12-8f25-4070-8fef-b7bad516d71b/127.0.0.1:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
# 按 key 进行授权, test-role 角色可以读写 name
[root@etcd1 ~]# etcdctl role grant-permission test-role readwrite name --user=root:123456
Role test-role updated
# 查看角色权限详情
[root@etcd1 ~]# etcdctl role get test-role --user=root:123456
Role test-role
KV Read:
name
KV Write:
name
# 撤销角色权限
[root@etcd1 ~]# etcdctl role revoke-permission test-role name --user=root:123456
Permission of key name is revoked from role test-role
# 查看角色权限详情
[root@etcd1 ~]# etcdctl role get test-role --user=root:123456
Role test-role
KV Read:
KV Write:
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐



所有评论(0)