一文入門ETCD

一 概述

背景:近期k8s應用中etcd的功能存在一些困惑,對其進行來單獨的學習,能更深刻理解k8s中的的一些特性。html

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

  • Node:一個Raft狀態機實例。linux

  • Member: 一個etcd實例。它管理着一個Node,而且能夠爲客戶端請求提供服務。git

  • Cluster:由多個Member構成能夠協同工做的etcd集羣。github

  • Peer:對同一個etcd集羣中另一個Member的稱呼。算法

  • Client: 向etcd集羣發送HTTP請求的客戶端。shell

  • WAL:預寫式日誌,etcd用於持久化存儲的日誌格式。數據庫

  • snapshot:etcd防止WAL文件過多而設置的快照,存儲etcd數據狀態。json

  • 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能夠用於服務的註冊與發現

  • 先後端業務註冊發現

img

中間價已經後端服務在etcd中註冊,前端和中間價能夠很輕鬆的從etcd中發現相關服務器而後服務器之間根據調用關係相關綁定調用

  • 多組後端服務器註冊發現

image-20191128115854263

後端多個無狀態相同副本的app能夠同事註冊到etcd中,前端能夠經過haproxy從etcd中獲取到後端的ip和端口組,而後進行請求轉發,能夠用來故障轉移屏蔽後端端口已經後端多組app實例。

3.2 消息發佈與訂閱

image-20191128120310649

etcd能夠充當消息中間件,生產者能夠往etcd中註冊topic併發送消息,消費者從etcd中訂閱topic,來獲取生產者發送至etcd中的消息。

3.3 負載均衡

image-20191128120453559

後端多組相同的服務提供者能夠經本身服務註冊到etcd中,etcd而且會與註冊的服務進行監控檢查,服務請求這首先從etcd中獲取到可用的服務提供者真正的ip:port,而後對此多組服務發送請求,etcd在其中充當了負載均衡的功能

3.4 分部署通知與協調

image-20191128174054754

  • 當etcd watch服務發現丟失,會通知服務檢查
  • 控制器向etcd發送啓動服務,etcd通知服務進行相應操做
  • 當服務完成work會講狀態更新至etcd,etcd對應會通知用戶

3.5 分佈式鎖

image-20191128183307205

當有多個競爭者node節點,etcd做爲總控,在分佈式集羣中與一個節點成功分配lock

3.6 分佈式隊列

image-20191203135537016

有對個node,etcd根據每一個node來建立對應node的隊列,根據不一樣的隊列能夠在etcd中找到對應的competitor

3.7 集羣與監控與Leader選舉

image-20191203135838727

etcd能夠根據raft算法在多個node節點來選舉出leader

四 安裝部署

4.1 單機部署

可使用二進制或源碼下載安裝,可是危害須要本身寫配置文件,如何要啓動須要本身寫服務啓動文件,推薦使用yum安裝方式

hostnamectl set-hostname etcd-1
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
# yum 倉庫中的etcd版本爲3.3.11,若是須要最新版本的etcd能夠進行二進制安裝
yum -y install etcd
systemctl enable etcd
複製代碼

能夠查看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.conf
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
ETCD_NAME="default"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
[root@VM_0_8_centos tmp]# systemctl status etcd
複製代碼

4.2 集羣部署

集羣部署最好部署奇數位,此能達到最好的集羣容錯

4.2.1 主機信息

image-20191203144634596

主機名稱 系統 IP地址 部署組件
etcd-0-8 CentOS 7.3 172.16.0.8 etcd
etcd-0-17 CentOS 7.3 172.16.0.17 etcd
etcd-0-14 CentOS 7.3 172.16.0.14 etcd

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 etcd
mkdir -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 最大wals
ETCD_NAME="etcd-0-8"																											# 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 -v
ETCD_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_NAME="etcd-0-8"
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_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"
ETCD_INITIAL_CLUSTER_STATE="new"
複製代碼

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 -v
ETCD_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_NAME="etcd-0-14"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.0.14:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.14:2379"
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"
ETCD_INITIAL_CLUSTER_STATE="new"
複製代碼
  • 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 -v
ETCD_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_NAME="etcd-0-17"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.0.17:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.17:2379"
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"
ETCD_INITIAL_CLUSTER_STATE="new"
複製代碼
  • 配置完成後啓動服務
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:2379

12月 03 15:55:28 etcd-0-8 etcd[24510]: set the initial cluster version to 3.0
12月 03 15:55:28 etcd-0-8 etcd[24510]: enabled capabilities for version 3.0
12月 03 15:55:30 etcd-0-8 etcd[24510]: peer 56e0b6dad4c53d42 became active
12月 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.3
12月 03 15:55:32 etcd-0-8 etcd[24510]: updated the cluster version from 3.0 to 3.3
12月 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 etcd
tcp        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 list
2d2e457c6a1a76cb: 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=false
56e0b6dad4c53d42: 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=true
d2d2e9fc758e6790: 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-health
member 2d2e457c6a1a76cb is healthy: got healthy result from http://127.0.0.1:2379
member 56e0b6dad4c53d42 is healthy: got healthy result from http://127.0.0.1:2379
member d2d2e9fc758e6790 is healthy: got healthy result from http://127.0.0.1:2379
cluster 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/testkey
PrevNode.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 hi
hi
$ etcdctl rmdir /dir
Error:  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/testkey
Hello world
複製代碼

當鍵不存在時,則會報錯。例如:

$ etcdctl get /testdir/testkey2
Error:  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/testkey
Hello world
$ etcdctl set /testdir/testkey "Hello watch"
Hello watch
$ etcdctl watch testdir/testkey
Hello 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

經過listaddremove命令列出、添加、刪除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 cluster
複製代碼

向集羣中新加節點

$ etcdctl member add etcd3 http://192.168.1.100:2380
Added 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 /msg
hello k8s
 # 獲取key值的詳細信息
[root@etcd-0-8 ~]# etcdctl -o extended get /msg
Key: /msg
Created-Index: 12
Modified-Index: 12
TTL: 0
Index: 12

hello k8s
 # 獲取不存在的key回報錯
[root@etcd-0-8 ~]# etcdctl get /xxzx
Error:  100: Key not found (/xxzx) [12]
 # 設置key的ttl,過時後會被自動刪除
[root@etcd-0-8 ~]# etcdctl set /testkey "tmp key test" --ttl 5
tmp key test
[root@etcd-0-8 ~]# etcdctl get /testkey
Error:  100: Key not found (/testkey) [14]
 # key 替換操做
[root@etcd-0-8 ~]# etcdctl get /msg
hello k8s
[root@etcd-0-8 ~]# etcdctl set --swap-with-value "hello k8s" /msg "goodbye"
goodbye
[root@etcd-0-8 ~]# etcdctl get /msg
goodbye
 # mk 僅當key不存在時建立(set對同一個key會覆蓋)
[root@etcd-0-8 ~]# etcdctl get /msg
goodbye
[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 s1
s1
[root@etcd-0-8 ~]# etcdctl mk --in-order /queue s2
s2
[root@etcd-0-8 ~]# etcdctl ls --sort /queue
/queue/00000000000000000021
/queue/00000000000000000022
[root@etcd-0-8 ~]# etcdctl get /queue/00000000000000000021
s1
 # 更新key值
[root@etcd-0-8 ~]# etcdctl update /msg1 "update test"
update test
[root@etcd-0-8 ~]# etcdctl get /msg1
update 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 /msg1
xxx

[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_backup
2019-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版本
[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 尚未圖形化的工具。

參考連接

相關文章
相關標籤/搜索