etcd
etcd简介
- etcd是一个键值存储仓库,用于配置共享和服务发现。用于共享配置和服务发现的高可用性密钥值存储。
- tcd 是 CoreOS 团队于 2013 年 6 月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库,基于 Go 语言实现。我们知道,在分布式系统中,各种服务的配置信息的管理分享,服务的发现是一个很基本同时也是很重要的问题。CoreOS 项目就希望基于 etcd 来解决这一问题。
- 最新和版本是:3.2.5 官网:https://coreos.com/etcd/
- 一般情况下,用户使用 etcd 可以在多个节点上启动多个实例,并添加它们为一个集群。同一个集群中的 etcd 实例将会保持彼此信息的一致性。
- etcd gateway没有提升性能等作用,它的作用就是当很多应用程序连接etcd的时候,如果etcd节点ip变了,那么不需要更改应用程序,只需要更改etcd gateway就可以了。
etcd特点
- 简单:基于HTTP+JSON的API让你用curl就可以轻松使用。
- 安全:可选SSL客户认证机制。
- 快速:每个实例每秒支持一千次写操作。
- 可信:使用Raft算法充分实现了分布式结构 。
- 2379:提供http api服务,供客户端交互。
- 2380:和集群其他节点通信
etcd系统限制方面
- etcd设计用于处理典型的元数据的小键值对。较大的请求将起作用,但可能会增加其他请求的延迟。目前,etcd保证支持高达1MB数据的RPC请求。将来,尺寸限制可能会松动或可配置
- Storage size limit:The default storage size limit is 2GB,configurable with –quota-backend-bytes flag;supports up to 8GB。
etcd安装
yum安装
yum install etcd -y
编译安装最新的
参考官方的文档:https://github.com/coreos/etcd/blob/master/Documentation/dl_build.md#build-the-latest-version
参考上面的文档,这种安装方法有几种,因为etcd是golang写的,所以需要安装go,但可以不安装go的情况下安装,如下:
$ git clone https://github.com/coreos/etcd.git $ cd etcd $ ./build
二进制安装(包含docker运行)
参考官方说明:https://github.com/coreos/etcd/releases/
wget https://github.com/coreos/etcd/releases/download/v3.2.5/etcd-v3.2.5-linux-amd64.tar.gz
解压之后 直接加参数运行,最好是用supervisor来管理。
如用docker启动三个节点组成一个集群:
docker run \ -p 2379:2379 \ -p 2380:2380 \ --network clc \ --ip 172.18.0.101 \ -d \ --name etcd1 \ --volume=/etc/localtime:/etc/localtime:ro \ --volume=/home/docker/etcd/etcd_node1:/etcd-data \ quay.io/coreos/etcd \ /usr/local/bin/etcd \ --name etcd-node1 \ --data-dir /etcd-data \ --listen-client-urls http://0.0.0.0:2379 \ --listen-peer-urls http://0.0.0.0:2380 \ --advertise-client-urls http://172.18.0.101:2379 \ --initial-advertise-peer-urls http://172.18.0.101:2380 \ --initial-cluster "etcd-node1=http://172.18.0.101:2380,etcd-node2=http://172.18.0.102:2380,etcd-node3=http://172.18.0.103:2380" \ --initial-cluster-token my-etcd-token \ --initial-cluster-state new docker run \ -p 2389:2379 \ --network clc \ --ip 172.18.0.102 \ -d \ --name etcd2 \ --volume=/etc/localtime:/etc/localtime:ro \ --volume=/home/docker/etcd/etcd_node2:/etcd-data \ quay.io/coreos/etcd \ /usr/local/bin/etcd \ --name etcd-node2 \ --data-dir /etcd-data \ --listen-client-urls http://0.0.0.0:2379 \ --listen-peer-urls http://0.0.0.0:2380 \ --advertise-client-urls http://172.18.0.102:2379 \ --initial-advertise-peer-urls http://172.18.0.102:2380 \ --initial-cluster "etcd-node1=http://172.18.0.101:2380,etcd-node2=http://172.18.0.102:2380,etcd-node3=http://172.18.0.103:2380" \ --initial-cluster-token my-etcd-token \ --initial-cluster-state new docker run \ -p 2399:2379 \ --network clc \ --ip 172.18.0.103 \ -d \ --name etcd3 \ --volume=/etc/localtime:/etc/localtime:ro \ --volume=/home/docker/etcd/etcd_node3:/etcd-data \ quay.io/coreos/etcd \ /usr/local/bin/etcd \ --name etcd-node3 \ --data-dir /etcd-data \ --listen-client-urls http://0.0.0.0:2379 \ --listen-peer-urls http://0.0.0.0:2380 \ --advertise-client-urls http://172.18.0.103:2379 \ --initial-advertise-peer-urls http://172.18.0.103:2380 \ --initial-cluster "etcd-node1=http://172.18.0.101:2380,etcd-node2=http://172.18.0.102:2380,etcd-node3=http://172.18.0.103:2380" \ --initial-cluster-token my-etcd-token \ --initial-cluster-state new
参数说明
--name 节点名称 --data-dir 指定节点的数据存储目录 --config-file 指定配置文件的路径 --listen-peer-urls 监听URL,用于与其他节点通讯(2380端口) --listen-client-urls 对外提供服务的地址:比如 http://ip:2379,http://127.0.0.1:2379 ,客户端会连接到这里和 etcd 交互 --advertise-client-urls 对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点(2379端口) --initial-advertise-peer-urls 该节点同伴监听地址,这个值会告诉集群中其他节点 --initial-cluster 集群中所有节点的信息,格式为 node1=http://ip1:2380,node2=http://ip2:2380,… 。注意:这里的 node1 是节点的 --name 指定的名字;后面的 ip1:2380 是 --initial-advertise-peer-urls 指定的值 --initial-cluster-state 新建集群的时候,这个值为 new ;假如已经存在的集群,这个值为 existing --initial-cluster-token 创建集群的 token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点 uuid;否则会导致多个集群之间的冲突,造成未知的错误 --eletion-timeout:重新投票的超时时间,如果 follow 在该时间间隔没有收到心跳包,会触发重新投票,默认为 1000 ms --snapshot-count:指定有多少事务(transaction)被提交时,触发截取快照保存到磁盘 所有以 --init 开头的配置都是在 bootstrap 集群的时候才会用到
配置文件样例
# [member] ETCD_NAME=node3 ETCD_DATA_DIR="/data/etcd/node3.etcd" #ETCD_WAL_DIR="" #ETCD_SNAPSHOT_COUNT="10000" #ETCD_HEARTBEAT_INTERVAL="100" #ETCD_ELECTION_TIMEOUT="1000" ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" #ETCD_MAX_SNAPSHOTS="5" #ETCD_MAX_WALS="5" #ETCD_CORS="" # #[cluster] ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.7.232:2380" # if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..." ETCD_INITIAL_CLUSTER="node2=http://192.168.7.231:2380,node3=http://192.168.7.232:2380" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_ADVERTISE_CLIENT_URLS="http://192.168.7.232:2379" #ETCD_DISCOVERY="" #ETCD_DISCOVERY_SRV="" #ETCD_DISCOVERY_FALLBACK="proxy" #ETCD_DISCOVERY_PROXY="" #ETCD_STRICT_RECONFIG_CHECK="false" #ETCD_AUTO_COMPACTION_RETENTION="0" # #[proxy] #ETCD_PROXY="off" #ETCD_PROXY_FAILURE_WAIT="5000" #ETCD_PROXY_REFRESH_INTERVAL="30000" #ETCD_PROXY_DIAL_TIMEOUT="1000" #ETCD_PROXY_WRITE_TIMEOUT="5000" #ETCD_PROXY_READ_TIMEOUT="0" # #[security] #ETCD_CERT_FILE="" #ETCD_KEY_FILE="" #ETCD_CLIENT_CERT_AUTH="false" #ETCD_TRUSTED_CA_FILE="" #ETCD_AUTO_TLS="false" #ETCD_PEER_CERT_FILE="" #ETCD_PEER_KEY_FILE="" #ETCD_PEER_CLIENT_CERT_AUTH="false" #ETCD_PEER_TRUSTED_CA_FILE="" #ETCD_PEER_AUTO_TLS="false" # #[logging] #ETCD_DEBUG="false" # examples for -log-package-levels etcdserver=WARNING,security=DEBUG #ETCD_LOG_PACKAGE_LEVELS="" # #[profiling] #ETCD_ENABLE_PPROF="false" #ETCD_METRICS="basic"
etcd集群部署
可以参考:http://cizixs.com/2016/08/02/intro-to-etcd
集群简介
每个 etcd cluster 都是有若干个 member 组成的,每个 member 是一个独立运行的 etcd 实例,单台机器上可以运行多个 member。
在正常运行的状态下,集群中会有一个 leader,其余的 member 都是 followers。leader 向 followers 同步日志,保证数据在各个 member 都有副本。leader 还会定时向所有的 member 发送心跳报文,如果在规定的时间里 follower 没有收到心跳,就会重新进行选举。
客户端所有的请求都会先发送给 leader,leader 向所有的 followers 同步日志,等收到超过半数的确认后就把该日志存储到磁盘,并返回响应客户端。
每个 etcd 服务有三大主要部分组成:raft 实现、WAL 日志存储、数据的存储和索引。WAL 会在本地磁盘(就是之前提到的 –data-dir)上存储日志内容(wal file)和快照(snapshot)
部署机制或方案有三种
- Static 静态配置机制
- etcd Discovery etcd发现
- DNS Discovery dns发现。
静态部署
启动前我们知道集群成员及他们的地址和集群大小,这时可以静态配置,可以通过initial-cluster来标记启动离线配置。
配置文件参考上面的docker启动时的文件
如果是在配置文件中配置的话,
ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380" ETCD_INITIAL_CLUSTER_STATE=new
命令行是:
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \ --initial-cluster-state new
etcdctl及http相关查询及备份操作
备份
etcdctl backup --data-dir /usr/local/etcd/niub3.etcd/ --backup-dir /backup/etcd_backup
http来获取相关信息
查看版本
[root@docker etcd]# curl http://192.168.7.211:2379/version {"etcdserver":"3.2.4","etcdcluster":"3.2.0"}
查看信息leader及followers的基本信息
/v2/stats/leader
[root@docker etcd]# curl http://192.168.7.211:2389/v2/stats/leader {"leader":"46bae016bbec6cc4","followers":{"62629576a6e5b9ff":{"latency":{"current":0.001565,"average":0.0046895781250000015,"standardDeviation":0.011505109292729316,"minimum":0.000293,"maximum":0.069893},"counts":{"fail":1,"success":64}},"7f5ae4d7f090a8b9":{"latency":{"current":0.002155,"average":0.07266914285714286,"standardDeviation":0.16934280627972914,"minimum":0.001008,"maximum":0.487454},"counts":{"fail":0,"success":7}}}}
会返回当前节点的信息
/v2/stats/self
[root@docker etcd]# curl http://192.168.7.211:2389/v2/stats/self {"name":"etcd-node2","id":"46bae016bbec6cc4","state":"StateLeader","startTime":"2017-08-09T09:32:59.64908421+08:00","leaderInfo":{"leader":"46bae016bbec6cc4","uptime":"9h43m16.864641954s","startTime":"2017-08-09T10:11:12.253310502+08:00"},"recvAppendRequestCnt":5,"sendAppendRequestCnt":72}
返回各种命令的统计信息
/v2/state/store
[root@docker etcd]# curl http://192.168.7.211:2389/v2/stats/store {"getsSuccess":2,"getsFail":5,"setsSuccess":19,"setsFail":0,"deleteSuccess":0,"deleteFail":0,"updateSuccess":0,"updateFail":0,"createSuccess":3,"createFail":0,"compareAndSwapSuccess":0,"compareAndSwapFail":0,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":0,"watchers":0}
返回各成员信息
/v2/members
[root@docker etcd]# curl http://192.168.7.211:2389/v2/members {"members":[{"id":"46bae016bbec6cc4","name":"etcd-node2","peerURLs":["http://172.18.0.102:2380"],"clientURLs":["http://172.18.0.102:2379"]},{"id":"62629576a6e5b9ff","name":"etcd-node1","peerURLs":["http://172.18.0.101:2380"],"clientURLs":["http://172.18.0.101:2379"]},{"id":"7f5ae4d7f090a8b9","name":"etcd-node3","peerURLs":["http://172.18.0.103:2380"],"clientURLs":["http://172.18.0.103:2379"]}]} [root@docker etcd]#
set
指定某个键的值。例如
$ etcdctl set /testdir/testkey "Hello world" Hello world
支持的选项包括:
--ttl '0' 该键值的超时时间(单位为秒),不配置(默认为 0)则永不超时 --swap-with-value value 若该键现在的值是 value,则进行设置操作 --swap-with-index '0' 若该键现在的索引值是指定索引,则进行设置操作
get
获取指定键的值。例如
$ etcdctl set testkey hello hello $ etcdctl update testkey world world
当键不存在时,则会报错。例如
$ etcdctl get testkey2 Error: 100: Key not found (/testkey2) [1]
支持的选项为
--sort 对结果进行排序 --consistent 将请求发给主节点,保证获取内容的一致性
update
当键存在时,更新值内容。例如
$ etcdctl set testkey hello hello $ etcdctl update testkey world world
当键不存在时,则会报错。例如
$ etcdctl update testkey2 world
支持的选项为
--ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时
rm
删除某个键值。例如
$ etcdctl rm testkey
当键不存在时,则会报错。例如
$ etcdctl rm testkey2 Error: 100: Key not found (/testkey2) [8]
支持的选项为
--dir 如果键是个空目录或者键值对则删除 --recursive 删除目录和所有子键 --with-value 检查现有的值是否匹配 --with-index '0' 检查现有的 index 是否匹配
mk
如果给定的键不存在,则创建一个新的键值。例如
$ etcdctl mk /testdir/testkey "Hello world" Hello world
当键存在的时候,执行该命令会报错,例如
$ etcdctl set testkey "Hello world" Hello world $ ./etcdctl mk testkey "Hello world" Error: 105: Key already exists (/testkey) [2]
支持的选项为
--ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时
mkdir
如果给定的键目录不存在,则创建一个新的键目录。例如
$ etcdctl mkdir testdir
当键目录存在的时候,执行该命令会报错,例如
$ etcdctl mkdir testdir $ etcdctl mkdir testdir Error: 105: Key already exists (/testdir) [7]
支持的选项为
--ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时
setdir
创建一个键目录,无论存在与否。
支持的选项为
--ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时
updatedir
更新一个已经存在的目录。 支持的选项为
--ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时
rmdir
删除一个空目录,或者键值对。
若目录不空,会报错
$ etcdctl set /dir/testkey hi hi $ etcdctl rmdir /dir Error: 108: Directory not empty (/dir) [13]
ls
列出目录(默认为根目录)下的键或者子目录,默认不显示子目录中内容。
例如
$ ./etcdctl set testkey 'hi' hi $ ./etcdctl set dir/test 'hello' hello $ ./etcdctl ls /testkey /dir $ ./etcdctl ls dir /dir/test
支持的选项包括
--sort 将输出结果排序 --recursive 如果目录下有子目录,则递归输出其中的内容 -p 对于输出为目录,在最后添加 `/` 进行区分
非数据库操作
backup
备份 etcd 的数据。
支持的选项包括
--data-dir etcd 的数据目录 --backup-dir 备份到指定路径
watch
监测一个键值的变化,一旦键值发生更新,就会输出最新的值并退出。
例如,用户更新 testkey 键值为 Hello world。
$ etcdctl watch testkey Hello world
支持的选项包括
--forever 一直监测,直到用户按 `CTRL+C` 退出 --after-index '0' 在指定 index 之前一直监测 --recursive 返回所有的键值和子键值
exec-watch
监测一个键值的变化,一旦键值发生更新,就执行给定命令。
例如,用户更新 testkey 键值。
$etcdctl exec-watch testkey -- sh -c 'ls' default.etcd Documentation etcd etcdctl etcd-migrate README-etcdctl.md README.md
支持的选项包括
--after-index '0' 在指定 index 之前一直监测 --recursive 返回所有的键值和子键值
member
通过 list、add、remove 命令列出、添加、删除 etcd 实例到 etcd 集群中。
例如本地启动一个 etcd 服务实例后,可以用如下命令进行查看。
$ etcdctl member list ce2a822cea30bfca: name=default peerURLs=http://localhost:2380,http://localhost:7001 clientURLs=http://localhost:2379,http://localhost:4001
命令选项
--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
打印版本信息
etcd报错总结
docker启动报错
报错如下:
etcdmain: couldn't find local name "etcd-node4" in the initial cluster configuration
解决方法:
配置参数有问题:–initial-cluster “etcd-node1=http:ip:2380,”,双引号里的内容没有空格,有空格就会有一台报以上错误 。
docker启动命令:
#docker network create --subnet 172.18.0.0/16 --driver bridge clc
docker run \
-p 2379:2379 \
-p 2380:2380 \
--network clc \
--ip 172.18.0.101 \
-d \
--name etcd1 \
--volume=/root/docker/etcd-docker/etcd-node1:/etcd-data \
quay.io/coreos/etcd \
/usr/local/bin/etcd \
--name etcd-node1 \
--data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://172.18.0.101:2379 \
--initial-advertise-peer-urls http://172.18.0.101:2380 \
--initial-cluster "etcd-node1=http://172.18.0.101:2380,etcd-node2=http://172.18.0.102:2380,etcd-node3=http://172.18.0.103:2380" \
--initial-cluster-token my-etcd-token \
--initial-cluster-state new
docker run \
-p 2389:2379 \
-p 2390:2380 \
--network clc \
--ip 172.18.0.102 \
-d \
--name etcd2 \
--volume=/root/docker/etcd-docker/etcd-node2:/etcd-data \
quay.io/coreos/etcd \
/usr/local/bin/etcd \
--name etcd-node2 \
--data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://172.18.0.102:2379 \
--initial-advertise-peer-urls http://172.18.0.102:2380 \
--initial-cluster "etcd-node1=http://172.18.0.101:2380,etcd-node2=http://172.18.0.102:2380,etcd-node3=http://172.18.0.103:2380" \
--initial-cluster-token my-etcd-token \
--initial-cluster-state new
docker run \
-p 2399:2379 \
-p 2400:2380 \
--network clc \
--ip 172.18.0.103 \
-d \
--name etcd3 \
--volume=/root/docker/etcd-docker/etcd-node3:/etcd-data \
quay.io/coreos/etcd \
/usr/local/bin/etcd \
--name etcd-node3 \
--data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://172.18.0.103:2379 \
--initial-advertise-peer-urls http://172.18.0.103:2380 \
--initial-cluster "etcd-node1=http://172.18.0.101:2380,etcd-node2=http://172.18.0.102:2380,etcd-node3=http://172.18.0.103:2380" \
--initial-cluster-token my-etcd-token \
--initial-cluster-state new
原文链接:ETCD,转载请注明来源!