一文深入淺出 ETCD
一 概述
背景:近期 k8s 應用中 etcd 的功能存在一些困惑,對其進行來單獨的學習,能更深入理解 k8s 中的的一些特性。
1.1 etcd 簡介
etcd 是 CoreOS 團隊於 2013 年 6 月發起的開源項目,它的目標是構建一個高可用的分佈式鍵值 (key-value) 數據庫。etcd 內部採用raft
協議作爲一致性算法,etcd 基於 Go 語言實現。
1.2 發展歷史
1.3 etcd 的特點
-
簡單:安裝配置簡單,而且提供了 HTTP API 進行交互,使用也很簡單
-
安全:支持 SSL 證書驗證
-
快速:根據官方提供的 benchmark 數據,單實例支持每秒 2k + 讀操作
-
可靠:採用 raft 算法,實現分佈式系統數據的可用性和一致性
1.4 概念術語
-
Raft:etcd 所採用的保證分佈式系統強一致性的算法。
-
Node:一個 Raft 狀態機實例。
-
Member:一個 etcd 實例。它管理着一個 Node,並且可以爲客戶端請求提供服務。
-
Cluster:由多個 Member 構成可以協同工作的 etcd 集羣。
-
Peer:對同一個 etcd 集羣中另外一個 Member 的稱呼。
-
Client:向 etcd 集羣發送 HTTP 請求的客戶端。
-
WAL:預寫式日誌,etcd 用於持久化存儲的日誌格式。
-
snapshot:etcd 防止 WAL 文件過多而設置的快照,存儲 etcd 數據狀態。
-
Proxy:etcd 的一種模式,爲 etcd 集羣提供反向代理服務。
-
Leader:Raft 算法中通過競選而產生的處理所有數據提交的節點。
-
Follower:競選失敗的節點作爲 Raft 中的從屬節點,爲算法提供強一致性保證。
-
Candidate:當 Follower 超過一定時間接收不到 Leader 的心跳時轉變爲 Candidate 開始競選。
-
Term:某個節點成爲 Leader 到下一次競選時間,稱爲一個 Term。
-
Index:數據項編號。Raft 中通過 Term 和 Index 來定位數據。
1.5 數據讀寫順序
爲了保證數據的強一致性,etcd 集羣中所有的數據流向都是一個方向,從 Leader (主節點)流向 Follower,也就是所有 Follower 的數據必須與 Leader 保持一致,如果不一致會被覆蓋。
用戶對於 etcd 集羣所有節點進行讀寫
-
讀取:由於集羣所有節點數據是強一致性的,讀取可以從集羣中隨便哪個節點進行讀取數據
-
寫入:etcd 集羣有 leader,如果寫入往 leader 寫入,可以直接寫入,然後然後 Leader 節點會把寫入分發給所有 Follower,如果往 follower 寫入,然後 Leader 節點會把寫入分發給所有 Follower
1.6 leader 選舉
假設三個節點的集羣,三個節點上均運行 Timer(每個 Timer 持續時間是隨機的),Raft 算法使用隨機 Timer 來初始化 Leader 選舉流程,第一個節點率先完成了 Timer,隨後它就會向其他兩個節點發送成爲 Leader 的請求,其他節點接收到請求後會以投票迴應然後第一個節點被選舉爲 Leader。
成爲 Leader 後,該節點會以固定時間間隔向其他節點發送通知,確保自己仍是 Leader。有些情況下當 Follower 們收不到 Leader 的通知後,比如說 Leader 節點宕機或者失去了連接,其他節點會重複之前選舉過程選舉出新的 Leader。
1.7 判斷數據是否寫入
etcd 認爲寫入請求被 Leader 節點處理並分發給了多數節點後,就是一個成功的寫入。那麼多少節點如何判定呢,假設總結點數是 N,那麼多數節點 Quorum=N/2+1
。關於如何確定 etcd 集羣應該有多少個節點的問題,上圖的左側的圖表給出了集羣中節點總數 (Instances) 對應的 Quorum 數量,用 Instances 減去 Quorom 就是集羣中容錯節點(允許出故障的節點)的數量。
所以在集羣中推薦的最少節點數量是 3 個,因爲 1 和 2 個節點的容錯節點數都是 0,一旦有一個節點宕掉整個集羣就不能正常工作了。
二 etcd 架構及解析
2.1 架構圖
2.2 架構解析
從 etcd 的架構圖中我們可以看到,etcd 主要分爲四個部分。
-
HTTP Server:用於處理用戶發送的 API 請求以及其它 etcd 節點的同步與心跳信息請求。
-
Store:用於處理 etcd 支持的各類功能的事務,包括數據索引、節點狀態變更、監控與反饋、事件處理與執行等等,是 etcd 對用戶提供的大多數 API 功能的具體實現。
-
Raft:Raft 強一致性算法的具體實現,是 etcd 的核心。
-
WAL:Write Ahead Log(預寫式日誌),是 etcd 的數據存儲方式。除了在內存中存有所有數據的狀態以及節點的索引以外,etcd 就通過 WAL 進行持久化存儲。WAL 中,所有的數據提交前都會事先記錄日誌。
-
Snapshot 是爲了防止數據過多而進行的狀態快照;
-
Entry 表示存儲的具體日誌內容。
通常,一個用戶的請求發送過來,會經由 HTTP Server 轉發給 Store 進行具體的事務處理,如果涉及到節點的修改,則交給 Raft 模塊進行狀態的變更、日誌的記錄,然後再同步給別的 etcd 節點以確認數據提交,最後進行數據的提交,再次同步。
三 應用場景
3.1 服務註冊與發現
etcd 可以用於服務的註冊與發現
- 前後端業務註冊發現
中間價已經後端服務在 etcd 中註冊,前端和中間價可以很輕鬆的從 etcd 中發現相關服務器然後服務器之間根據調用關係相關綁定調用
- 多組後端服務器註冊發現
後端多個無狀態相同副本的 app 可以同事註冊到 etcd 中,前端可以通過 haproxy 從 etcd 中獲取到後端的 ip 和端口組,然後進行請求轉發,可以用來故障轉移屏蔽後端端口已經後端多組 app 實例。
3.2 消息發佈與訂閱
etcd 可以充當消息中間件,生產者可以往 etcd 中註冊 topic 併發送消息,消費者從 etcd 中訂閱 topic,來獲取生產者發送至 etcd 中的消息。
3.3 負載均衡
後端多組相同的服務提供者可以經自己服務註冊到 etcd 中,etcd 並且會與註冊的服務進行監控檢查,服務請求這首先從 etcd 中獲取到可用的服務提供者真正的 ip:port,然後對此多組服務發送請求,etcd 在其中充當了負載均衡的功能
3.4 分部署通知與協調
-
當 etcd watch 服務發現丟失,會通知服務檢查
-
控制器向 etcd 發送啓動服務,etcd 通知服務進行相應操作
-
當服務完成 work 會講狀態更新至 etcd,etcd 對應會通知用戶
3.5 分佈式鎖
當有多個競爭者 node 節點,etcd 作爲總控,在分佈式集羣中與一個節點成功分配 lock
3.6 分佈式隊列
有對個 node,etcd 根據每個 node 來創建對應 node 的隊列,根據不同的隊列可以在 etcd 中找到對應的 competitor
3.7 集羣與監控與 Leader 選舉
etcd 可以根據 raft 算法在多個 node 節點來選舉出 leader
四 安裝部署
4.1 單機部署
可以使用二進制或源碼下載安裝,但是危害需要自己寫配置文件,如何要啓動需要自己寫服務啓動文件,推薦使用 yum 安裝方式
可以查看 yum 安裝的 etcd 的有效配置文件,根據自己的需求來修改數據存儲目錄,已經監聽端口 url/etcd 的名稱等
-
etcd 默認將數據存放到當前路徑的
default.etcd/
目錄下 -
在
http://localhost:2380
和集羣中其他節點通信 -
在
http://localhost:2379
提供 HTTP API 服務,供客戶端交互 -
該節點的名稱默認爲
default
-
heartbeat 爲 100ms,後面會說明這個配置的作用
-
election 爲 1000ms,後面會說明這個配置的作用
-
snapshot count 爲 10000,後面會說明這個配置的作用
-
集羣和每個節點都會生成一個 uuid
-
啓動的時候,會運行 raft,選舉出 leader
[root@VM_0_8_centos tmp]# grep -Ev "^#|^$" /etc/etcd/etcd.confETCD_DATA_DIR="/var/lib/etcd/default.etcd"ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"ETCD_[root@VM_0_8_centos tmp]# systemctl status etcd複製代碼
# 4.2 集羣部署
集羣部署最好部署奇數位,此能達到最好的集羣容錯
4.2.1 主機信息
4.2.2 host 配置
在此示例用三個節點來部署 etcd 集羣,各節點修改 hosts
cat >> /etc/hosts << EOF
172.16.0.8 etcd-0-8
172.16.0.14 etcd-0-14
172.16.0.17 etcd-0-17
EOF
4.2.3 etcd 安裝
三個節點均安裝 etcd
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
yum -y install etcd
systemctl enable etcdmkdir -p /data/app/etcd/chown etcd:etcd /data/app/etcd/複製代碼
4.2.4 etcd配置
- etcd 默認配置文件
[root@etcd-0-8 app]# cat /etc/etcd/etcd.conf#[Member]#ETCD_CORS=""ETCD_DATA_DIR="/data/app/etcd/" # etcd數據存儲目錄,建議存儲在數據盤#ETCD_WAL_DIR=""ETCD_LISTEN_PEER_URLS="http://172.16.0.8:2380" # 與同伴的通訊地址,和其他節點同伴的通訊地址
ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.8:2379" # 對外提供服務的地址#ETCD_MAX_SNAPSHOTS="5" # etcd最大快照保存數#ETCD_MAX_WALS="5" # etcd 最大walsETCD_ # etcd節點名稱,集羣內需要唯一#ETCD_SNAPSHOT_COUNT="100000" # 指定有多少事務(transaction)被提交時,觸發截取快照保存到磁盤#ETCD_HEARTBEAT_INTERVAL="100" # leader 多久發送一次心跳到 followers。默認值是 100ms#ETCD_ELECTION_TIMEOUT="1000" # 重新投票的超時時間,如果 follow 在該時間間隔沒有收到心跳包,會觸發重新投票,默認爲 1000 ms#ETCD_QUOTA_BACKEND_BYTES="0"#ETCD_MAX_REQUEST_BYTES="1572864"#ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"#ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"#ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"##[Clustering]ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.0.8:2380" # 該節點同伴監聽地址,這個值會告訴集羣中其他節點
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.8:2379" # 對外公告的該節點客戶端監聽地址,這個值會告訴集羣中其他節點#ETCD_DISCOVERY=""#ETCD_DISCOVERY_FALLBACK="proxy"#ETCD_DISCOVERY_PROXY=""#ETCD_DISCOVERY_SRV=""ETCD_INITIAL_CLUSTER="etcd-0-8=http://172.16.0.8:2380,etcd-0-17=http://172.16.0.17:2380,etcd-0-14=http://172.16.0.14:2380" # 集羣中所有節點的信
ETCD_INITIAL_CLUSTER_TOKEN="etcd-token" # 創建集羣的 token,這個值每個集羣保持唯一。這樣的話,如果你要重新創建集羣,即使配置和之前一樣,也會再次生成新的集羣和節點 uuid;否則會導致多個集羣之間的衝突,造成未知的錯誤
ETCD_INITIAL_CLUSTER_STATE="new"#ETCD_STRICT_RECONFIG_CHECK="true" # 新建集羣的時候,這個值爲 new;假如已經存在的集羣,這個值爲 existing#ETCD_ENABLE_V2="true"##[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"#ETCD_LOG_PACKAGE_LEVELS=""#ETCD_LOG_OUTPUT="default"##[Unsafe]#ETCD_FORCE_NEW_CLUSTER="false"##[Version]#ETCD_VERSION="false"#ETCD_AUTO_COMPACTION_RETENTION="0"##[Profiling]#ETCD_ENABLE_PPROF="false"#ETCD_METRICS="basic"##[Auth]#ETCD_AUTH_TOKEN="simple"複製代碼
etcd-0-8配置:
[root@etcd-server ~]# hostnamectl set-hostname etcd-0-8[root@etcd-0-8 ~]# egrep "^#|^$" /etc/etcd/etcd.conf -vETCD_DATA_DIR="/data/app/etcd/"ETCD_LISTEN_PEER_URLS="http://172.16.0.8:2380"ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.8:2379"ETCD_複製代碼
etcd-0-14配置:
[root@etcd-server ~]# hostnamectl set-hostname etcd-0-14[root@etcd-server ~]# mkdir -p /data/app/etcd/[root@etcd-0.14 ~]# egrep "^#|^$" /etc/etcd/etcd.conf -vETCD_DATA_DIR="/data/app/etcd/"ETCD_LISTEN_PEER_URLS="http://172.16.0.14:2380"ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.14:2379"ETCD_複製代碼
etcd-0-7配置:
[root@etcd-server ~]# hostnamectl set-hostname etcd-0-17[root@etcd-server ~]# mkdir -p /data/app/etcd/[root@etcd-0-17 ~]# egrep "^#|^$" /etc/etcd/etcd.conf -vETCD_DATA_DIR="/data/app/etcd/"ETCD_LISTEN_PEER_URLS="http://172.16.0.17:2380"ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.17:2379"ETCD_複製代碼
- 配置完成後啓動服務
systemctl start etcd
4.2.5 查看集羣狀態
- 查看 etcd 狀態
[root@etcd-0-8 default.etcd]# systemctl status etcd● etcd.service - Etcd Server
Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled) Active: active (running) since 二 2019-12-03 15:55:28 CST; 8s ago
Main PID: 24510 (etcd) CGroup: /system.slice/etcd.service
└─24510 /usr/bin/etcd --name=etcd-0-8 --data-dir=/data/app/etcd/ --listen-client-urls=http://172.16.0.8:237912月 03 15:55:28 etcd-0-8 etcd[24510]: set the initial cluster version to 3.012月 03 15:55:28 etcd-0-8 etcd[24510]: enabled capabilities for version 3.012月 03 15:55:30 etcd-0-8 etcd[24510]: peer 56e0b6dad4c53d42 became active12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream Message reader)12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream Message writer)12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream MsgApp v2 reader)12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream MsgApp v2 writer)12月 03 15:55:32 etcd-0-8 etcd[24510]: updating the cluster version from 3.0 to 3.312月 03 15:55:32 etcd-0-8 etcd[24510]: updated the cluster version from 3.0 to 3.312月 03 15:55:32 etcd-0-8 etcd[24510]: enabled capabilities for version 3.3複製代碼
- 查看端口監聽(如果未在本地監聽環回地址,那麼在本地使用etcdctl不能正常連入進去)
[root@etcd-0-8 default.etcd]# netstat -lntup |grep etcdtcp 0 0 172.16.0.8:2379 0.0.0.0:* LISTEN 25167/etcd
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 25167/etcd
tcp 0 0 172.16.0.8:2380 0.0.0.0:* LISTEN 25167/etcd複製代碼
- 查看集羣狀態(可以看到etcd-0-17)
[root@etcd-0-8 default.etcd]# etcdctl member list2d2e457c6a1a76cb: name=etcd-0-8 peerURLs=http://172.16.0.8:2380 clientURLs=http://127.0.0.1:2379,http://172.16.0.8:2379 isLeader=false56e0b6dad4c53d42: name=etcd-0-14 peerURLs=http://172.16.0.14:2380 clientURLs=http://127.0.0.1:2379,http://172.16.0.14:2379 isLeader=trued2d2e9fc758e6790: name=etcd-0-17 peerURLs=http://172.16.0.17:2380 clientURLs=http://127.0.0.1:2379,http://172.16.0.17:2379 isLeader=false[root@etcd-0-8 ~]# etcdctl cluster-healthmember 2d2e457c6a1a76cb is healthy: got healthy result from http://127.0.0.1:2379member 56e0b6dad4c53d42 is healthy: got healthy result from http://127.0.0.1:2379member d2d2e9fc758e6790 is healthy: got healthy result from http://127.0.0.1:2379cluster is healthy複製代碼
五 簡單使用
5.1 增加
- set
指定某個鍵的值。例如:
$ etcdctl set /testdir/testkey "Hello world"Hello world
支持的選項包括:
--ttl '0' 該鍵值的超時時間(單位爲秒),不配置(默認爲0)則永不超時--swap-with-value value 若該鍵現在的值是value,則進行設置操作--swap-with-index '0' 若該鍵現在的索引值是指定索引,則進行設置操作複製代碼
- mk
如果給定的鍵不存在,則創建一個新的鍵值。例如:
$ etcdctl mk /testdir/testkey "Hello world"Hello world
當鍵存在的時候,執行該命令會報錯,例如:
$ etcdctl mk /testdir/testkey "Hello world"Error: 105: Key already exists (/testdir/testkey) [8]複製代碼
支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲 0)。則永不超時複製代碼
- mkdir
如果給定的鍵目錄不存在,則創建一個新的鍵目錄。例如:
$ etcdctl mkdir testdir2
當鍵目錄存在的時候,執行該命令會報錯,例如:
$ etcdctl mkdir testdir2
Error: 105: Key already exists (/testdir2) [9]
支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。複製代碼
- setdir
創建一個鍵目錄。如果目錄不存在就創建,如果目錄存在更新目錄 TTL。
$ etcdctl setdir testdir3
支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。
5.2 刪除
- rm
刪除某個鍵值。例如:
$ etcdctl rm /testdir/testkeyPrevNode.Value: Hello
當鍵不存在時,則會報錯。例如:
$ etcdctl rm /testdir/testkey
Error: 100: Key not found (/testdir/testkey) [7]
支持的選項爲:
--dir 如果鍵是個空目錄或者鍵值對則刪除--recursive 刪除目錄和所有子鍵--with-value 檢查現有的值是否匹配--with-index '0'檢查現有的index是否匹配
- rmdir
刪除一個空目錄,或者鍵值對。
$ etcdctl setdir dir1$ etcdctl rmdir dir1
若目錄不空,會報錯:
$ etcdctl set /dir/testkey hihi$ etcdctl rmdir /dirError: 108: Directory not empty (/dir) [17]
# **5.3 更新**
- update
當鍵存在時,更新值內容。例如:
$ etcdctl update /testdir/testkey "Hello"Hello
當鍵不存在時,則會報錯。例如:
$ etcdctl update /testdir/testkey2 "Hello"Error: 100: Key not found (/testdir/testkey2) [6]
支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲 0)則永不超時。
- updatedir
更新一個已經存在的目錄。
$ etcdctl updatedir testdir2
支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。
5.4 查詢
- get
獲取指定鍵的值。例如:
$ etcdctl get /testdir/testkeyHello world
當鍵不存在時,則會報錯。例如:
$ etcdctl get /testdir/testkey2Error: 100: Key not found (/testdir/testkey2) [5]複製代碼
支持的選項爲:
--sort 對結果進行排序--consistent 將請求發給主節點,保證獲取內容的一致性。複製代碼
- ls
列出目錄 (默認爲根目錄) 下的鍵或者子目錄,默認不顯示子目錄中內容。
例如:
$ etcdctl ls/testdir
/testdir2
/dir
$ etcdctl ls dir/dir/testkey
支持的選項包括:
--sort 將輸出結果排序--recursive 如果目錄下有子目錄,則遞歸輸出其中的內容
-p 對於輸出爲目錄,在最後添加/進行區分
5.5 watch
- watch
監測一個鍵值的變化,一旦鍵值發生更新,就會輸出最新的值並退出。
例如: 用戶更新 testkey 鍵值爲 Hello watch。
$ etcdctl get /testdir/testkeyHello world$ etcdctl set /testdir/testkey "Hello watch"Hello watch$ etcdctl watch testdir/testkeyHello watch
支持的選項包括:
--forever 一直監測直到用戶按CTRL+C退出--after-index '0' 在指定index之前一直監測--recursive 返回所有的鍵值和子鍵值
- exec-watch
監測一個鍵值的變化,一旦鍵值發生更新,就執行給定命令。
例如:用戶更新 testkey 鍵值。
$ etcdctl exec-watch testdir/testkey -- sh -c 'ls'config Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md複製代碼
支持的選項包括:
--after-index '0' 在指定 index 之前一直監測
--recursive 返回所有的鍵值和子鍵值
5.6 備份
備份 etcd 的數據。
$ etcdctl backup --data-dir /var/lib/etcd --backup-dir /home/etcd_backup複製代碼
支持的選項包括:
--data-dir etcd的數據目錄
--backup-dir 備份到指定路徑複製代碼
5.7 member
通過list
、add
、remove
命令列出、添加、刪除 etcd 實例到 etcd 集羣中。
查看集羣中存在的節點
$ etcdctl member list
8e9e05c52164694d: name=dev-master-01 peerURLs=http://localhost:2380 clientURLs=http://localhost:2379 isLeader=true
刪除集羣中存在的節點
$ etcdctl member remove 8e9e05c52164694d
Removed member 8e9e05c52164694d from cluste
向集羣中新加節點
$ etcdctl member add etcd3 http://192.168.1.100:2380Added member named etcd3 with ID 8e9e05c52164694d to cluster
示例
# 設置一個key值[root@etcd-0-8 ~]# etcdctl set /msg "hello k8s"hello k8s# 獲取key的值[root@etcd-0-8 ~]# etcdctl get /msghello k8s# 獲取key值的詳細信息[root@etcd-0-8 ~]# etcdctl -o extended get /msgKey: /msg
Created-Index: 12
Modified-Index: 12
TTL: 0
Index: 12
hello k8s# 獲取不存在的key回報錯[root@etcd-0-8 ~]# etcdctl get /xxzxError: 100: Key not found (/xxzx) [12]# 設置key的ttl,過期後會被自動刪除[root@etcd-0-8 ~]# etcdctl set /testkey "tmp key test" --ttl 5tmp key test[root@etcd-0-8 ~]# etcdctl get /testkeyError: 100: Key not found (/testkey) [14]# key 替換操作[root@etcd-0-8 ~]# etcdctl get /msghello k8s[root@etcd-0-8 ~]# etcdctl set --swap-with-value "hello k8s" /msg "goodbye"goodbye[root@etcd-0-8 ~]# etcdctl get /msggoodbye# mk 僅當key不存在時創建(set對同一個key會覆蓋)[root@etcd-0-8 ~]# etcdctl get /msggoodbye[root@etcd-0-8 ~]# etcdctl mk /msg "mktest"Error: 105: Key already exists (/msg) [18][root@etcd-0-8 ~]# etcdctl mk /msg1 "mktest"mktest# 創建自排序的key[root@etcd-0-8 ~]# etcdctl mk --in-order /queue s1s1[root@etcd-0-8 ~]# etcdctl mk --in-order /queue s2s2[root@etcd-0-8 ~]# etcdctl ls --sort /queue/queue/00000000000000000021
/queue/00000000000000000022[root@etcd-0-8 ~]# etcdctl get /queue/00000000000000000021s1# 更新key值[root@etcd-0-8 ~]# etcdctl update /msg1 "update test"update test[root@etcd-0-8 ~]# etcdctl get /msg1update test# 更新key的ttl及值[root@etcd-0-8 ~]# etcdctl update --ttl 5 /msg "aaa"aaa# 創建目錄[root@etcd-0-8 ~]# etcdctl mkdir /testdir# 刪除空目錄[root@etcd-0-8 ~]# etcdctl mkdir /test1[root@etcd-0-8 ~]# etcdctl rmdir /test1# 刪除非空目錄[root@etcd-0-8 ~]# etcdctl get /testdir/testdir: is a directory[root@etcd-0-8 ~]#[root@etcd-0-8 ~]# etcdctl rm --recursive /testdir# 列出目錄內容[root@etcd-0-8 ~]# etcdctl ls //tmp
/msg1
/queue[root@etcd-0-8 ~]# etcdctl ls /tmp/tmp/a
/tmp/b# 遞歸列出目錄的內容[root@etcd-0-8 ~]# etcdctl ls --recursive //msg1
/queue
/queue/00000000000000000021
/queue/00000000000000000022
/tmp
/tmp/b
/tmp/a# 監聽key,當key發生改變的時候打印出變化[root@etcd-0-8 ~]# etcdctl watch /msg1xxx[root@VM_0_17_centos ~]# etcdctl update /msg1 "xxx"xxx# 監聽某個目錄,當目錄中任何 node 改變的時候,都會打印出來[root@etcd-0-8 ~]# etcdctl watch --recursive /[update] /msg1
xxx[root@VM_0_17_centos ~]# etcdctl update /msg1 "xxx"xxx# 一直監聽,除非 `CTL + C` 導致退出監聽[root@etcd-0-8 ~]# etcdctl watch --forever /# 監聽目錄,當發生變化時執行一條命令[root@etcd-0-8 ~]# etcdctl exec-watch --recursive / -- sh -c "echo change"change# backup[root@etcd-0-14 ~]# etcdctl backup --data-dir /data/app/etcd --backup-dir /root/etcd_backup2019-12-04 10:25:16.113237 I | ignoring EntryConfChange raft entry
2019-12-04 10:25:16.113268 I | ignoring EntryConfChange raft entry
2019-12-04 10:25:16.113272 I | ignoring EntryConfChange raft entry
2019-12-04 10:25:16.113293 I | ignoring member attribute update on /0/members/2d2e457c6a1a76cb/attributes
2019-12-04 10:25:16.113299 I | ignoring member attribute update on /0/members/d2d2e9fc758e6790/attributes
2019-12-04 10:25:16.113305 I | ignoring member attribute update on /0/members/56e0b6dad4c53d42/attributes
2019-12-04 10:25:16.113310 I | ignoring member attribute update on /0/members/56e0b6dad4c53d42/attributes
2019-12-04 10:25:16.113314 I | ignoring member attribute update on /0/members/2d2e457c6a1a76cb/attributes
2019-12-04 10:25:16.113319 I | ignoring member attribute update on /0/members/d2d2e9fc758e6790/attributes
2019-12-04 10:25:16.113384 I | ignoring member attribute update on /0/members/56e0b6dad4c53d42/attributes# 使用v3版本
# 使用v3版本
[root@etcd-0-14 ~]# export ETCDCTL_API=3
[root@etcd-0-14 ~]# etcdctl --endpoints="http://172.16.0.8:2379,http://172.16.0.14:2379,http://172.16.0.17:2379" snapshot save mysnapshot.db
Snapshot saved at mysnapshot.db
[root@etcd-0-14 ~]# etcdctl snapshot status mysnapshot.db -w json
{"hash":928285884,"revision":0,"totalKey":5,"totalSize":20480}
六 總結
-
etcd 默認只保存 1000 個歷史事件,所以不適合有大量更新操作的場景,這樣會導致數據的丟失。etcd 典型的應用場景是配置管理和服務發現,這些場景都是讀多寫少的。
-
相比於 zookeeper,etcd 使用起來要簡單很多。不過要實現真正的服務發現功能,etcd 還需要和其他工具(比如 registrator、confd 等)一起使用來實現服務的自動註冊和更新。
-
目前 etcd 還沒有圖形化的工具。
參考鏈接
-
https://github.com/etcd-io/etcd
-
https://www.hi-linux.com/posts/40915.html
-
www.hi-linux.com/posts/40915…
-
https://cizixs.com/2016/08/02/intro-to-etcd/
-
Etcd Raft 使用入門及原理解析
-
https://juejin.cn/post/6844903970461351944
-
https://www.infoq.cn/article/coreos-analyse-etcd/
作者:kaliarch
來源:juejin.cn/post/6844904031186321416
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/d_usTF2hxEilXIv9fIgURg