【华为云专家原创】彻底搞懂 etcd 系列文章(五):etcdctl 的使用

举报
aoho 发表于 2020/12/15 09:59:19 2020/12/15
【摘要】 0 专辑概述etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件。《彻底搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周...

0 专辑概述

etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件。

《彻底搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周持续更新,欢迎关注。

1 etcdctl 的实践应用

在前面的文章介绍了 etcd 的相关概念,单机和集群的多种安装方式,以及etcd 安全通信相关的内容。本篇主要基于 etcdctl 介绍 etcd 的常用命令和操作。

etcdctl 是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟etcd服务打交道,而无需基于 HTTP API 方式。可以方便我们在对服务进行测试或者手动修改数据库内容。我们刚开始可以通过 etdctl 来熟悉相关操作。这些操作跟 HTTP API 基本上是对应的。etcdctl 在两个不同的 etcd 版本下的行为方式也完全不同。

export ETCDCTL_API=2
export ETCDCTL_API=3

这里主要以讲解 API 3 为主。

etcd 项目二进制发行包中已经包含了 etcdctl 工具,etcdctl 支持的命令大体上分为数据库操作和非数据库操作两类。

2 常用命令介绍

首先查看一下 etcd 的版本:

$ etcd --version

etcd Version: 3.4.7
Git SHA: e784ba73c
Go Version: go1.12.12
Go OS/Arch: linux/amd64

我们的版本是 etcd 3.4.7 ,下面介绍下 etcdctl 常用的命令。

$ etcdctl -h

NAME:
 etcdctl - A simple command line client for etcd3.

USAGE:
 etcdctl [flags]

VERSION:
 3.4.7

API VERSION:
 3.4


COMMANDS:
 alarm disarm  Disarms all alarms
 alarm list  Lists all alarms
 auth disable  Disables authentication
 auth enable  Enables authentication
 check datascale  Check the memory usage of holding data for different workloads on a given server endpoint.
 check perf  Check the performance of the etcd cluster
 compaction  Compacts the event history in etcd
 defrag   Defragments the storage of the etcd members with given endpoints
 del   Removes the specified key or range of keys [key, range_end)
 elect   Observes and participates in leader election
 endpoint hashkv  Prints the KV history hash for each endpoint in --endpoints
 endpoint health  Checks the healthiness of endpoints specified in `--endpoints` flag
 endpoint status  Prints out the status of endpoints specified in `--endpoints` flag
 get   Gets the key or a range of keys
 help   Help about any command
 lease grant  Creates leases
 lease keep-alive Keeps leases alive (renew)
 lease list  List all active leases
 lease revoke  Revokes leases
 lease timetolive Get lease information
 lock   Acquires a named lock
 make-mirror  Makes a mirror at the destination etcd cluster
 member add  Adds a member into the cluster
 member list  Lists all members in the cluster
 member promote  Promotes a non-voting member in the cluster
 member remove  Removes a member from the cluster
 member update  Updates a member in the cluster
 migrate   Migrates keys in a v2 store to a mvcc store
 move-leader  Transfers leadership to another etcd cluster member.
 put   Puts the given key into the store
 role add  Adds a new role
 role delete  Deletes a role
 role get  Gets detailed information of a role
 role grant-permission Grants a key to a role
 role list  Lists all roles
 role revoke-permission Revokes a key from a role
 snapshot restore Restores an etcd member snapshot to an etcd directory
 snapshot save  Stores an etcd node backend snapshot to a given file
 snapshot status  Gets backend snapshot status of a given file
 txn   Txn processes all the requests in one transaction
 user add  Adds a new user
 user delete  Deletes a user
 user get  Gets detailed information of a user
 user grant-role  Grants a role to a user
 user list  Lists all users
 user passwd  Changes password of user
 user revoke-role Revokes a role from a user
 version   Prints the version of etcdctl
 watch   Watches events stream on keys or prefixes

OPTIONS:
      --cacert=""    verify certificates of TLS-enabled secure servers using this CA bundle
      --cert=""     identify secure client using this TLS certificate file
      --command-timeout=5s   timeout for short running command (excluding dial timeout)
      --debug[=false]    enable client-side debug logging
      --dial-timeout=2s    dial timeout for client connections
  -d, --discovery-srv=""   domain name to query for SRV records describing cluster endpoints
      --discovery-srv-name=""   service name to query when using DNS discovery
      --endpoints=[127.0.0.1:2379]  gRPC endpoints
  -h, --help[=false]    help for etcdctl
      --hex[=false]    print byte strings as hex encoded strings
      --insecure-discovery[=true]  accept insecure SRV records describing cluster endpoints
      --insecure-skip-tls-verify[=false] skip server certificate verification
      --insecure-transport[=true]  disable transport security for client connections
      --keepalive-time=2s   keepalive time for client connections
      --keepalive-timeout=6s   keepalive timeout for client connections
      --key=""     identify secure client using this TLS key file
      --password=""    password for authentication (if this option is used, --user option shouldn't include password)
      --user=""     username[:password] for authentication (prompt if password is not supplied)
  -w, --write-out="simple"   set the output format (fields, json, protobuf, simple, table)

可以看到,etcdctl 支持的命令很多,常用的命令选项:

--debug 输出CURL命令,显示执行命令的时候发起的请求
--no-sync 发出请求之前不同步集群信息
--output, -o 'simple' 输出内容的格式(simple 为原始信息,json 为进行json格式解码,易读性好一些)
--peers, -C 指定集群中的同伴信息,用逗号隔开(默认为: "127.0.0.1:4001")
--cert-file HTTPS下客户端使用的SSL证书文件
--key-file HTTPS下客户端使用的SSL密钥文件
--ca-file 服务端使用HTTPS时,使用CA文件进行验证
--help, -h 显示帮助命令信息
--version, -v 打印版本信息

下面我们将介绍其中常用的数据库命令。

3 数据库操作

数据库操作围绕对键值和目录的 CRUD (即增删改查,符合 REST 风格的一套API操作)完整生命周期的管理。

etcd在键的组织上采用了层次化的空间结构(类似于文件系统中目录的概念),用户指定的键可以为单独的名字,如:testkey,此时实际上放在根目录/下面,也可以为指定目录结构,如/cluster1/node2/testkey,则将创建相应的目录结构。

3.1 键操作

  • set 指定某个键的值。例如:

    $ etcdctl put /testdir/testkey "Hello world"
    $ etcdctl put /testdir/testkey2 "Hello world2"
    $ etcdctl put /testdir/testkey3 "Hello world3"
    

    成功写入三对键值,/testdir/testkey、/testdir/testkey2 和 /testdir/testkey3。

  • get 获取指定键的值。例如:

    $ etcdctl get /testdir/testkey
    Hello world
    
  • get 十六进制读指定的值:

    $ etcdctl get /testdir/testkey --hex
    \x2f\x74\x65\x73\x74\x64\x69\x72\x2f\x74\x65\x73\x74\x6b\x65\x79 #键
    \x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64 #值
    

    加上 --print-value-only 可以读取对应的值。

  • get 范围内的值

     $ etcdctl get /testdir/testkey /testdir/testkey3
    
    /testdir/testkey
    Hello world
    /testdir/testkey2
    Hello world2
    

    可以看到,获取了大于等于 /testdir/testkey,且小于 /testdir/testkey3 的键值对。testkey3 不在范围之内,因为范围是半开区间 [testkey, testkey3), 不包含 testkey3。

  • 获取某个前缀的所有键值对,通过 --prefix 可以指定前缀:

    $ etcdctl get --prefix /testdir/testkey
    /testdir/testkey
    Hello world
    /testdir/testkey2
    Hello world2
    /testdir/testkey3
    Hello world3
    

    这样既可获取所有以 /testdir/testkey 开头的键值对。当前缀获取的结果过多时,还可以通过 --limit=2 限制获取的数量:

    etcdctl get --prefix --limit=2 /testdir/testkey
    
  • 读取键过往版本的值 应用可能想读取键的被替代的值。例如,应用可能想通过访问键的过往版本来回滚到旧的配置。或者,应用可能想通过多个请求来得到一个覆盖多个键的统一视图,而这些请求可以通过访问键历史记录而来。因为 etcd 集群上键值存储的每个修改都会增加 etcd 集群的全局修订版本,应用可以通过提供旧有的 etcd 修改版本来读取被替代的键。现有如下这些键值对:

    foo = bar         # revision = 2
    foo1 = bar2       # revision = 3
    foo = bar_new     # revision = 4
    foo1 = bar1_new   # revision = 5
    

    以下是访问以前版本 key 的示例:

    $ etcdctl get --prefix foo # 访问最新版本的key
    foo
    bar_new
    foo1
    bar1_new
    
    $ etcdctl get --prefix --rev=4 foo # 访问第4个版本的key
    foo
    bar_new
    foo1
    bar1
    
    $ etcdctl get --prefix --rev=3 foo #  访问第3个版本的key
    foo
    bar
    foo1
    bar1
    
    $ etcdctl get --prefix --rev=2 foo #  访问第3个版本的key
    foo
    bar
    
    $ etcdctl get --prefix --rev=1 foo #  访问第1个版本的key
    
  • 读取大于等于指定键的 byte 值的键 应用可能想读取大于等于指定键 的 byte 值的键。假设 etcd 集群已经有下列键:

    a = 123
    b = 456
    z = 789
    

    读取大于等于键 b 的 byte 值的键的命令:

    $ etcdctl get --from-key b
    b
    456
    z
    789
    
  • 删除键。应用可以从 etcd 集群中删除一个键或者特定范围的键。 假设 etcd 集群已经有下列键:

    foo = bar
    foo1 = bar1
    foo3 = bar3
    zoo = val
    zoo1 = val1
    zoo2 = val2
    a = 123
    b = 456
    z = 789
    

    删除键 foo 的命令:

    $ etcdctl del foo
    1 # 删除了一个键
    

    删除从 foo to foo9 范围的键的命令:

    $ etcdctl del foo foo9
    2 # 删除了两个键
    

    删除键 zoo 并返回被删除的键值对的命令:

    $ etcdctl del --prev-kv zoo
    1   # 一个键被删除
    zoo # 被删除的键
    val # 被删除的键的值
    

    删除前缀为 zoo 的键的命令:

    $ etcdctl del --prefix zoo
    2 # 删除了两个键
    

    删除大于等于键 b 的 byte 值的键的命令:

    $ etcdctl del --from-key b
    2 # 删除了两个键
    

3.2 watch 历史改动

  • watch 监测一个键值的变化,一旦键值发生更新,就会输出最新的值并退出。例如:用户更新 testkey 键值为 Hello watch。

    $ etcdctl watch  testkey
    # 在另外一个终端: etcdctl put  testkey Hello watch
    testkey
    Hello watch
    

    从 foo to foo9 范围内键的命令:

    $ etcdctl watch foo foo9
    # 在另外一个终端: etcdctl put foo bar
    PUT
    foo
    bar
    # 在另外一个终端: etcdctl put foo1 bar1
    PUT
    foo1
    bar1
    

    以16进制格式在键 foo 上进行观察的命令:

    $ etcdctl watch foo --hex
    # 在另外一个终端: etcdctl put foo bar
    PUT
    \x66\x6f\x6f          # 键
    \x62\x61\x72          # 值
    

    观察多个键 foo 和 zoo 的命令:

    $ etcdctl watch -i
    $ watch foo
    $ watch zoo
    # 在另外一个终端: etcdctl put foo bar
    PUT
    foo
    bar
    # 在另外一个终端: etcdctl put zoo val
    PUT
    zoo
    val
    
  • 查看 key 的历史改动,应用可能想观察 etcd 中键的历史改动。例如,应用想接收到某个键的所有修改。如果应用一直连接到 etcd,那么 watch 就足够好了。但是,如果应用或者 etcd 出错,改动可能发生在出错期间,这样应用就没能实时接收到这个更新。为了保证更新被交付,应用必须能够观察到键的历史变动。为了做到这点,应用可以在观察时指定一个历史修订版本,就像读取键的过往版本一样。
    假设我们完成了下列操作序列:

    $ etcdctl put foo bar         # revision = 2
    OK
    $ etcdctl put foo1 bar1       # revision = 3
    OK
    $ etcdctl put foo bar_new     # revision = 4
    OK
    $ etcdctl put foo1 bar1_new   # revision = 5
    OK
    

    观察历史改动:

    # 从修订版本 2 开始观察键 `foo` 的改动
    $ etcdctl watch --rev=2 foo
    PUT
    foo
    bar
    PUT
    foo
    bar_new
    

    从上一次历史修改开始观察:

    # 在键 `foo` 上观察变更并返回被修改的值和上个修订版本的值
    $ etcdctl watch --prev-kv foo
    # 在另外一个终端: etcdctl put foo bar_latest
    PUT
    foo         # 键
    bar_new     # 在修改前键foo的上一个值
    foo         # 键
    bar_latest  # 修改后键foo的值
    
  • 压缩修订版本。如我们提到的,etcd 保存修订版本以便应用可以读取键的过往版本。但是,为了避免积累无限数量的历史数据,压缩过往的修订版本就变得很重要。压缩之后,etcd 删除历史修订版本,释放资源来提供未来使用。所有修订版本在压缩修订版本之前的被替代的数据将不可访问。这是压缩修订版本的命令:

    $ etcdctl compact 5
    compacted revision 5 #在压缩修订版本之前的任何修订版本都不可访问
    $ etcdctl get --rev=4 foo
    {"level":"warn","ts":"2020-05-04T16:37:38.020+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-c0d35565-0584-4c07-bfeb-034773278656/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
    

3.3 租约

  • 授予租约 应用可以为 etcd 集群里面的键授予租约。当键被附加到租约时,它的存活时间被绑定到租约的存活时间,而租约的存活时间相应的被 time-to-live (TTL)管理。在租约授予时每个租约的最小TTL值由应用指定。租约的实际 TTL 值是不低于最小 TTL,由 etcd 集群选择。一旦租约的 TTL 到期,租约就过期并且所有附带的键都将被删除。

    # 授予租约,TTL为100秒
    $ etcdctl lease grant 100
    lease 694d71ddacfda227 granted with TTL(10s)
    
    # 附加键 foo 到租约694d71ddacfda227
    $ etcdctl put --lease=694d71ddacfda227 foo10 bar
    OK
    

    建议时间设置久一点,否则来不及操作会出现如下的错误:

  • 撤销租约 应用通过租约 id 可以撤销租约。撤销租约将删除所有它附带的 key。 假设我们完成了下列的操作:

    $ etcdctl lease revoke 694d71ddacfda227
    lease 694d71ddacfda227 revoked
    
    $ etcdctl get foo10
    
  • 刷新租期
    应用程序可以通过刷新其TTL来保持租约活着,因此不会过期。

    $ etcdctl lease keep-alive 694d71ddacfda227
    lease 694d71ddacfda227 keepalived with TTL(100)
    lease 694d71ddacfda227 keepalived with TTL(100)
    ...
    
  • 查询租期 应用程序可能想要了解租赁信息,以便它们可以续订或检查租赁是否仍然存在或已过期。应用程序也可能想知道特定租约所附的 key。

    假设我们完成了以下一系列操作:

    $ etcdctl lease grant 300
    lease 694d71ddacfda22c granted with TTL(300s)
    
    $ etcdctl put --lease=694d71ddacfda22c foo10 bar
    OK
    

    获取有关租赁信息以及哪些 key 使用了租赁信息:

    $ etcdctl lease timetolive 694d71ddacfda22c
    lease 694d71ddacfda22c granted with TTL(300s), remaining(282s)
    
    $ etcdctl lease timetolive --keys 694d71ddacfda22c
    lease 694d71ddacfda22c granted with TTL(300s), remaining(220s), attached keys([foo10])
    

4 小结

本篇主要基于 etcdctl 介绍 etcd 的常用命令和操作,包括键值对的操作、租期、Watch 监测键值等。通过这些命令实现我们在前面文章介绍的 etcd 多种使用场景。下面的文章将开始介绍 etcd v3 的 API 定义和使用,深入了解 etcd 的内幕。


推荐阅读

  1. etcd 与 Zookeeper、Consul 等其它 k-v 组件的对比
  2. 彻底搞懂 etcd 系列文章(一):初识 etcd
  3. 彻底搞懂 etcd 系列文章(二):etcd 的多种安装姿势
  4. 彻底搞懂 etcd 系列文章(三):etcd 集群运维部署
  5. 彻底搞懂 etcd 系列文章(四):etcd 安全

参考

etcd docs

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200