一、概述
ETCD是一個開源的、分布式的鍵值對數據存儲系統,由Go語言實現,用於存儲key-value鍵值對,同時不僅僅是存儲,主要用途是提供共享配置及服務發現,使用Raft一致性算法來管理高度可用的復制日志。有下面特點
簡單:定義明確,面向用戶的API(gRPC)
安全:具有可選客戶端證書身份驗證的自動TLS
快速:基准測試10,000次/秒
可靠:使用Raft正確分布
二、安裝
2.1、二進制安裝
- 下載地址:
wget https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz
- 解壓即可使用
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
- 解壓以后文件信息如下
2.2 docker化安裝
# docker run -itd -p 2379:2379 -p 2380:2380 --name etcd elcolio/etcd
進入docker容器就可以正常使用了
# docker exec -it etcd bash
不過版本有點老了
三、基本使用
1、啟動單節點服務
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcd
[WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead
2020-06-23 16:55:10.974638 I | etcdmain: etcd Version: 3.4.9
2020-06-23 16:55:10.974744 I | etcdmain: Git SHA: 54ba95891
2020-06-23 16:55:10.974781 I | etcdmain: Go Version: go1.12.17
2020-06-23 16:55:10.974815 I | etcdmain: Go OS/Arch: linux/amd64
2020-06-23 16:55:10.974851 I | etcdmain: setting maximum number of CPUs to 40, total number of available CPUs is 40
2020-06-23 16:55:10.974896 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd
[WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead
2020-06-23 16:55:10.975986 I | embed: name = default
2020-06-23 16:55:10.976024 I | embed: data dir = default.etcd
2020-06-23 16:55:10.976047 I | embed: member dir = default.etcd/member
2020-06-23 16:55:10.976078 I | embed: heartbeat = 100ms
2020-06-23 16:55:10.976102 I | embed: election = 1000ms
2020-06-23 16:55:10.976125 I | embed: snapshot count = 100000
2020-06-23 16:55:10.976156 I | embed: advertise client URLs = http://localhost:2379
2020-06-23 16:55:10.980673 I | etcdserver: starting member 8e9e05c52164694d in cluster cdf818194e3a8c32
raft2020/06/23 16:55:10 INFO: 8e9e05c52164694d switched to configuration voters=()
raft2020/06/23 16:55:10 INFO: 8e9e05c52164694d became follower at term 0
raft2020/06/23 16:55:10 INFO: newRaft 8e9e05c52164694d [peers: [], term: 0, commit: 0, applied: 0, lastindex: 0, lastterm: 0]
raft2020/06/23 16:55:10 INFO: 8e9e05c52164694d became follower at term 1
raft2020/06/23 16:55:10 INFO: 8e9e05c52164694d switched to configuration voters=(10276657743932975437)
2020-06-23 16:55:10.982217 W | auth: simple token is not cryptographically signed
2020-06-23 16:55:10.984728 I | etcdserver: starting server... [version: 3.4.9, cluster version: to_be_decided]
2020-06-23 16:55:10.985016 I | etcdserver: 8e9e05c52164694d as single-node; fast-forwarding 9 ticks (election ticks 10)
raft2020/06/23 16:55:10 INFO: 8e9e05c52164694d switched to configuration voters=(10276657743932975437)
2020-06-23 16:55:10.985788 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32
2020-06-23 16:55:10.989122 I | embed: listening for peers on 127.0.0.1:2380
raft2020/06/23 16:55:11 INFO: 8e9e05c52164694d is starting a new election at term 1
raft2020/06/23 16:55:11 INFO: 8e9e05c52164694d became candidate at term 2
raft2020/06/23 16:55:11 INFO: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 2
raft2020/06/23 16:55:11 INFO: 8e9e05c52164694d became leader at term 2
raft2020/06/23 16:55:11 INFO: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2
2020-06-23 16:55:11.482246 I | etcdserver: setting up the initial cluster version to 3.4
2020-06-23 16:55:11.482468 I | etcdserver: published {Name:default ClientURLs:[http://localhost:2379]} to cluster cdf818194e3a8c32
2020-06-23 16:55:11.482523 I | embed: ready to serve client requests
2020-06-23 16:55:11.482594 N | etcdserver/membership: set the initial cluster version to 3.4
2020-06-23 16:55:11.482737 I | etcdserver/api: enabled capabilities for version 3.4
2020-06-23 16:55:11.483780 N | embed: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
啟動信息說明:
name表示節點名稱,默認為default。
data-dir 保存日志和快照的目錄,默認為當前工作目錄default.etcd/目錄下。
在http://localhost:2380和集群中其他節點通信。
在http://localhost:2379提供HTTP API服務,供客戶端交互。
heartbeat為100ms,該參數的作用是leader多久發送一次心跳到followers,默認值是100ms。
election為1000ms,該參數的作用是重新投票的超時時間,如果follow在該超時時間間隔沒有收到心跳包,會觸發重新投票,默認為1000ms。
snapshot count為100000,該參數的作用是指定有多少事務被提交時,觸發截取快照保存到磁盤。
集群和每個節點都會生成一個uuid。
啟動的時候會運行raft,選舉出leader。
如果是測試,可以直接使用 ./etcd 啟動,當然還可以配置其他參
列如:
啟動時指定節點名稱和數據存放目錄
./etcd --name 'test' --data-dir test.dir
./etcd --data-dir ./data --listen-client-urls 'http://192.168.1.15:2379' --advertise-client-urls 'http://192.168.1.15:2379'
查看數據目錄信息
(base) [root@localhost etcd-v3.4.9-linux-amd64]# tree test.dir/
test.dir/
└── member
├── snap
│ └── db
└── wal
├── 0000000000000000-0000000000000000.wal
└── 0.tmp
3 directories, 3 files
① snap:存放快照信息
② wal: 存放數據庫的操作日志信息,wal就是(wal-ahead log)預寫日志。類似於hbase的wal,主要是保存數據的可用性。可以使用 --wal-dir 指定其他的存儲位置。
./etcd -h
Member:
--name 'default'
Human-readable name for this member.
--data-dir '${name}.etcd'
Path to the data directory.
--wal-dir ''
Path to the dedicated wal directory.
--snapshot-count '100000'
Number of committed transactions to trigger a snapshot to disk.
--heartbeat-interval '100'
Time (in milliseconds) of a heartbeat interval.
--election-timeout '1000'
Time (in milliseconds) for an election to timeout. See tuning documentation for details.
--initial-election-tick-advance 'true'
Whether to fast-forward initial election ticks on boot for faster election.
--listen-peer-urls 'http://localhost:2380'
List of URLs to listen on for peer traffic.
--listen-client-urls 'http://localhost:2379'
List of URLs to listen on for client traffic.
--max-snapshots '5'
Maximum number of snapshot files to retain (0 is unlimited).
--max-wals '5'
Maximum number of wal files to retain (0 is unlimited).
--quota-backend-bytes '0'
Raise alarms when backend size exceeds the given quota (0 defaults to low space quota).
--backend-batch-interval ''
BackendBatchInterval is the maximum time before commit the backend transaction.
--backend-batch-limit '0'
BackendBatchLimit is the maximum operations before commit the backend transaction.
--max-txn-ops '128'
Maximum number of operations permitted in a transaction.
--max-request-bytes '1572864'
Maximum client request size in bytes the server will accept.
--grpc-keepalive-min-time '5s'
Minimum duration interval that a client should wait before pinging server.
--grpc-keepalive-interval '2h'
Frequency duration of server-to-client ping to check if a connection is alive (0 to disable).
--grpc-keepalive-timeout '20s'
Additional duration of wait before closing a non-responsive connection (0 to disable).
.........
檢查服務狀態
(base) [root@localhost etcd-v3.4.9-linux-amd64]# curl -L localhost:2379/health
{"health":"true"}
2、put :設置鍵值對
# ./etcdctl put key value #老版本的是set命令,目前的版本是第三版,老版本對應v2版。
OK
或者:
./etcdctl --endpoints=192.168.1.15:2379 put key value
3、get :獲取指定key的信息,當鍵不存在的時候返回會空,不會報錯。
① 獲取指定key
# ./etcdctl get key
key
value
② 只獲取值
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl get key --print-value-only #獲取數據的時候不獲取key,僅僅只獲取值
value
③ 前綴匹配key或者說過濾key
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl get --prefix k --print-value-only
v1
v4
v7
value
3、grant :授權租期(TTL)
# ./etcdctl lease grant 20 #設置TTL為20秒
lease 694d72e06369850f granted with TTL(20s)
# ./etcdctl put --lease=694d72e06369850f k2 v2 #插入數據的時候指定TTL
OK
# ./etcdctl get k2
k2
v2
# ./etcdctl get k2 #20秒過后數據將會被刪除
#
4、revoke : 回收租期
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl lease grant 60
lease 694d72e063698515 granted with TTL(60s)
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl put --lease=694d72e063698515 k3 v3
OK
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl lease revoke 694d72e063698515 #回收租期
lease 694d72e063698515 revoked
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl get k3 #租期回收以后,數據將會刪除
(base) [root@localhost etcd-v3.4.9-linux-amd64]#
5、keep-alive :讓租期保持一致存活
./etcdctl lease keep-alive 694d72e06369851a
lease 694d72e06369851a keepalived with TTL(10)
lease 694d72e06369851a keepalived with TTL(10)
lease 694d72e06369851a keepalived with TTL(10)
lease 694d72e06369851a keepalived with TTL(10)
lease 694d72e06369851a keepalived with TTL(10)
lease 694d72e06369851a keepalived with TTL(10)
lease 694d72e06369851a keepalived with TTL(10)
(base) [root@localhost etcd-v3.4.9-linux-amd64]# date;./etcdctl put --lease=694d72e06369851a k6 v6 #插入數據
Tue Jun 23 17:27:02 CST 2020
OK
(base) [root@localhost etcd-v3.4.9-linux-amd64]# date;./etcdctl get k6 #獲取數據,10秒鍾以后數據還是存活的
Tue Jun 23 17:27:13 CST 2020
k6
v6
(base) [root@localhost etcd-v3.4.9-linux-amd64]# date;./etcdctl get k6 #crtl + c停止存活,可以發現數據就消失了
Tue Jun 23 17:28:17 CST 2020
(base) [root@localhost etcd-v3.4.9-linux-amd64]#
6、member list :查看集群成員信息
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl member list
8e9e05c52164694d, started, default, http://localhost:2380, http://localhost:2379, false
7、創建用戶
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user list
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user add test1
Password of test1: #輸入密碼
Type password of test1 again for confirmation: #再次確實密碼
User test1 created
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user get test1
User: test1
Roles: #顯示用戶屬於哪個角色
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user list
test1
(base) [root@localhost etcd-v3.4.9-linux-amd64]#
8、創建角色
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl role add role1
Role role1 created
9、給用戶授權角色
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user grant-role test1 role1 #grant-role 用戶名 角色名
Role role1 is granted to user test1
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user get test1
User: test1
Roles: role1
(base) [root@localhost etcd-v3.4.9-linux-amd64]#
10、開啟認證
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl auth enable --user='test1'
Password:
{"level":"warn","ts":"2020-06-23T17:43:15.804+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-aa4e66e9-684d-4966-867a-03dcdf79cb0c/127.0.0.1:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: authentication is not enabled"}
{"level":"warn","ts":"2020-06-23T17:43:15.806+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-aa4e66e9-684d-4966-867a-03dcdf79cb0c/127.0.0.1:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: root user does not exist"}
Error: etcdserver: root user does not exist #需要創建一個root用戶
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl user add root
Password of root:
Type password of root again for confirmation:
User root created
(base) [root@localhost etcd-v3.4.9-linux-amd64]# ./etcdctl auth enable --user='test1'
Password:
{"level":"warn","ts":"2020-06-23T17:43:55.778+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-261be6df-24f4-40ea-99c4-918878caedf1/127.0.0.1:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: authentication is not enabled"}
{"level":"warn","ts":"2020-06-23T17:43:55.780+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-261be6df-24f4-40ea-99c4-918878caedf1/127.0.0.1:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: root user does not have root role"}
Authentication Enabled
(base) [root@localhost etcd-v3.4.9-linux-amd64]#