etcdctl 是一个 etcd 命令行工具,通过它可以与 etcd 集群进行交互。这篇文章总结下 etcdctl 的使用方法。
通用说明
当前 etcdctl 默认使用 v3 API 和 etcd 通信。如果想要使用 v2 API,可以设置环境变量:ETCDCTL_API=2
。
所有的命令都可以通过 -w
或 --write-out
选项设置输出格式。支持的输出格式有 simple
、json
、Protobuf
、Fields
所有命令默认都是 simple
输出。如果一个命令有对应的 RPC,那么它可以接受所有输出格式
如果命令执行失败,返回非 0 退出码,同时会输出错误字符串信息,此时输出格式不生效
Key-value 命令 设置 key 命令语法:
1 PUT [options] <key> <value>
为指定 key 设置 value
对应的 RPC: Put
通用选项:
--lease <lease ID>
:设置 key 所使用的租约 ID
--prev-kv
:返回该 key 修改之前的值
ignore-value
:使用当前值更新 key
ignore-lease
:使用当前 lease 更新 key
示例:
1 2 3 4 5 $ etcdctl put foo bar OK $ etcdctl get foo foo bar
1 2 3 4 5 6 7 $ etcdctl put foo bar1 --prev-kv OK foo bar $ etcdctl get foo foo bar1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 $etcdctl put foo --ignore-valueOK $ etcdctl get foo foo bar1 $ etcdctl get foo -w fields "ClusterID" : 10316109323310759371"MemberID" : 12530464223947363063"Revision" : 4"RaftTerm" : 2"Key" : "foo" "CreateRevision" : 2"ModRevision" : 4"Version" : 3"Value" : "bar1" "Lease" : 0"More" : false "Count" : 1$ etcdctl put foo --ignore-value OK // 可以看到,虽然值没有变,但是其 ModRevision 发生了改变 $ etcdctl get foo -w fields "ClusterID" : 10316109323310759371"MemberID" : 12530464223947363063"Revision" : 5"RaftTerm" : 2"Key" : "foo" "CreateRevision" : 2"ModRevision" : 5"Version" : 4"Value" : "bar1" "Lease" : 0"More" : false "Count" : 1
注意事项:
如果想在 value 中包含换行符,需要在输入时使用 ""
引用输入的内容。
如果输入 value 中包含 -
,可以通过如下形式解决,否则 -value
会被当成命令 flag
1 2 ./etcdctl put <key> -- <value> ./etcdctl put -- <key> <value>
例如:
1 2 3 4 5 $ etcdctl put foo3 -- -test OK $ etcdctl get foo3 foo3 -test
获取 key 命令语法:
1 GET [options] <key> [range_end]
用于获取某个 key 或某个 key 范围 [key, range_end)
对应的 RPC:Range
常用选项:
--hex
:以十六进制输出 key/value
--limit <number>
:限制输出结果的个数
--prefix
:通过前缀匹配获取 key
--order
:对结果排序,ASCEND 或 DESCEND
sort-by
:设置排序依据,可以是 CREATE、KEY、MODIFY、VALUE 或 VERSION
--rev <revision>
:指定 KV 版本
--print-value-only
:只输出值
--consistency
:一致性,可以是 Linearizable 或 Serializable
from-key
:获取大于等于指定 key 的所有 key(通过字节比较排序)
keys-only
:只输出 key
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 $ etcdctl get foo foo bar1 $ etcdctl get foo foo2 foo bar1 foo1 bar1 $ etcdctl get foo foo2 --limit 1 foo bar1 $ etcdctl get foo --prefix foo bar1 foo1 bar1 foo2 barnew foo3 -test4 $ etcdctl get foo foo2 --order DESCEND --sort-by MODIFY foo1 bar1 foo bar1 $ etcdctl get foo foo2 --print-value-only bar1 bar1 $ etcdctl get foo --from-key foo bar1 foo1 bar1 foo2 barnew foo3 -test4 $ etcdctl get foo --from-key --keys-only foo foo1 foo2 foo3
注意事项:
可以通过 etcdctl get --from-key ''
获取所有的 key
当 key 或 value 中有不可打印字符或者控制字符,此时输出可能会引入混淆,为了解决该问题,可以使用 --hex
进行输出
删除 key 命令语法:
1 DEL [options] <key> [range_end]
移除指定的 key 或 key 范围
对应的 RPC 方法:DeleteRange
如果删除成功,返回删除的元素个数
常用选项:
--prefix
:通过前缀匹配指定 key
--prev-kv
:返回删除的 key-value 对
--from-key
:删除大于等于指定 key 的所有 key(通过字节比较排序)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ etcdctl del foo 1 $ etcdctl del foo foo1 0 $ etcdctl del foo foo2 1 $ etcdctl del foo2 --prev-kv 1 foo2 barnew $ etcdctl del foo2 --from-key 1 $ etcdctl del foo2 --prefix 0
事务 命令语法:
TXN 从标准输入中读取多个请求,并将它们应用到单个原子的事务操作中。一个事务包含 一系列的条件
、所有条件都满足时要执行的一系列请求
、任意条件不满足时要执行的一系列请求
对应的 RPC:Txn
TXN 的语法为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <Txn> ::= <CMP>* "\n" <THEN> "\n" <ELSE> "\n" <CMP> ::= (<CMPCREATE>|<CMPMOD>|<CMPVAL>|<CMPVER>|<CMPLEASE>) "\n" <CMPOP> ::= "<" | "=" | ">" <CMPCREATE> := ("c" |"create" )"(" <KEY>")" <CMPOP> <REVISION> <CMPMOD> ::= ("m" |"mod" )"(" <KEY>")" <CMPOP> <REVISION> <CMPVAL> ::= ("val" |"value" )"(" <KEY>")" <CMPOP> <VALUE> <CMPVER> ::= ("ver" |"version" )"(" <KEY>")" <CMPOP> <VERSION> <CMPLEASE> ::= "lease(" <KEY>")" <CMPOP> <LEASE> <THEN> ::= <OP>* <ELSE> ::= <OP>* <OP> ::= ((see put, get, del etcdctl command syntax)) "\n" <KEY> ::= (%q formatted string) <VALUE> ::= (%q formatted string) <REVISION> ::= "\"" [0-9]+"\"" <VERSION> ::= "\"" [0-9]+"\"" <LEASE> ::= "\"" [0-9]+\""
如果执行的是事务成功条件下的命令列表,输出 SUCCESS
,否则输出 FAILURE
。同时会输出命令列表中的每个命令的结果,以空行分隔。
常用选项:
--hex
:以十六进制输出 key 和 value
--interactive
:以交互模式执行 input transaction
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ etcdctl txn -i compares: mod("key1" ) > "0" success requests (get, put, del): put key1 "overwrote-key1" failure requests (get, put, del): put key1 "created-key1" put key2 "some extra key" FAILURE OK OK $ etcdctl get key1 key1 created-key1 $ etcdctl get key2 key2 some extra key
注意事项:
由于在 TXN 中通过换行符来分隔事务命令,因此如果 TXN 命令中如果本身需要输入换行符,则必须使用 \n
。
压缩 命令语法:
1 COMPACTION [options] <revision>
compaction 命令用于丢弃给定 revision 之前的所有 etcd 事件历史。由于 etcd 使用多版本并发控制模型,它会以事件历史的形式保存所有的 key 更新记录。当给定 revision 之前的事件历史不再需要时候,此时可以对 key 进行压缩以释放 etcd 后端数据存储空间
对应的 RPC 方法:Compact
常用选项:
--physical
:等待 compaction 操作物理移除所有旧的 revisions
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ etcdctl put key value1 -w fields "ClusterID" : 10316109323310759371"MemberID" : 12530464223947363063"Revision" : 21"RaftTerm" : 2$ etcdctl put key value2 -w fields "ClusterID" : 10316109323310759371"MemberID" : 12530464223947363063"Revision" : 22"RaftTerm" : 2$ etcdctl compact 22 compacted revision 22 I have no name!@9008eb121933:/opt/bitnami/etcd$ etcdctl get key key value2 $ etcdctl get key --rev 22 key value2 $ etcdctl get key --rev 21 {"level" :"warn" ,"ts" :"2022-02-23T11:34:26.239Z" ,"logger" :"etcd-client" ,"caller" :"v3/retry_interceptor.go:62" ,"msg" :"retrying of unary invoker failed" ,"target" :"etcd-endpoints://0xc00023e000/127.0.0.1:2379" ,"attempt" :0,"error" :"rpc error: code = OutOfRange desc = etcdserver: mvcc: required revision has been compacted" } Error: etcdserver: mvcc: required revision has been compacted
WATCH 命令语法:
1 WATCH [options] [key or prefix] [range_end] [--] [exec-command arg1 arg2 ...]
通过 Watch
命令可以监控指定 key、前缀、key 范围的事件流。watch
命令会持续运行,直到出现错误或终端用户手动终止
对应的 RPC 方法:Watch
输出的格式为:
1 <event>[\n<old_key>\n<old_value>]\n<key>\n<value>\n<event>\n<next_key>\n<next_value>\n...
常用选项:
--hex
:以十六进制输出 key 和 value
--interactive
:开始交互式的 watch
--prefix
:按前缀进行 watch
--prev-kv
:输出之前的 key-value 值
--rev
:从指定的 revision 开始 watch,这可以使得我们获得之间的事件
示例:
1 2 3 4 5 6 7 8 9 $ etcdctl watch foo $ etcdctl put foo bar OK $ etcdctl watch foo PUT foo bar
1 2 3 4 5 6 7 8 $ etcdctl put foo bar2 $ etcdctl watch foo --prev-kv PUT foo bar foo bar2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ etcdctl put foo bar3 OK $ etcdctl put foo3 bar3 OK $ etcdctl put foo1 bar1 OK $ etcdctl watch foo foo2 PUT foo bar3 PUT foo1 bar1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 $ etcdctl put foo bar4 -w fields "ClusterID" : 10316109323310759371"MemberID" : 15168875803774599630"Revision" : 33"RaftTerm" : 2$ etcdctl put foo bar5 -w fields "ClusterID" : 10316109323310759371"MemberID" : 15168875803774599630"Revision" : 34"RaftTerm" : 2$ etcdctl put foo bar6 -w fields "ClusterID" : 10316109323310759371"MemberID" : 15168875803774599630"Revision" : 35"RaftTerm" : 2$ etcdctl watch foo --rev 34 PUT foo bar5 PUT foo bar6 $ etcdctl watch foo --rev 35 PUT foo bar6
如果想在收到事件后执行命令,可以通过 [--] [exec-command arg1 arg2 ...]
的方式指定,例如在收到事件后,执行 echo watch event received
:
1 2 3 4 5 6 7 8 9 10 $ etcdctl watch foo -- echo watch event received $ etcdctl put foo bar OK $ etcdctl watch foo -- echo watch event received PUT foo bar watch event received
watch 的响应会通过环境变量 ETCD_WATCH_*
设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ etcdctl put foo bar $ etcdctl watch foo -- sh -c "env | grep ETCD_WATCH_" PUT foo bar ETCD_WATCH_REVISION=25 ETCD_WATCH_KEY="foo" ETCD_WATCH_EVENT_TYPE="PUT" ETCD_WATCH_VALUE="bar" DELETE foo $ etcdctl del foo ETCD_WATCH_REVISION=26 ETCD_WATCH_KEY="foo" ETCD_WATCH_EVENT_TYPE="DELETE" ETCD_WATCH_VALUE=""
租约 创建租约 命令语法:
新建一个租约,租约的到期时间为 ttl
秒
对应的 RPC:LeaseGrant
输出创建的租约 ID
示例:
1 2 3 4 5 6 7 8 $ etcdctl lease grant 20 lease 12f77f2076d86f50 granted with TTL(20s) $ etcdctl put foo bar --lease 12f77f2076d86f50 OK $ etcdctl get foo foo bar $ etcdctl get foo
释放租约 命令语法:
释放一个指定的租约,并删除该租约关联的所有 keys
对应的 RPC:LeaseRevoke
示例:
1 2 3 4 5 6 7 8 9 10 $ etcdctl lease grant 600 lease 12f77f2076d86f60 granted with TTL(600s) $ etcdctl put foo bar --lease 12f77f2076d86f60 OK $ etcdctl get foo foo bar $ etcdctl lease revoke 12f77f2076d86f60 lease 12f77f2076d86f60 revoked $ etcdctl get foo
获取租约 命令语法:
1 LEASE TIMETOLIVE <leaseID> [options]
获取指定租约的信息
对应的 RPC 方法:LeaseTimeToLive
常用选项:
示例:
1 2 3 4 5 6 7 8 9 10 11 $ etcdctl lease grant 600 lease 12f77f2076d86f66 granted with TTL(600s) $ etcdctl put foo bar --lease 12f77f2076d86f66 OK $ etcdctl lease timetolive 12f77f2076d86f66 lease 12f77f2076d86f66 granted with TTL(600s), remaining(572s) $ etcdctl lease timetolive 12f77f2076d86f66 --keys lease 12f77f2076d86f66 granted with TTL(600s), remaining(566s), attached keys([foo]) $ etcdctl put foo1 bar1 --lease 12f77f2076d86f66 $ etcdctl lease timetolive 12f77f2076d86f66 --keys lease 12f77f2076d86f66 granted with TTL(600s), remaining(462s), attached keys([foo foo1])
获取租约列表 命令语法:
列出所有的 lease
对应的 RPC 方法:LeaseLeases
示例:
1 2 3 $ etcdctl lease list found 1 leases 12f77f2076d86f66
续约 命令语法:
1 LEASE KEEP-ALIVE <leaseID>
LEASE KEEP-ALIVE 周期性地对指定租约进行续约,因此该 lease 不会过期
示例:
1 2 3 4 5 6 7 8 $ etcdctl lease timetolive 12f77f2076d86f66 lease 12f77f2076d86f66 granted with TTL(600s), remaining(234s) $ etcdctl lease keep-alive 12f77f2076d86f66 lease 12f77f2076d86f66 keepalived with TTL(600) $ etcdctl lease timetolive 12f77f2076d86f66 lease 12f77f2076d86f66 granted with TTL(600s), remaining(556s)
集群维护命令 成员管理 成员管理命令用于管理 etcd 集群中的成员关系。
添加成员 命令语法:
1 MEMBER ADD <memberName> [options]
在 etcd 集群中新添加一个成员
输出新成员的成员 ID 以及其所在的 cluster ID
对应的 RPC 方法:MemberAdd
常用选项:
peer-urls
:新成员所关联的 peer-urls
,如果包含多个 URL,需要用逗号分隔
示例:
1 2 3 4 5 6 7 $ etcdctl member add newMember --peer-urls=https://etcd4:2380 Member 2833744901904773 added to cluster 8f2a2ec5c0087dcb ETCD_NAME="newMember" ETCD_INITIAL_CLUSTER="newMember=https://etcd4:2380,etcd1=http://etcd1:2380,etcd3=http://etcd3:2380,etcd2=http://etcd2:2380" ETCD_INITIAL_ADVERTISE_PEER_URLS="https://etcd4:2380" ETCD_INITIAL_CLUSTER_STATE="existing"
更新成员 命令语法:
1 MEMBER UPDATE <memberID> [options]
对 etcd 集群中的 member 进行更新,只能更新 peer URLs
输出更新的成员 ID 以及其所在的 cluster ID
对应的 RPC 方法:MemberUpdate
常用选项:
--peer-urls
:成员所关联的 peer-urls
,如果包含多个 URL,需要用逗号分隔
示例:
1 2 $ etcdctl member update 2833744901904773 --peer-urls=https://etcd4:2380 Member 2833744901904773 updated in cluster 8f2a2ec5c0087dcb
移除成员 命令语法:
1 MEMBER REMOVE <memberID>
从 etcd 集群中移除成员
输出删除的成员 ID 以及其所在的 cluster ID。
对应的 RPC 方法:MEMBER REMOVE
示例:
1 2 $ etcdctl member remove 2833744901904773 Member 2833744901904773 removed from cluster 8f2a2ec5c0087dcb
列出成员 命令语法:
示例:
1 2 3 4 $ etcdctl member list ade526d28b1f92f7, started, etcd1, http://etcd1:2380, http://etcd1:2379, false bd388e7810915853, started, etcd3, http://etcd3:2380, http://etcd3:2379, false d282ac2ce600c1ce, started, etcd2, http://etcd2:2380, http://etcd2:2379, false
ENDPOINT 命令 ENDPOINT
命令用于查询独立的 endpoints。
节点健康信息 命令语法:
用于检查 cluster 集群中 endpoint
列表的健康情况。如果某个 endpoint 无法与集群的其他节点达成一致,就认为该节点是不健康的
常用选项:
--cluster
:使用 etcd 集群中的所有成员
示例:
1 2 3 $ etcdctl endpoint health 127.0.0.1:2379 is healthy: successfully committed proposal: took = 8.8908ms
1 2 3 4 5 $ etcdctl endpoint --cluster health http://etcd2:2379 is healthy: successfully committed proposal: took = 9.1295ms http://etcd3:2379 is healthy: successfully committed proposal: took = 8.031ms http://etcd1:2379 is healthy: successfully committed proposal: took = 25.7359ms
节点状态 命令语法:
ENDPOINT STATUS
用来查询给定 endpoint
列表中每个 endpoint 的状态。
示例:
1 2 3 4 5 6 7 $ etcdctl endpoint status 127.0.0.1:2379, ade526d28b1f92f7, 3.5.2, 25 kB, false , false , 2, 85, 85, $ etcdctl endpoint status --cluster http://etcd1:2379, ade526d28b1f92f7, 3.5.2, 25 kB, false , false , 2, 85, 85, http://etcd3:2379, bd388e7810915853, 3.5.2, 25 kB, true , false , 2, 85, 85, http://etcd2:2379, d282ac2ce600c1ce, 3.5.2, 25 kB, false , false , 2, 85, 85,
节点 HASHKV 命令语法:
ENDPOINT HASHKV
用于获取某个 endpoint KV 存储的 hash 值
示例:
1 2 3 4 5 6 7 $ etcdctl endpoint hashkv 127.0.0.1:2379, 2755762864 $ etcdctl endpoint hashkv --cluster http://etcd1:2379, 2755762864 http://etcd3:2379, 2755762864 http://etcd2:2379, 2755762864
ALARM 命令 提供告警相关的命令。
解除警告 命令语法:
解除所有的告警
对应的 RPC 方法: Alarm
示例:
列出警告
列出所有的告警
对应的 RPC 方法为 Alarm
示例:
碎片整理 DEFRAG 命令可以在 etcd 运行时为一系列 endpoint 整理后端数据库文件的碎片。当 etcd member 删除或压缩 keys 时,这些 keys 占用的空间仍然会被占用。通过对数据库进行碎片整理,etcd 成员可以把这些空间归还给文件系统。
需要注意,在某个成员上进行在线的碎片整理会阻塞系统的读写。碎片整理操作默认不会在集群中传播,它只会应用于 local node。可以通过 --endpoints
指定集群成员,或者使用 --cluster
标志来指定所有集群成员。
如果想使用离线碎片整理(–data-dir flag),可以使用 etcutl defrag
。
示例:
1 2 3 4 etcdctl --endpoints=localhost:2379,badendpoint:2379 defrag Finished defragmenting etcd member[localhost:2379] {"level" :"warn" ,"ts" :"2022-02-24T12:05:08.985Z" ,"logger" :"etcd-client" ,"caller" :"v3/retry_interceptor.go:62" ,"msg" :"retrying of unary invoker failed" ,"target" :"etcd-endpoints://0xc00020e000/localhost:2379" ,"attempt" :0,"error" :"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp: lookup badendpoint on 127.0.0.11:53: no such host\"" } Failed to defragment etcd member[badendpoint:2379] (context deadline exceeded)
1 2 3 4 $ etcdctl defrag --cluster Finished defragmenting etcd member[http://etcd1:2379] Finished defragmenting etcd member[http://etcd3:2379] Finished defragmenting etcd member[http://etcd2:2379]
如果想直接压缩某个数据目录,可以使用 etcdutl
并指定 --data-dir
(该标志马上将被删除)。
快照命令 SNAPSHOT 命令可以用于实现快照。
保存快照 命令语法:
1 SNAPSHOT SAVE <filename>
示例:
1 2 3 4 5 6 7 8 etcdctl snapshot save test.db {"level" :"info" ,"ts" :1645705033.3974695,"caller" :"snapshot/v3_snapshot.go:68" ,"msg" :"created temporary db file" ,"path" :"test.db.part" } {"level" :"info" ,"ts" :1645705033.4031475,"logger" :"client" ,"caller" :"v3/maintenance.go:211" ,"msg" :"opened snapshot stream; downloading" } {"level" :"info" ,"ts" :1645705033.403688,"caller" :"snapshot/v3_snapshot.go:76" ,"msg" :"fetching snapshot" ,"endpoint" :"127.0.0.1:2379" } {"level" :"info" ,"ts" :1645705033.4247742,"logger" :"client" ,"caller" :"v3/maintenance.go:219" ,"msg" :"completed snapshot read; closing" } {"level" :"info" ,"ts" :1645705033.428916,"caller" :"snapshot/v3_snapshot.go:91" ,"msg" :"fetched snapshot" ,"endpoint" :"127.0.0.1:2379" ,"size" :"25 kB" ,"took" :"now" } {"level" :"info" ,"ts" :1645705033.4335535,"caller" :"snapshot/v3_snapshot.go:100" ,"msg" :"saved" ,"path" :"test.db" } Snapshot saved at test.db
恢复快照 命令语法:
1 SNAPSHOT RESTORE [options] <filename>
它根据后端数据库快照以及新的集群配置,为 etcd 集群成员创建一个 etcd 数据目录。为新集群中的每个 member 恢复 snapshot,这样新的 etcd 集群就预先加载了快照数据
该命令即将被遗弃,应该使用 etcdutl snapshot restore
该命令支持的选项基本类似于 etcd 集群命令:
--data-dir <dir>
:数据目录的路径,如果没有指定的话默认使用 <name>.etcd
--wal-dir <dir>
:WAL 目录路径,如果没有指定的话则使用数据目录
--initial-cluster <configuration>
:初始集群配置
initial-cluster-token
:初始 token
initial-advertise-peer-urls
:初始通告的成员 peer URLS
name
:集群成员名称
skip-hash-check
:忽略快照的 hash value
示例:
1 2 3 4 5 6 7 8 9 $ etcdctl snapshot restore test.db --initial-cluster-token etcd-cluster-1 --initial-advertise-peer-urls http://127.0.0.1:12380 --name sshot1 --initial-cluster 'sshot1=http://127.0.0.1:12380,sshot2=http://127.0.0.1:22380,sshot3=http://127.0.0.1:32380' Deprecated: Use `etcdutl snapshot restore` instead. 2022-02-24T13:03:33Z info snapshot/v3_snapshot.go:251 restoring snapshot {"path" : "test.db" , "wal-dir" : "sshot1.etcd/member/wal" , "data-dir" : "sshot1.etcd" , "snap-dir" : "sshot1.etcd/member/snap" , "stack" : "go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\n\t/tmp/etcd-release-3.5.2/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:257\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\n\t/tmp/etcd-release-3.5.2/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\n\t/tmp/etcd-release-3.5.2/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:128\ngithub.com/spf13/cobra.(*Command).execute\n\t/usr/local/google/home/siarkowicz/.gvm/pkgsets/go1.16.3/global/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\t/usr/local/google/home/siarkowicz/.gvm/pkgsets/go1.16.3/global/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\ngithub.com/spf13/cobra.(*Command).Execute\n\t/usr/local/google/home/siarkowicz/.gvm/pkgsets/go1.16.3/global/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\n\t/tmp/etcd-release-3.5.2/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\n\t/tmp/etcd-release-3.5.2/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\nmain.main\n\t/tmp/etcd-release-3.5.2/etcd/release/etcd/etcdctl/main.go:59\nruntime.main\n\t/usr/local/google/home/siarkowicz/.gvm/gos/go1.16.3/src/runtime/proc.go:225" } 2022-02-24T13:03:33Z info membership/store.go:141 Trimming membership information from the backend... 2022-02-24T13:03:33Z info membership/cluster.go:421 added member {"cluster-id" : "ef37ad9dc622a7c4" , "local-member-id" : "0" , "added-peer-id" : "8211f1d0f64f3269" , "added-peer-peer-urls" : ["http://127.0.0.1:12380" ]} 2022-02-24T13:03:33Z info membership/cluster.go:421 added member {"cluster-id" : "ef37ad9dc622a7c4" , "local-member-id" : "0" , "added-peer-id" : "91bc3c398fb3c146" , "added-peer-peer-urls" : ["http://127.0.0.1:22380" ]} 2022-02-24T13:03:33Z info membership/cluster.go:421 added member {"cluster-id" : "ef37ad9dc622a7c4" , "local-member-id" : "0" , "added-peer-id" : "fd422379fda50e48" , "added-peer-peer-urls" : ["http://127.0.0.1:32380" ]} 2022-02-24T13:03:33Z info snapshot/v3_snapshot.go:272 restored snapshot {"path" : "test.db" , "wal-dir" : "sshot1.etcd/member/wal" , "data-dir" : "sshot1.etcd" , "snap-dir" : "sshot1.etcd/member/snap" }
1 etcd --name sshot1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 &
查快快照 命令语法:
1 SNAPSHOT STATUS <filename>
示例:
1 2 3 4 $ etcdctl snapshot status test.db Deprecated: Use `etcdutl snapshot status` instead. dc4be536, 48, 43, 25 kB
1 2 3 4 5 6 7 8 etcdctl snapshot status test.db -w table Deprecated: Use `etcdutl snapshot status` instead. +----------+----------+------------+------------+ | HASH | REVISION | TOTAL KEYS | TOTAL SIZE | +----------+----------+------------+------------+ | dc4be536 | 48 | 43 | 25 kB | +----------+----------+------------+------------+
MOVE-LEADER 命令语法:
示例:
1 2 3 4 5 6 7 8 9 10 11 12 $ etcdctl endpoint status --cluster http://etcd1:2379, ade526d28b1f92f7, 3.5.2, 25 kB, false , false , 2, 89, 89, http://etcd3:2379, bd388e7810915853, 3.5.2, 25 kB, true , false , 2, 89, 89, http://etcd2:2379, d282ac2ce600c1ce, 3.5.2, 25 kB, false , false , 2, 89, 89, $ etcdctl endpoint status --cluster | grep -m 1 "false" | awk -F', ' '{print $2}' ade526d28b1f92f7 $ etcdctl move-leader ade526d28b1f92f7 Error: no leader endpoint given at [127.0.0.1:2379] $ etcdctl --endpoints bd388e7810915853 move-leader ade526d28b1f92f7
降级命令 降级在 v3.6 中是实验性质的特性,并不推荐在生产环境中使用。降级命令用于对集群进行降级。通常来说,由于集群版本机制的问题,etcd 成员是不能降级的。
在初始启动后,集群成员对集群版本达成一致。每隔 5 s,leader 会检查所有成员的版本并选择最小的版本。如果新加入的成员,其版本低于当前的集群版本,该成员无法加入集群,这样可以防止集群被降级。而降级命令则允许集群管理员强制对集群进行降级。
降级应该分阶段执行:
执行 etcdctl downgrade validate <TARGET_VERSION>
验证当前集群是否准备好进行降级
etcdctl downgrade enable <TARGET_VERSION>
开始集群降级
对于每个成员
通过检查其 log 中是否包含 The server is ready to downgrade
来确认成员准备好执行降级
替换成员的二进制版本
确认每个成员都正确启动并加入集群
通过检查 leader log 中是否包含 The server is ready to downgrade
来确认降级是否成功
降级校验 命令语法:
1 DOWNGRADE VALIDATE <TARGET_VERSION>
启动降级 命令语法:
1 DOWNGRADE ENABLE <TARGET_VERSION>
取消降级 命令语法:
1 DOWNGRADE CANCEL <TARGET_VERSION>
并发命令 LOCK 命令 命令语法:
1 LOCK [options] <lockname> [command arg1 arg2 ...]
获取一个分布式锁,该锁的名称由 lockname
指定。一旦 lock 获取到后,该锁一直会被持有,直到 etcdctl 命令终止
如果 lock 获取到,同时没有指定要执行的命令,那么会输出则会输出该 lock 的 KEY
如果 lock 获取到,同时指定了要执行的命令,那么换将变量 ETCD_LOCK_KEY
和 ETCD_LOCK_KEY
会输出成 lock 的 key 和 revision
常用选项:
示例:
1 2 3 4 5 $ etcdctl lock mylock mylock/12f77f2076d86fa0 $ etcdctl lock mylock etcdctl put foo bar OK
注意事项:
只有当 LOCK 命令是通过信号终止,并释放 lock 之后,LOCK 命令的退出码才是 0
如果 LOCK 命令是异常终止,或者无法让集群释放锁时,该 lock 会一直被占有,直到租约过期(60s)
ELECT 命令 命令语法:
1 ELECT [options] <election-name> [proposal]
ELECT 命令用于参加一个命名选举。通过在 ELECT 命令中提供一个 prososal
值,来表明本节点参与本选举
如果只是想观察选举,不用提供 prososal
值,但是需要使用 listen
选项
无论何时 leader 被选举后,它的 prososal
值都会被打印出来
对于候选人,如果该节点赢得了选举,会输出对应的 key 信息。如果是观察选举,ELECT 命令会持续输出选举的结果
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ etcdctl elect myelection etcd1 myelection/12f77f2076d86fb4 etcd1 $ etcdctl elect myelection etcd2 $ etcdctl elect myelection -l myelection/12f77f2076d86fb4 etcd1 $ etcdctl elect myelection etcd2 myelection/41ce7f2076d86923 etcd2 $ etcdctl elect myelection -l myelection/12f77f2076d86fb4 etcd1 myelection/41ce7f2076d86923 etcd2
注意事项:
只有当 ELECT 命令是通过信号终止,并释放其候选人/领导者身份的时候,ELECT 命令的退出码才是 0
如果候选人是异常终止,那么该选举过程会一直持续,直到默认租约过期(60s)
认证命令 开启/关闭认证 命令语法:
1 AUTH <enable or disable >
用于开启或关闭 etcd 集群的认证机制。当开启 etcd 的认证机制的时候,etcd 会对所有请求进行认证检查
对应的 RPC:AuthEnable/AuthDisable
添加角色 命令语法:
创建一个角色
对应的 RPC 方法:RoleAdd
示例:
1 2 $ etcdctl role add test Role test created
获取角色 命令语法:
获取详细的角色信息
对应的 RPC 方法 RoleGet
示例:
1 2 3 4 $ etcdctl role get test Role test KV Read: KV Write:
删除角色 命令语法:
删除指定角色
对应的 RPC 方法: RoleDelete
示例:
1 2 $ etcdctl role delete test Role test deleted
列出角色 命令语法:
列出 etcd 中所有的角色
对应的 RPC 方法:RoleList
示例:
1 2 $ etcdctl role list test
角色授权 命令语法:
1 ROLE GRANT-PERMISSION [options] <role name> <permission type > <key> [endkey]
针对某个 key 或 key 范围,为 role 设置权限
对应的 RPC 方法为 RoleGrantPermission
常用选项:
--from-key
:为大于等于指定 key 的所有 key(通过字节比较排序)进行授权
--preifx
:使用前缀匹配
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ etcdctl role grant-permission test readwrite test_key Role test updated $ etcdctl role get test Role test KV Read: test_key KV Write: test_key $ etcdctl role grant-permission test read foo/ --prefix Role test updated $ etcdctl role get test Role test KV Read: [foo/, foo0) (prefix foo/) test_key KV Write: test_key
取消授权 命令语法:
1 ROLE REVOKE-PERMISSION <role name> <permission type > <key> [endkey]
针对某个 key 或者 key 范围,为 role 撤销权限
对应的 RPC 方法为 RoleRevokePermission
常用选项:
--from-key
:为大于等于指定 key 的所有 key(通过字节比较排序)取消授权
--preifx
:使用前缀匹配
示例:
1 2 3 4 5 6 7 8 9 10 $ etcdctl role revoke-permission test test_key Permission of key test_key is revoked from role test $ etcdctl role revoke-permission test --prefix foo/ Permission of range [foo/, foo0) is revoked from role test $ etcdctl role get test Role test KV Read: KV Write:
添加用户 命令语法:
1 USER ADD <user name or user:password> [options]
添加一个用户
对应的 RPC 方法为:UserAdd
常用选项:
--interactive
:交互模式,从标准输入中读取密码
示例:
1 2 3 4 etcdctl user add test_user Password of test_user: Type password of test_user again for confirmation: User test_user created
获取用户 命令语法:
1 USER GET <user name> [options]
获取指定用户的信息
对应的RPC 方法 UserGet
常用选项:
示例:
1 2 etcdctl user get test_user --detail User: test_user
删除用户 命令语法:
删除指定的用户
对应的 RPC 方法为 UserDelete
示例:
1 2 $ etcdctl user delete test_user User test_user deleted
列出用户 命令语法:
示例:
1 2 $ etcdctl user list test_user
设置密码 命令语法:
1 USER PASSWD <user name> [options]
修改用户的密码
对应的 RPC 方法:UserChangePassword
常用选项:
--interactive
:交互模式,从标准输入中读取密码
示例:
1 2 3 4 $ etcdctl user passwd test_user Password of test_user: Type password of test_user again for confirmation: Password updated
设置用户角色 命令语法:
1 USER GRANT-ROLE <user name> <role name>
为 user 指定角色
对应的 RPC 方法:UserGrantRole
示例:
1 2 $ etcdctl user grant-role test_user test Role test is granted to user test_user
取消用户角色 命令语法:
1 USER REVOKE-ROLE <user name> <role name>
撤销用户的角色
对应的 RPC 方法:UserRevokeRole
示例:
1 2 $ etcdctl user revoke-role test_user test Role test is revoked from user test_user
工具命令 make-mirror 命令语法:
1 MAKE-MIRROR [options] <destination>
将 etcd 集群中的某些 key 映射到另一个 etcd 集群中
常用选项
--dest-cacert <cacert>
:目的集群的 TLS cacert 文件
--dest-cacert <cert>
:目的集群的 TLS cert 文件
--dest-key <key>
:目的集群的 TLS key 文件
--prefix
:按前缀匹配
dest-prefix
:指定在目标集群中的前缀
no-dest-prefix
:在目标集群的 root 下进行 mirror
dest-insecure-transport
:关闭传输层安全
版本 命令语法:
示例:
1 2 3 $ etcdctl version etcdctl version: 3.5.2 API version: 3.5
CHECK 用于检查 etcd 集群中的各个信息。
性能检查 命令语法:
用于检查 etcd 集群的性能信息。
对应的 RPC 方法:CheckPerf
常用选项:
--load
:性能检查的负载模型,支持有:s(small), m(medium)、l(large)、xl(xlarge)
--prefix
:性能测试使用的 key 前缀
--auto-compact
:性能测试后,自动进行 compact
auto-defrag
:性能测试后自动进行 defragment
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ etcdctl check perf --load="s" 60 / 60 Booooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo! 100.00% 1m0s PASS: Throughput is 149 writes/s PASS: Slowest request took 0.261242s PASS: Stddev is 0.013076s PASS $ etcdctl check perf --load="l" FAIL: too many errors FAIL: ERROR(etcdserver: request timed out) -> 287 FAIL: Throughput too low: 297 writes/s Slowest request took too long: 8.325122s Stddev too high: 1.062989s FAIL
数据规模检查 命令语法:
1 CHECK DATASCALE [options]
检查在一个指定的 endpoint server 上,不同负载情况下保存数据所需要使用的内存
对应的 RPC 方法 CheckDatascale
常用选项:
--load
:所使用的负载模型,支持有:s(small), m(medium)、l(large)、xl(xlarge)
--prefix
:所使用的 key 前缀
--auto-compact
:性能测试后,自动进行 compact
auto-defrag
:性能测试后自动进行 defragment
示例:
1 2 3 4 $ etcdctl check datascale --load="s" Start data scale check for work load [10000 key-value pairs, 1024 bytes per key-value, 50 concurrent clients]. 10000 / 10000 Boooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo! 100.00% 14s PASS: Approximate system memory used : 91.16 MB.
Reference