如何使用Etcdctl和ETCD,CoreOS的分布式key-value存储

ETCD是形成集群技术在CoreOS为基础,以全球分布式key-value存储。在本指南中,我们将看看ETCD和etcdctl效用,并讨论如何将它们用于存储和检索应用程序和集群的数据。

介绍

一个使CoreOS可能的技术是etcd ,一个全球分布式key-value存储。 此服务由各个CoreOS机器使用以形成集群和作为存储全局可访问数据的平台。

在本指南中,我们将探讨etcd守护进程以及在etcdctl实用程序和HTTP / JSON API,可以用来控制它。

先决条件

要使用本指南遵循以来,我们假设你有CoreOS机的群集作为我们的指导得到一个CoreOS集群建立在DigitalOcean轮廓。 这将让您在单个集群中拥有三个服务器:

  • coreos-1
  • coreos-2
  • coreos-3

一旦这些机器启动并运行,您可以继续本指南。

集群发现模型

一个最根本的任务etcd负责是单个机器组织成集群。 这是当CoreOS是通过在提供的发现地址检查在引导做cloud-config是在创建传递文件。

通过CoreOS运行发现服务是在访问https://discovery.etcd.io 您可以通过访问获得新令牌/new页面。 在那里,你会得到一个令牌,你的机器可以使用它来发现它们的伴侣节点。 它看起来像这样:

https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c

必须为每一个新的群集提供一个新的令牌。 这包括当您必须使用可能具有相同IP地址的节点重建集群时。 etcd实例将受此困惑,将无法正常工作构建集群,如果你重用发现地址。

在Web浏览器中访问发现地址,您将获得描述已知机器的JSON对象。 首次启动时,不会有任何节点:

{"action":"get","node":{"key":"/_etcd/registry/dcadc5d4d42328488ecdcd7afae5f57c","dir":true,"modifiedIndex":102511104,"createdIndex":102511104}}

启动群集后,您将可以在此处查看更多信息:

{"action":"get","node":{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda","dir":true,"nodes":[{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/2ddbdb7c872b4bc59dd1969ac166501e","value":"http://10.132.252.38:7001","expiration":"2014-09-19T13:41:26.912303668Z","ttl":598881,"modifiedIndex":102453704,"createdIndex":102453704},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/921a7241c31a499a97d43f785108b17c","value":"http://10.132.248.118:7001","expiration":"2014-09-19T13:41:29.602508981Z","ttl":598884,"modifiedIndex":102453736,"createdIndex":102453736},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/27987f5eaac243f88ca6823b47012c5b","value":"http://10.132.248.121:7001","expiration":"2014-09-19T13:41:41.817958205Z","ttl":598896,"modifiedIndex":102453860,"createdIndex":102453860}],"modifiedIndex":101632353,"createdIndex":101632353}}

如果需要查找群集的发现URL,可以从作为成员的任何一台计算机执行此操作。 这个信息可以从内检索/run层次结构:

cat /run/systemd/system/etcd.service.d/20-cloudinit.conf
[Service]
Environment="ETCD_ADDR=10.132.248.118:4001"
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c"
Environment="ETCD_NAME=921a7241c31a499a97d43f785108b17c"
Environment="ETCD_PEER_ADDR=10.132.248.118:7001"

该URL存储在内部ETCD_DISCOVERY条目。

当运行的机器etcd启动时,它们会检查这个网址的信息。 它将提交自己的信息和查询其他成员。 集群中的第一个节点显然不会找到有关其他节点的信息,因此它将自己指定为集群领导者。

后续计算机还将使用其信息与发现URL联系。 他们将收到有关已签入的机器的信息。然后他们将选择其中一台机器并直接连接,在那里他们将获得健康集群成员的完整列表。 复制和数据分布是通过完成筏共识算法

关于各机器的数据被存储于一个隐藏的目录结构中etcd 你可以看到,机器的信息etcd知道通过键入:

etcdctl ls /_etcd/machines --recursive
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
/_etcd/machines/921a7241c31a499a97d43f785108b17c
/_etcd/machines/27987f5eaac243f88ca6823b47012c5b

该细节etcd传递到新的集群成员都包含这些键中。 您可以通过请求那些看个人的价值观etcdctl

etcdctl get /_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
etcd=http%3A%2F%2F10.132.252.38%3A4001&raft=http%3A%2F%2F10.132.252.38%3A7001

我们会在etcdctl命令更深入以后。

Etcdctl用法

有与相互作用的两种基本方式etcd 通过HTTP / JSON API和通过客户端,如包括etcdctl效用。 我们去了etcdctl第一。

查看键和目录

在开始之前,让我们来看看一个什么etcdctl目前正在存储。 我们可以通过键入以下内容查看顶级键:

etcdctl ls /
/coreos.com

正如你所看到的,我们有一个结果。 在这一点上,不清楚这是目录还是键。 我们可以尝试get节点以查看任一键的值或者一看就知道它是一个目录:

etcdctl get /coreos.com
/coreos.com: is a directory

为了避免本手册递归过程中,我们可以告诉etcdctl通过键入列出的可视信息的整个层次:

etcdctl ls / --recursive
/coreos.com
/coreos.com/updateengine
/coreos.com/updateengine/rebootlock
/coreos.com/updateengine/rebootlock/semaphore

正如你所看到的,有初始颇下了几个目录/coreos.com节点。 我们可以通过在最终端点请求信息来查看从节点中获取实际数据的样子:

etcdctl get /coreos.com/updateengine/rebootlock/semaphore
{"semaphore":1,"max":1,"holders":null}

这不包含对我们非常有用的信息。 我们可以通过传递在获得有关此项目的一些额外的元数据-o extended选项。 这是一个全球性的选择,所以它一定要来的前get命令:

etcdctl -o extended get /coreos.com/updateengine/rebootlock/semaphore
Key: /coreos.com/updateengine/rebootlock/semaphore
Created-Index: 6
Modified-Index: 6
TTL: 0
Etcd-Index: 170387
Raft-Index: 444099
Raft-Term: 8

{"semaphore":1,"max":1,"holders":null}

设置键和创建节点

要创建新的目录,你可以使用mkdir命令,如下所示:

etcdctl mkdir /example

为了使键,就可以使用mk命令:

etcdctl mk /example/key data
data

这只有当键不存在时才有效。 如果我们要求我们创建的键的值,我们可以检索我们设置的数据:

etcdctl get /example/key
data

要更新现有键,使用update的命令:

etcdctl update /example/key turtles
turtles

同伴updatedir如果您设置了TTL,或目录的时间到现场进行指挥的目录可能是唯一有用的。 这将用通过的时间更新TTL时间。 您可以通过将设置目录或按键的TTL --ttl #说法,其中“#”是秒保持数:

etcdctl mkdir /here/you/go --ttl 120

然后,您可以更新与TTL updatedir

etcdctl updatedir /here/you/go --ttl 500

要更改现有键的值,或创建如果它不存在一个键,使用set命令。 这个想象成组合mkupdate的命令:

etcdctl set /example/key new
new

这可以包括不存在的路径。 将动态创建路径组件:

etcdctl set /a/b/c here
here

要获取目录同样创造-IF-不-不存在的功能,您可以使用setdir命令:

etcdctl setdir /x/y/z

注意setdir命令目前不作为说明。 在目前的版本,它的使用反映了updatedir命令,如果该目录已经存在,就会失败。 GitHub存储库有一个开放的问题来解决这个问题。

删除条目

要删除现有的密钥,您可以使用rmrmdir命令。

rm命令可用于删除键:

etcdctl rm /a/b/c

它也可以递归地删除目录和每个子目录:

etcdctl rm /a --recursive

只删除空目录键,使用rmdir命令:

etcdctl rmdir /x/y/z

这可用于确保您只删除层次结构的端点。

观看更改

您可以观看特定键或整个目录以进行更改。 与看着这些etcdctl会导致操作挂起,直到一些事件发生到任何被监视。

要观看密钥,请使用它没有任何标志:

etcdctl watch /example/hello

驻足观望,你可以按CTRL-C 如果在观察期间检测到更改,则将返回新值。

要观看整个目录结构,使用--recursive标志:

etcdctl watch --recursive /example

你可以通过将它放在一个简单的循环结构中来不断地监视值的状态来看看这是如何有用的:

while true; do etcdctl watch --recursive /example; done

如果你想执行每当检测到变化的命令,使用exec-watch命令:

etcdctl exec-watch --recursive  /example -- echo "hello"

当目录中的值改变时,这将回显“hello”到屏幕。

隐藏值

有一件事情是不会立即显现的是,有中隐藏的目录结构etcd 这些是以下划线开头的目录或键。

这些都不是通过传统的上市etcdctl工具,你必须知道你是为了找到他们要找的内容。

例如,有一个名为一个隐藏目录/_coreos.com持有一些内部信息fleet 您可以通过显式请求查看层次结构:

etcdctl ls --recursive /_coreos.com 
/_coreos.com/fleet
/_coreos.com/fleet/states
/_coreos.com/fleet/states/apache@6666.service
/_coreos.com/fleet/states/apache@6666.service/2ddbdb7c872b4bc59dd1969ac166501e
/_coreos.com/fleet/states/apache@7777.service
/_coreos.com/fleet/states/apache@7777.service/921a7241c31a499a97d43f785108b17c
. . .

另一个这样的目录结构位于内/_etcd

etcdctl ls --recursive /_etcd
/_etcd/machines
/_etcd/machines/27987f5eaac243f88ca6823b47012c5b
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
/_etcd/machines/921a7241c31a499a97d43f785108b17c
/_etcd/config

这些功能与任何其他条目完全相同,唯一的区别是它们不会显示在一般列表中。 您可以通过简单地使用下划线开始键或目录名称来创建它们。

Etcd HTTP / JSON API用法

另一种方法与互动etcd与简单的HTTP / JSON API。

要访问API,你可以像使用一个简单的HTTP程序curl 必须提供-L标志来遵循传回任何重定向。 从你的集群中,你可以使用本地127.0.0.1接口和端口4001的大多数查询。

注意 :要连接到etcd从Docker容器内,该地址http://172.17.42.1:4001可以使用。 这对于应用程序根据注册信息更新其配置可能很有用。

正常的密钥空间可以通过将要达到http://127.0.0.1:4001/v2/keys/在任何主机上的。 例如,要获取顶级密钥/目录的列表,请键入:

curl -L http://127.0.0.1:4001/v2/keys/
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"modifiedIndex":6,"createdIndex":6},{"key":"/services","dir":true,"modifiedIndex":333,"createdIndex":333}]}}

请求中的尾部斜杠是必需的。 如果没有它,它将无法正确解决。

您可以使用普通HTTP动词设置或检索值。

要修改这些操作的行为,您可以使用您的请求的结束标志传递?flag=value语法。 多个标志被分隔&字符。

例如,要递归地列出所有的键,我们可以键入:

curl -L http://127.0.0.1:4001/v2/keys/?recursive=true
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"nodes":[{"key":"/coreos.com/updateengine","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock/semaphore","value":"{\"semaphore\":1,\"max\":1,\"holders\":null}","modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}. . .

在正常键空间之外访问的另一个有用的信息是版本信息,可在这里访问:

curl -L http://127.0.0.1:4001/version
etcd 0.4.6

您可以通过访问此端点查看有关每个集群领导与每个关注者的关系的统计信息:

curl -L http://127.0.0.1:4001/v2/stats/leader
{"leader":"921a7241c31a499a97d43f785108b17c","followers":{"27987f5eaac243f88ca6823b47012c5b":{"latency":{"current":1.607038,"average":1.3762888642395448,"standardDeviation":1.4404313533578545,"minimum":0.471432,"maximum":322.728852},"counts":{"fail":0,"success":98718}},"2ddbdb7c872b4bc59dd1969ac166501e":{"latency":{"current":1.584985,"average":1.1554367141497013,"standardDeviation":0.6872303198242179,"minimum":0.427485,"maximum":31.959235},"counts":{"fail":0,"success":98723}}}}

类似的操作可用于检测关于您当前使用的机器的统计数据:

curl -L http://127.0.0.1:4001/v2/stats/self
{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","startTime":"2014-09-11T16:42:03.035382298Z","leaderInfo":{"leader":"921a7241c31a499a97d43f785108b17c","uptime":"1h19m11.469872568s","startTime":"2014-09-12T19:47:25.242151859Z"},"recvAppendRequestCnt":1944480,"sendAppendRequestCnt":201817,"sendPkgRate":40.403374523779064,"sendBandwidthRate":3315.096879676072}

要查看有关已执行的操作的统计信息,请键入:

curl -L http://127.0.0.1:4001/v2/stats/store
{"getsSuccess":78823,"getsFail":14,"setsSuccess":121370,"setsFail":4,"deleteSuccess":28,"deleteFail":32,"updateSuccess":20468,"updateFail":4,"createSuccess":39,"createFail":102340,"compareAndSwapSuccess":51169,"compareAndSwapFail":0,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":3,"watchers":6}

这些仅仅是一些可用于控制操作的etcd通过API。

Etcd配置

etcd服务可以在几个不同的方式来配置。

第一种方式是与你的参数传递cloud-config文件,您使用来引导你的节点。 在引导指南中,你看到了一些关于如何做到这一点:

#cloud-config

coreos:
  etcd:
    discovery: https://discovery.etcd.io/<token>
    addr: $private_ipv4:4001
    peer-addr: $private_ipv4:7001
. . .

要看到你有可用的选项,使用-h与标志etcd

etcd -h

要在你的这些选项的cloud-config ,只需脱掉从值主导破折号和独立的按键加上冒号,而不是等号。 所以-peer-addr=<host:port>成为peer-addr: <host:port>

在阅读了cloud-config文件,CoreOS将这些目标变为一个存根单元文件,它是用来启动服务的环境变量。

调整设置的另一种方法etcd是通过API。 这是使用通常进行7001端口,而不是标准的4001是用于关键查询。

例如,您可以通过键入以下内容获取某些当前配置值:

curl -L http://127.0.0.1:7001/v2/admin/config
{"activeSize":9,"removeDelay":1800,"syncInterval":5}

您可以通过使用PUT操作传递新的JSON作为数据有效内容来更改这些值:

curl -L http://127.0.0.1:7001/v2/admin/config -XPUT -d '{"activeSize":9,"removeDelay":1800,"syncInterval":5}'
{"activeSize":9,"removeDelay":1800,"syncInterval":5}

要获得机器的列表,你可以去/v2/admin/machines端点:

curl -L http://127.0.0.1:7001/v2/admin/machines
[{"name":"27987f5eaac243f88ca6823b47012c5b","state":"follower","clientURL":"http://10.132.248.121:4001","peerURL":"http://10.132.248.121:7001"},{"name":"2ddbdb7c872b4bc59dd1969ac166501e","state":"follower","clientURL":"http://10.132.252.38:4001","peerURL":"http://10.132.252.38:7001"},{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","clientURL":"http://10.132.248.118:4001","peerURL":"http://10.132.248.118:7001"}]

这可以用于使用DELETE方法强制从集群中删除计算机。

结论

正如你所看到的, etcd可以用来存储或集群可以从任何计算机的信息。 这允许您同步数据,并为服务提供位置,以查找配置数据和连接详细信息。

这在构建分布式系统时特别有用,因为您可以提供一个简单的端点,该端点将在集群内的任何位置有效。 通过利用此资源,您的服务可以动态配置自己。