Etcd 简介
Etcd CoreOS 团队于 2013 年6月发起的开源项目,它的目标是构建一个高可用的分布式键值( key-value )仓库,遵循 Apache v2许可,基于 Go 语言实现,接触过分布式系统的读者应该知道,分布式系统中最基本的问题之一就是实现信息的共识,在此基础上才能实现对服务配置信息的管理、服务的发现、更新、同步,等等 而要解决这些问题,往往需要利用一套能保证一致性的分布式数据库系统,比如经典的 Apache ZooKeeper 项目 ,采用了 Paxos 算法来实现数据的强一致性。
Etcd 专门为集群环境设计,采用了更为简洁的 Raft 共识算法,Raft 是一套通过选举主节点来实现分布式系统一致性的算法,同样可以实现数据强一致性,并支持集群节点状态管理和服务自动发现等
Etcd 在进行设计的时候重点考虑了下面四个要素:
口简单:支持 RESTfulAPI和gRPCAPI;
口安全: 基于 TLS 式实 安全连接访
口快速: 支持每 一万次 并发写操作,超时控制在毫秒量级
口可靠: 支持分布式结构 基于 Raft 算法实现一致性
通常情况下,用户使用 Etcd 可以在多个节点上启动多个实例,并将它们添加为 个集群。同一个集群中的 Etcd 实例将会自动保持彼此信息的一致性,这意味着分布在各个节点上的应用也将获取到一致的信息。
安装和使用 Etcd
第一步:下载
https://github.com/etcd-io/etcd/releases
第二步:解压
[root@ken2 ~]# tar xf etcd-v3.3.1-linux-amd64.tar.gz [root@ken2 ~]# cp etcd-v3.3.1-linux-amd64/etcd* /usr/local/bin
其中 etcd 是服务主文件, etcdctl 是提供给用户的命令客户端,其他都是文档文件
使用etcd
下面将先以单节点 式为例讲解 Etcd 支持的功能和操作
1.可通过如下命令查看 etcd 的版本信息:
[root@ken2 ~]# etcdctl --version etcdctl version: 3.3.1 API version: 2
2.接下来,直接执行 Etcd 命令,将启动 个服务节点,监昕在本地的 2379 (客户端端口)和 2380 (其他节点连 端口
显示类似如下的信息:
[root@ken2 ~]# etcd [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead 2019-09-10 14:24:00.393171 I | etcdmain: etcd Version: 3.4.0 2019-09-10 14:24:00.393235 I | etcdmain: Git SHA: 898bd1351 2019-09-10 14:24:00.393242 I | etcdmain: Go Version: go1.12.9 2019-09-10 14:24:00.393253 I | etcdmain: Go OS/Arch: linux/amd64 2019-09-10 14:24:00.393262 I | etcdmain: setting maximum number of CPUs to 4, total number of available CPUs is 4 2019-09-10 14:24:00.393273 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead 2019-09-10 14:24:00.492487 I | embed: name = default 2019-09-10 14:24:00.492507 I | embed: data dir = default.etcd 2019-09-10 14:24:00.492513 I | embed: member dir = default.etcd/member 2019-09-10 14:24:00.492518 I | embed: heartbeat = 100ms 2019-09-10 14:24:00.492522 I | embed: election = 1000ms 2019-09-10 14:24:00.492526 I | embed: snapshot count = 100000 2019-09-10 14:24:00.492540 I | embed: advertise client URLs = http://localhost:2379 2019-09-10 14:24:00.500959 I | etcdserver: starting member 8e9e05c52164694d in cluster cdf818194e3a8c32 raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d switched to configuration voters=() raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d became follower at term 0 raft2019/09/10 14:24:00 INFO: newRaft 8e9e05c52164694d [peers: [], term: 0, commit: 0, applied: 0, lastindex: 0, lastterm: 0] raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d became follower at term 1 raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d switched to configuration voters=(10276657743932975437) 2019-09-10 14:24:00.512116 W | auth: simple token is not cryptographically signed 2019-09-10 14:24:00.514290 I | etcdserver: starting server... [version: 3.4.0, cluster version: to_be_decided] 2019-09-10 14:24:00.516603 I | etcdserver: 8e9e05c52164694d as single-node; fast-forwarding 9 ticks (election ticks 10) raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d switched to configuration voters=(10276657743932975437) 2019-09-10 14:24:00.524693 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32 2019-09-10 14:24:00.529322 I | embed: listening for peers on 127.0.0.1:2380 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d is starting a new election at term 1 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d became candidate at term 2 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 2 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d became leader at term 2 raft2019/09/10 14:24:01 INFO: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2 2019-09-10 14:24:01.307817 I | etcdserver: setting up the initial cluster version to 3.4 2019-09-10 14:24:01.310805 I | etcdserver: published {Name:default ClientURLs:[http://localhost:2379]} to cluster cdf818194e3a8c32 2019-09-10 14:24:01.333900 I | embed: ready to serve client requests 2019-09-10 14:24:01.334870 N | etcdserver/membership: set the initial cluster version to 3.4 2019-09-10 14:24:01.335022 I | etcdserver/api: enabled capabilities for version 3.4 2019-09-10 14:24:01.353146 N | embed: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
此时,可以通过 REST API 直接查看集群健康状态:
[root@ken2 ~]# curl -L 127.0.0.1:2379/health {"health":"true"}
当然,也可以使用自带的 etcdctl 命令进行查看(实际上是封装了REST API 调用):
[root@ken1 ~]# etcdctl cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379 cluster is healthy
3.通过 etcdctl 设置和获取值也十分方便,例如设置键值对name : ken
[root@ken1 ~]# etcdctl set name ken ken [root@ken1 ~]# etcdctl get name ken
说明键值对已经设 成功了
数据目录
作为数据库,最重要的自 然是数据存放位置 Etcd 认创建的本地数据目录为 ${name}.etcd ,其中${ name }为节点别名 默认情况下本地数据路径为 default.etcd,
[root@ken1 ~]# ls 192.168.64.6 anaconda-ks.cfg default.etcd etcd-v3.3.1-linux-amd64 etcd-v3.3.1-linux-amd64.tar.gz n1.etcd
[root@ken1 ~]# tree default.etcd/ default.etcd/ └── member ├── snap │ └── db └── wal ├── 0000000000000000-0000000000000000.wal └── 0.tmp 3 directories, 3 files
其中, snap 目录下将定期记录节点的状态快照信息, wal 目录下则记录数据库的操作日志信息、(可以通过 wal-dir 参数来指定存放到特定目录)
用户也可以通过一data-dir 选项来指定本地数据存放的位置
使用客户端命令
etcdctl是Etcd官方提供的命令行客户端, 它支持一些基于 HTTP API 封装好的命令,供用户直接跟Etcd服务打交道, 而无须基千 API 的方式。 当然, 这些命令跟API 实际上是对应的, 最终效果上并无不同之处。某些情况下使用etcdctl十分方便。 例如用户需要对Etcd服务进行简单测试或者手动来修改数据库少量内容;也推荐在刚接触Etcd时通过etcdctl命令来熟悉服务相关功能。Etcd项目二进制发行包中已经包含了etcdctl.
etcdctl的命令格式为:
etcdctl [全局选项]命令[命令选项] [命令参数]
全局选项参数如下:
支持的命令大体上分为:数据类操作和非数据类操作
非数据类操作命令见下, 主要是 Etcd 提供的系统配置、 权限管理等
下面分别来看各个操作的主要用法和功能
数据类操作
数据类操作围绕对键值和目录的CRUD (符合REST风格的一套操作:Create)完整生命周期的管理。Etcd在键的组织上十分灵活。用户指定的键可以为只有一级的名字,如name, 此时实际上都直接放在根目录/下面,也可以为指定层次化目录结构(类似于ZooKeeper), 如:clusster1/node2/ name, 则将创建相应的目录结构。
CRUD即Create, Read, Update, Delete , 是符合REST风格的一套API操作规范。
1.设置某个键的值为给定值
[root@ken1 ~]# etcdctl set age 18 18
2.获取指定键的值
[root@ken1 ~]# etcdctl get age 18
3.更新键值
[root@ken1 ~]# etcdctl update age 20 20 [root@ken1 ~]# etcdctl get age 20
4.mk 如果给定的键不存在, 则创建一个新的键值。
[root@ken1 ~]# etcdctl mk address jiangsu jiangsu [root@ken1 ~]# etcdctl get address jiangsu
5.rm删除某个键值
[root@ken1 ~]# etcdctl rm address PrevNode.Value: jiangsu [root@ken1 ~]# etcdctl get address Error: 100: Key not found (/address) [8]
6.watch监测一个键值的变化, 一旦键值发生更新, 就会输出最新的值并退出。
[root@ken1 ~]# etcdctl watch name ken1
7.exec-watch
监测一个键值的变化, 一旦键值发生更新, 就执行给定命令。 这个功能十分强大, 很多时候可以用于实时根据键值更新本地服务的配置信息, 并重新加载服务。 可以实现分布式应用配置的自动分发。
例如, 一旦检测到键值被更新, 则执行ls命令:
[root@ken1 ~]# etcdctl exec-watch name -- sh -c "ls" anaconda-ks.cfg default.etcd etcd-v3.3.1-linux-amd64 etcd-v3.3.1-linux-amd64.tar.gz
8.1s
列出目录(默认为根目录)下的键或者子目录, 默认不显示子目录中内容。 例如:
[root@ken1 ~]# etcdctl set key hi hi [root@ken1 ~]# etcdctl set ken/key hi1 hi1 [root@ken1 ~]# etcdctl ls /name /age /key /ken [root@ken1 ~]# etcdctl ls ken /ken/key
9.mkdir
如果给定的键目录不存在, 则创建一个新的键目录。 例如:
[root@ken1 ~]# etcdctl mkdir test [root@ken1 ~]# etcdctl ls /name /age /key /ken /test
10.rmdir
删除一个空目录, 或者键值对。若目录不空, 会报错, 例如:
[root@ken1 ~]# etcdctl rmdir test [root@ken1 ~]# etcdctl rmdir ken Error: 108: Directory not empty (/ken) [14]
11.setdir
创建一个键目录, 无论存在与否。 实际上, 目前版本当目录已经存在的时候会报错,
例如:
[root@ken1 ~]# etcdctl setdir test [root@ken1 ~]# etcdctl ls /name /age /key /ken /test
12.updatedir
更新一个已经存在的目录的属性(目前只有存活时间), 例如:
[root@ken1 ~]# etcdctl mkdir test1 --ttl 100 [root@ken1 ~]# etcdctl updatedir test1 --ttl 200
支待的选项为—ttlvalue: 超时时间(单位为秒),默认值为0, 意味着永不超时。
非数据类操作
非数据类操作不直接对数据本身进行管理, 而是负责围绕集群自身的一些配置。
1.cluster-health
查看Etcd集群的健康状态。 例如:
[root@ken1 ~]# etcdctl cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379 cluster is healthy
2.member
通过list、add、remove等子命令列出、 添加、 删除Etcd实例到Etcd集群中。 例如, 本
地启动一个Etcd服务实例后, 可以用如下命令进行查看 默认的实例成员:
[root@ken1 ~]# etcdctl member list 8e9e05c52164694d: name=default peerURLs=http://localhost:2380 clientURLs=http://localhost:2379 isLeader=true
3.user
对用户进行管理, 包括一系列子命令:
add: 添加一个用户;
get:查询用户细节;
list: 列出所有用户;
remove: 删除用户;
grant:添加用户到角色;
revoke: 删除用户的角色;
passwd: 修改用户的密码。
默认情况下, 需要先创建(启用) root用户作为etcd集群的最高权限管理员:
会要求输入密码
[root@ken1 ~]# etcdctl user add root New password: User root created
分配某些已有角色给用户
[root@ken1 ~]# etcdctl user grant root --roles root auth: Granting duplicate role root for user root
4.role
对用户角色进行管理,包括一系列子命令:
add :添加一个角色;
get :查询角色细节;
list 列出所有用户角色;
remove :删除用户角色;
grant 添加路径到角色控制,可以为 read write 或者 readwrite;
revoke 删除某路径的用户角色信息
默认带有 root,guest 两种角色,前者为全局最高权限,后者为不带验证情况下的用户
例如
[root@ken1 ~]# etcdctl role add testrole Role testrole created [root@ken1 ~]# etcdctl role list root testrole
[root@ken1 ~]# etcdctl role grant testrole --path='/ken/*' --rw Role testrole updated
5.auth
是否启用访问验证 enable 为启用, disable 禁用。例如,在 root 用户创建后,启用
认证:
[root@ken1 ~]# etcdctl auth enable Authentication Enabled
Etcd 集群管理
tcd 集群也采用了典型的“主一从”模型,通过 Raft 协议来保证在 段时间内有一个节点为主节点 ,其 节点为从节点 一旦主节点发生故障其他节点可以自动再重新选举出新的主节点。与其他分布式系统类似,集群中节点个数推荐为奇数个,最少为3个,此时 quorum为2,越多节点个数自然能提供更多的冗余’性 ,但同时会带来写数据性能的下降
在分布式系统中有一个很重要的概念 quorum ,意味着一个集群正常工作需要能参加投票的节点个数的最小值
构建集群
构建集群无非是让节点们知道自己加入了哪个集群,其他对等节点的访问信息是啥。
Etcd 支持两种模式来构建集群:静态配 和动态发现
.静态配置集群信息
顾名思义, 静态配置就是提取写好集群中的有关信息。接下来演示使用三个节点创建集群
第一步:首先在各个 点上将地址和别名信息添加到 etc/hosts
[root@ken1 ~]# cat /etc/hosts localhost 127.0.0.1 ken1 192.168.64.5 ken2 192.168.64.6 ken3 192.168.64.7
第二步:需要在每个节点安装etcd
略
第三步:可以通过如下命令来启动各个节点上 etcd 服务 ,分别命名为 nl n2 n3
在节点1上,执行如下命令:
[root@ken1 ~]# etcd --name n1 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.64.5:2379,http://127.0.0.1:2379 --listen-peer-urls http://192.168.64.5:2380 --advertise-client-urls http://192.168.64.5:2379 --initial-advertise-peer-urls http://ken1:2380 --initial-cluster n1=http://ken1:2380,n2=http://ken2:2380,n3=http://ken3:2380
参数分析
-name 节点名称
-initial-advertise-peer-urls 通知其他 Etcd 实例地址
-listen-peer-urls 监听其他 Etcd 实例的地址
-initial-cluster-token 初始化集群 token
-initial-cluster 初始化集群内节点地址
-initial-cluster-state 初始化集群状态,new 表示新建
在节点2上执行如下的命令:
[root@ken2 ~]# etcd --name n2 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.64.6:2379,http://127.0.0.1:2379 --listen-peer-urls http://192.168.64.6:2380 --advertise-client-urls http://192.168.64.6:2379 --initial-advertise-peer-urls http://ken2:2380 --initial-cluster n1=http://ken1:2380,n2=http://ken2:2380,n3=http://ken3:2380
在节点3上执行如下的命令:
[root@ken3 ~]# etcd --name n3 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.64.7:2379,http://127.0.0.1:2379 --listen-peer-urls http://192.168.64.7:2380 --advertise-client-urls http://192.168.64.7:2379 --initial-advertise-peer-urls http://ken3:2380 --initial-cluster n1=http://ken1:2380,n2=http://ken2:2380,n3=http://ken3:2380
成功后,可以在任一节点上通过 et cdctl 来查看当前集群中的成员信息:
[root@ken1 ~]# etcdctl member list 906a78458065a88a: name=n2 peerURLs=http://ken2:2380 clientURLs=http://192.168.64.6:2379 isLeader=false c41dc5eb2046fd27: name=n3 peerURLs=http://ken3:2380 clientURLs=http://192.168.64.7:2379 isLeader=true c7ce0761a258afbd: name=n1 peerURLs=http://ken1:2380 clientURLs=http://192.168.64.5:2379 isLeader=false
测试:在任意一台主机创建键值
[root@ken1 ~]# etcdctl set name1 ken1 ken1
可以在另外节点查看该键值
[root@ken2 ~]# etcdctl get name1
Etcd 简介
Etcd CoreOS 团队于 2013 年6月发起的开源项目,它的目标是构建一个高可用的分布式键值( key-value )仓库,遵循 Apache v2许可,基于 Go 语言实现,接触过分布式系统的读者应该知道,分布式系统中最基本的问题之一就是实现信息的共识,在此基础上才能实现对服务配置信息的管理、服务的发现、更新、同步,等等 而要解决这些问题,往往需要利用一套能保证一致性的分布式数据库系统,比如经典的 Apache ZooKeeper 项目 ,采用了 Paxos 算法来实现数据的强一致性。
Etcd 专门为集群环境设计,采用了更为简洁的 Raft 共识算法,Raft 是一套通过选举主节点来实现分布式系统一致性的算法,同样可以实现数据强一致性,并支持集群节点状态管理和服务自动发现等
Etcd 在进行设计的时候重点考虑了下面四个要素:
口简单:支持 RESTfulAPI和gRPCAPI;
口安全: 基于 TLS 式实 安全连接访
口快速: 支持每 一万次 并发写操作,超时控制在毫秒量级
口可靠: 支持分布式结构 基于 Raft 算法实现一致性
通常情况下,用户使用 Etcd 可以在多个节点上启动多个实例,并将它们添加为 个集群。同一个集群中的 Etcd 实例将会自动保持彼此信息的一致性,这意味着分布在各个节点上的应用也将获取到一致的信息。
安装和使用 Etcd
第一步:下载
https://github.com/etcd-io/etcd/releases
第二步:解压
[root@ken2 ~]# tar xf etcd-v3.3.1-linux-amd64.tar.gz [root@ken2 ~]# cp etcd-v3.3.1-linux-amd64/etcd* /usr/local/bin
其中 etcd 是服务主文件, etcdctl 是提供给用户的命令客户端,其他都是文档文件
使用etcd
下面将先以单节点 式为例讲解 Etcd 支持的功能和操作
1.可通过如下命令查看 etcd 的版本信息:
[root@ken2 ~]# etcdctl --version etcdctl version: 3.3.1 API version: 2
2.接下来,直接执行 Etcd 命令,将启动 个服务节点,监昕在本地的 2379 (客户端端口)和 2380 (其他节点连 端口
显示类似如下的信息:
[root@ken2 ~]# etcd [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead 2019-09-10 14:24:00.393171 I | etcdmain: etcd Version: 3.4.0 2019-09-10 14:24:00.393235 I | etcdmain: Git SHA: 898bd1351 2019-09-10 14:24:00.393242 I | etcdmain: Go Version: go1.12.9 2019-09-10 14:24:00.393253 I | etcdmain: Go OS/Arch: linux/amd64 2019-09-10 14:24:00.393262 I | etcdmain: setting maximum number of CPUs to 4, total number of available CPUs is 4 2019-09-10 14:24:00.393273 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead 2019-09-10 14:24:00.492487 I | embed: name = default 2019-09-10 14:24:00.492507 I | embed: data dir = default.etcd 2019-09-10 14:24:00.492513 I | embed: member dir = default.etcd/member 2019-09-10 14:24:00.492518 I | embed: heartbeat = 100ms 2019-09-10 14:24:00.492522 I | embed: election = 1000ms 2019-09-10 14:24:00.492526 I | embed: snapshot count = 100000 2019-09-10 14:24:00.492540 I | embed: advertise client URLs = http://localhost:2379 2019-09-10 14:24:00.500959 I | etcdserver: starting member 8e9e05c52164694d in cluster cdf818194e3a8c32 raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d switched to configuration voters=() raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d became follower at term 0 raft2019/09/10 14:24:00 INFO: newRaft 8e9e05c52164694d [peers: [], term: 0, commit: 0, applied: 0, lastindex: 0, lastterm: 0] raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d became follower at term 1 raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d switched to configuration voters=(10276657743932975437) 2019-09-10 14:24:00.512116 W | auth: simple token is not cryptographically signed 2019-09-10 14:24:00.514290 I | etcdserver: starting server... [version: 3.4.0, cluster version: to_be_decided] 2019-09-10 14:24:00.516603 I | etcdserver: 8e9e05c52164694d as single-node; fast-forwarding 9 ticks (election ticks 10) raft2019/09/10 14:24:00 INFO: 8e9e05c52164694d switched to configuration voters=(10276657743932975437) 2019-09-10 14:24:00.524693 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32 2019-09-10 14:24:00.529322 I | embed: listening for peers on 127.0.0.1:2380 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d is starting a new election at term 1 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d became candidate at term 2 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 2 raft2019/09/10 14:24:01 INFO: 8e9e05c52164694d became leader at term 2 raft2019/09/10 14:24:01 INFO: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2 2019-09-10 14:24:01.307817 I | etcdserver: setting up the initial cluster version to 3.4 2019-09-10 14:24:01.310805 I | etcdserver: published {Name:default ClientURLs:[http://localhost:2379]} to cluster cdf818194e3a8c32 2019-09-10 14:24:01.333900 I | embed: ready to serve client requests 2019-09-10 14:24:01.334870 N | etcdserver/membership: set the initial cluster version to 3.4 2019-09-10 14:24:01.335022 I | etcdserver/api: enabled capabilities for version 3.4 2019-09-10 14:24:01.353146 N | embed: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
此时,可以通过 REST API 直接查看集群健康状态:
[root@ken2 ~]# curl -L 127.0.0.1:2379/health {"health":"true"}
当然,也可以使用自带的 etcdctl 命令进行查看(实际上是封装了REST API 调用):
[root@ken1 ~]# etcdctl cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379 cluster is healthy
3.通过 etcdctl 设置和获取值也十分方便,例如设置键值对name : ken
[root@ken1 ~]# etcdctl set name ken ken [root@ken1 ~]# etcdctl get name ken
说明键值对已经设 成功了
数据目录
作为数据库,最重要的自 然是数据存放位置 Etcd 认创建的本地数据目录为 ${name}.etcd ,其中${ name }为节点别名 默认情况下本地数据路径为 default.etcd,
[root@ken1 ~]# ls 192.168.64.6 anaconda-ks.cfg default.etcd etcd-v3.3.1-linux-amd64 etcd-v3.3.1-linux-amd64.tar.gz n1.etcd
[root@ken1 ~]# tree default.etcd/ default.etcd/ └── member ├── snap │ └── db └── wal ├── 0000000000000000-0000000000000000.wal └── 0.tmp 3 directories, 3 files
其中, snap 目录下将定期记录节点的状态快照信息, wal 目录下则记录数据库的操作日志信息、(可以通过 wal-dir 参数来指定存放到特定目录)
用户也可以通过一data-dir 选项来指定本地数据存放的位置
使用客户端命令
etcdctl是Etcd官方提供的命令行客户端, 它支持一些基于 HTTP API 封装好的命令,供用户直接跟Etcd服务打交道, 而无须基千 API 的方式。 当然, 这些命令跟API 实际上是对应的, 最终效果上并无不同之处。某些情况下使用etcdctl十分方便。 例如用户需要对Etcd服务进行简单测试或者手动来修改数据库少量内容;也推荐在刚接触Etcd时通过etcdctl命令来熟悉服务相关功能。Etcd项目二进制发行包中已经包含了etcdctl.
etcdctl的命令格式为:
etcdctl [全局选项]命令[命令选项] [命令参数]
全局选项参数如下:
支持的命令大体上分为:数据类操作和非数据类操作
非数据类操作命令见下, 主要是 Etcd 提供的系统配置、 权限管理等
下面分别来看各个操作的主要用法和功能
数据类操作
数据类操作围绕对键值和目录的CRUD (符合REST风格的一套操作:Create)完整生命周期的管理。Etcd在键的组织上十分灵活。用户指定的键可以为只有一级的名字,如name, 此时实际上都直接放在根目录/下面,也可以为指定层次化目录结构(类似于ZooKeeper), 如:clusster1/node2/ name, 则将创建相应的目录结构。
CRUD即Create, Read, Update, Delete , 是符合REST风格的一套API操作规范。
1.设置某个键的值为给定值
[root@ken1 ~]# etcdctl set age 18 18
2.获取指定键的值
[root@ken1 ~]# etcdctl get age 18
3.更新键值
[root@ken1 ~]# etcdctl update age 20 20 [root@ken1 ~]# etcdctl get age 20
4.mk 如果给定的键不存在, 则创建一个新的键值。
[root@ken1 ~]# etcdctl mk address jiangsu jiangsu [root@ken1 ~]# etcdctl get address jiangsu
5.rm删除某个键值
[root@ken1 ~]# etcdctl rm address PrevNode.Value: jiangsu [root@ken1 ~]# etcdctl get address Error: 100: Key not found (/address) [8]
6.watch监测一个键值的变化, 一旦键值发生更新, 就会输出最新的值并退出。
[root@ken1 ~]# etcdctl watch name ken1
7.exec-watch
监测一个键值的变化, 一旦键值发生更新, 就执行给定命令。 这个功能十分强大, 很多时候可以用于实时根据键值更新本地服务的配置信息, 并重新加载服务。 可以实现分布式应用配置的自动分发。
例如, 一旦检测到键值被更新, 则执行ls命令:
[root@ken1 ~]# etcdctl exec-watch name -- sh -c "ls" anaconda-ks.cfg default.etcd etcd-v3.3.1-linux-amd64 etcd-v3.3.1-linux-amd64.tar.gz
8.1s
列出目录(默认为根目录)下的键或者子目录, 默认不显示子目录中内容。 例如:
[root@ken1 ~]# etcdctl set key hi hi [root@ken1 ~]# etcdctl set ken/key hi1 hi1 [root@ken1 ~]# etcdctl ls /name /age /key /ken [root@ken1 ~]# etcdctl ls ken /ken/key
9.mkdir
如果给定的键目录不存在, 则创建一个新的键目录。 例如:
[root@ken1 ~]# etcdctl mkdir test [root@ken1 ~]# etcdctl ls /name /age /key /ken /test
10.rmdir
删除一个空目录, 或者键值对。若目录不空, 会报错, 例如:
[root@ken1 ~]# etcdctl rmdir test [root@ken1 ~]# etcdctl rmdir ken Error: 108: Directory not empty (/ken) [14]
11.setdir
创建一个键目录, 无论存在与否。 实际上, 目前版本当目录已经存在的时候会报错,
例如:
[root@ken1 ~]# etcdctl setdir test [root@ken1 ~]# etcdctl ls /name /age /key /ken /test
12.updatedir
更新一个已经存在的目录的属性(目前只有存活时间), 例如:
[root@ken1 ~]# etcdctl mkdir test1 --ttl 100 [root@ken1 ~]# etcdctl updatedir test1 --ttl 200
支待的选项为—ttlvalue: 超时时间(单位为秒),默认值为0, 意味着永不超时。
非数据类操作
非数据类操作不直接对数据本身进行管理, 而是负责围绕集群自身的一些配置。
1.cluster-health
查看Etcd集群的健康状态。 例如:
[root@ken1 ~]# etcdctl cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379 cluster is healthy
2.member
通过list、add、remove等子命令列出、 添加、 删除Etcd实例到Etcd集群中。 例如, 本
地启动一个Etcd服务实例后, 可以用如下命令进行查看 默认的实例成员:
[root@ken1 ~]# etcdctl member list 8e9e05c52164694d: name=default peerURLs=http://localhost:2380 clientURLs=http://localhost:2379 isLeader=true
3.user
对用户进行管理, 包括一系列子命令:
add: 添加一个用户;
get:查询用户细节;
list: 列出所有用户;
remove: 删除用户;
grant:添加用户到角色;
revoke: 删除用户的角色;
passwd: 修改用户的密码。
默认情况下, 需要先创建(启用) root用户作为etcd集群的最高权限管理员:
会要求输入密码
[root@ken1 ~]# etcdctl user add root New password: User root created
分配某些已有角色给用户
[root@ken1 ~]# etcdctl user grant root --roles root auth: Granting duplicate role root for user root
4.role
对用户角色进行管理,包括一系列子命令:
add :添加一个角色;
get :查询角色细节;
list 列出所有用户角色;
remove :删除用户角色;
grant 添加路径到角色控制,可以为 read write 或者 readwrite;
revoke 删除某路径的用户角色信息
默认带有 root,guest 两种角色,前者为全局最高权限,后者为不带验证情况下的用户
例如
[root@ken1 ~]# etcdctl role add testrole Role testrole created [root@ken1 ~]# etcdctl role list root testrole
[root@ken1 ~]# etcdctl role grant testrole --path='/ken/*' --rw Role testrole updated
5.auth
是否启用访问验证 enable 为启用, disable 禁用。例如,在 root 用户创建后,启用
认证:
[root@ken1 ~]# etcdctl auth enable Authentication Enabled
Etcd 集群管理
tcd 集群也采用了典型的“主一从”模型,通过 Raft 协议来保证在 段时间内有一个节点为主节点 ,其 节点为从节点 一旦主节点发生故障其他节点可以自动再重新选举出新的主节点。与其他分布式系统类似,集群中节点个数推荐为奇数个,最少为3个,此时 quorum为2,越多节点个数自然能提供更多的冗余’性 ,但同时会带来写数据性能的下降
在分布式系统中有一个很重要的概念 quorum ,意味着一个集群正常工作需要能参加投票的节点个数的最小值
构建集群
构建集群无非是让节点们知道自己加入了哪个集群,其他对等节点的访问信息是啥。
Etcd 支持两种模式来构建集群:静态配 和动态发现
.静态配置集群信息
顾名思义, 静态配置就是提取写好集群中的有关信息。接下来演示使用三个节点创建集群
第一步:首先在各个 点上将地址和别名信息添加到 etc/hosts
[root@ken1 ~]# cat /etc/hosts localhost 127.0.0.1 ken1 192.168.64.5 ken2 192.168.64.6 ken3 192.168.64.7
第二步:需要在每个节点安装etcd
略
第三步:可以通过如下命令来启动各个节点上 etcd 服务 ,分别命名为 nl n2 n3
在节点1上,执行如下命令:
[root@ken1 ~]# etcd --name n1 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.64.5:2379,http://127.0.0.1:2379 --listen-peer-urls http://192.168.64.5:2380 --advertise-client-urls http://192.168.64.5:2379 --initial-advertise-peer-urls http://ken1:2380 --initial-cluster n1=http://ken1:2380,n2=http://ken2:2380,n3=http://ken3:2380
参数分析
-name 节点名称
-initial-advertise-peer-urls 通知其他 Etcd 实例地址
-listen-peer-urls 监听其他 Etcd 实例的地址
-initial-cluster-token 初始化集群 token
-initial-cluster 初始化集群内节点地址
-initial-cluster-state 初始化集群状态,new 表示新建
在节点2上执行如下的命令:
[root@ken2 ~]# etcd --name n2 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.64.6:2379,http://127.0.0.1:2379 --listen-peer-urls http://192.168.64.6:2380 --advertise-client-urls http://192.168.64.6:2379 --initial-advertise-peer-urls http://ken2:2380 --initial-cluster n1=http://ken1:2380,n2=http://ken2:2380,n3=http://ken3:2380
在节点3上执行如下的命令:
[root@ken3 ~]# etcd --name n3 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.64.7:2379,http://127.0.0.1:2379 --listen-peer-urls http://192.168.64.7:2380 --advertise-client-urls http://192.168.64.7:2379 --initial-advertise-peer-urls http://ken3:2380 --initial-cluster n1=http://ken1:2380,n2=http://ken2:2380,n3=http://ken3:2380
成功后,可以在任一节点上通过 et cdctl 来查看当前集群中的成员信息:
[root@ken1 ~]# etcdctl member list 906a78458065a88a: name=n2 peerURLs=http://ken2:2380 clientURLs=http://192.168.64.6:2379 isLeader=false c41dc5eb2046fd27: name=n3 peerURLs=http://ken3:2380 clientURLs=http://192.168.64.7:2379 isLeader=true c7ce0761a258afbd: name=n1 peerURLs=http://ken1:2380 clientURLs=http://192.168.64.5:2379 isLeader=false
测试:在任意一台主机创建键值
[root@ken1 ~]# etcdctl set name1 ken1 ken1
可以在另外节点查看该键值
[root@ken2 ~]# etcdctl get name1 ken1
[root@ken1 ~]# etcdctl member list 906a78458065a88a: name=n2 peerURLs=http://ken2:2380 clientURLs=http://192.168.64.6:2379 isLeader=true c41dc5eb2046fd27: name=n3 peerURLs=http://ken3:2380 clientURLs=http://192.168.64.7:2379 isLeader=false c7ce0761a258afbd: name=n1 peerURLs=http://ken1:2380 clientURLs=http://192.168.64.5:2379 isLeader=false
当前主机点为ken2
把ken2集群退掉
可以发现主机点已经切换为ken3
[root@ken1 ~]# etcdctl member list 906a78458065a88a: name=n2 peerURLs=http://ken2:2380 clientURLs=http://192.168.64.6:2379 isLeader=false c41dc5eb2046fd27: name=n3 peerURLs=http://ken3:2380 clientURLs=http://192.168.64.7:2379 isLeader=true c7ce0761a258afbd: name=n1 peerURLs=http://ken1:2380 clientURLs=http://192.168.64.5:2379 isLeader=false
ken1
[root@ken1 ~]# etcdctl member list 906a78458065a88a: name=n2 peerURLs=http://ken2:2380 clientURLs=http://192.168.64.6:2379 isLeader=true c41dc5eb2046fd27: name=n3 peerURLs=http://ken3:2380 clientURLs=http://192.168.64.7:2379 isLeader=false c7ce0761a258afbd: name=n1 peerURLs=http://ken1:2380 clientURLs=http://192.168.64.5:2379 isLeader=false
当前主机点为ken2
把ken2集群退掉
可以发现主机点已经切换为ken3
[root@ken1 ~]# etcdctl member list 906a78458065a88a: name=n2 peerURLs=http://ken2:2380 clientURLs=http://192.168.64.6:2379 isLeader=false c41dc5eb2046fd27: name=n3 peerURLs=http://ken3:2380 clientURLs=http://192.168.64.7:2379 isLeader=true c7ce0761a258afbd: name=n1 peerURLs=http://ken1:2380 clientURLs=http://192.168.64.5:2379 isLeader=false