etcd是一個高可用的分佈式鍵值(key-value)數據庫。etcd內部採用raft協議做爲一致性算法,etcd基於Go語言實現。html
提供配置共享和服務發現的系統比較多,其中最爲你們熟知的是[Zookeeper](後文簡稱ZK),而ETCD能夠算得上是後起之秀了。在項目實現,一致性協議易理解性,運維,安全等多個維度上,ETCD相比Zookeeper都佔據優點。
etcd是一個服務發現系統,具有如下的特色: node
本文選取ZK做爲典型表明與ETCD進行比較,而不考慮[Consul]項目做爲比較對象,緣由爲Consul的可靠性和穩定性還須要時間來驗證(項目發起方自身服務並未使用Consul, 本身都不用)。python
和ZK相似,ETCD有不少使用場景,包括:linux
按照官網給出的[Benchmark], 在2CPU,1.8G內存,SSD磁盤這樣的配置下,單節點的寫性能能夠達到16K QPS, 而先寫後讀也能達到12K QPS。這個性能仍是至關可觀的。git
ETCD使用Raft協議來維護集羣內各個節點狀態的一致性。簡單說,ETCD集羣是一個分佈式系統,由多個節點相互通訊構成總體對外服務,每一個節點都存儲了完整的數據,而且經過Raft協議保證每一個節點維護的數據是一致的。github
如圖所示,每一個ETCD節點都維護了一個狀態機,而且,任意時刻至多存在一個有效的主節點。主節點處理全部來自客戶端寫操做,經過Raft協議保證寫操做對狀態機的改動會可靠的同步到其餘節點。算法
ETCD工做原理核心部分在於Raft協議。本節接下來將簡要介紹Raft協議,具體細節請參考其[論文]。
Raft協議正如論文所述,確實方便理解。主要分爲三個部分:選主,日誌複製,安全性。shell
Raft協議是用於維護一組服務節點數據一致性的協議。這一組服務節點構成一個集羣,而且有一個主節點來對外提供服務。當集羣初始化,或者主節點掛掉後,面臨一個選主問題。集羣中每一個節點,任意時刻處於Leader, Follower, Candidate這三個角色之一。選舉特色以下:數據庫
Candidate節點收到來自主節點的信息後,會當即終止選舉過程,進入Follower角色。json
爲了不陷入選主失敗循環,每一個節點未收到心跳發起選舉的時間是必定範圍內的隨機值,這樣可以避免2個節點同時發起選主。
所謂日誌複製,是指主節點將每次操做造成日誌條目,並持久化到本地磁盤,而後經過網絡IO發送給其餘節點。其餘節點根據日誌的邏輯時鐘(TERM)和日誌編號(INDEX)來判斷是否將該日誌記錄持久化到本地。當主節點收到包括本身在內超過半數節點成功返回,那麼認爲該日誌是可提交的(committed),並將日誌輸入到狀態機,將結果返回給客戶端。
這裏須要注意的是,每次選主都會造成一個惟一的TERM編號,至關於邏輯時鐘。每一條日誌都有全局惟一的編號。
主節點經過網絡IO向其餘節點追加日誌。若某節點收到日誌追加的消息,首先判斷該日誌的TERM是否過時,以及該日誌條目的INDEX是否比當前以及提交的日誌的INDEX跟早。若已過時,或者比提交的日誌更早,那麼就拒絕追加,並返回該節點當前的已提交的日誌的編號。不然,將日誌追加,並返回成功。
當主節點收到其餘節點關於日誌追加的回覆後,若發現有拒絕,則根據該節點返回的已提交日誌編號,發生其編號下一條日誌。
主節點像其餘節點同步日誌,還做了擁塞控制。具體地說,主節點發現日誌複製的目標節點拒絕了某第二天志追加消息,將進入日誌探測階段,一條一條發送日誌,直到目標節點接受日誌,而後進入快速複製階段,可進行批量日誌追加。
按照日誌複製的邏輯,咱們能夠看到,集羣中慢節點不影響整個集羣的性能。另一個特色是,數據只從主節點複製到Follower節點,這樣大大簡化了邏輯流程。
截止此刻,選主以及日誌複製並不能保證節點間數據一致。試想,當一個某個節點掛掉了,一段時間後再次重啓,並當選爲主節點。而在其掛掉這段時間內,集羣如有超過半數節點存活,集羣會正常工做,那麼會有日誌提交。這些提交的日誌沒法傳遞給掛掉的節點。當掛掉的節點再次當選主節點,它將缺失部分已提交的日誌。在這樣場景下,按Raft協議,它將本身日誌複製給其餘節點,會將集羣已經提交的日誌給覆蓋掉。
這顯然是不可接受的。
其餘協議解決這個問題的辦法是,新當選的主節點會詢問其餘節點,和本身數據對比,肯定出集羣已提交數據,而後將缺失的數據同步過來。這個方案有明顯缺陷,增長了集羣恢復服務的時間(集羣在選舉階段不可服務),而且增長了協議的複雜度。
Raft解決的辦法是,在選主邏輯中,對可以成爲主的節點加以限制,確保選出的節點已定包含了集羣已經提交的全部日誌。若是新選出的主節點已經包含了集羣全部提交的日誌,那就不須要從和其餘節點比對數據了。簡化了流程,縮短了集羣恢復服務的時間。
這裏存在一個問題,加以這樣限制以後,還可否選出主呢?答案是:只要仍然有超過半數節點存活,這樣的主必定可以選出。由於已經提交的日誌必然被集羣中超過半數節點持久化,顯然前一個主節點提交的最後一條日誌也被集羣中大部分節點持久化。當主節點掛掉後,集羣中仍有大部分節點存活,那這存活的節點中必定存在一個節點包含了已經提交的日誌了。
至此,關於Raft協議的簡介就所有結束了。
據公開資料顯示,至少有CoreOS, Google Kubernetes, Cloud Foundry, 以及在Github上超過500個項目在使用ETCD。
ETCD提供HTTP協議,在最新版本中支持Google gRPC方式訪問。具體支持接口狀況以下:
etcd在生產環境中通常推薦集羣方式部署。在這裏,主要講講單節點安裝和基本使用。
由於etcd是go語言編寫的,安裝只須要下載對應的二進制文件,並放到合適的路徑就行。
訪問下載連接:
https://github.com/etcd-io/etcd/releases
目前最新版本是3.3.10,因此完整的下載連接以下:
https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz
本文所使用的系統爲: ubuntu-16.04.5-server-amd64
wget https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz tar zxvf etcd-v3.3.10-linux-amd64.tar.gz mv etcd-v3.3.10-linux-amd64 /opt/etcd-v3.3.10
解壓後的文件以下所示:
root@ubuntu:/opt/etcd-v3.3.10# ls default.etcd Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md
其中etcd是server端,etcdctl是客戶端,操做以後會生成一個default.etcd,主要用來存儲etct數據。
啓動一個單節點的etcd服務,只須要運行etcd命令就行。不過有可能會出現如下問題:
root@ubuntu:/opt/etcd-v3.3.10# ./etcd bash: ./etcd: 權限不夠
這個時候須要提升文件的權限,採用以下方法:
root@ubuntu:/opt/etcd-v3.3.10# chmod 755 etcd
再次啓動etcd
root@ubuntu:/opt/etcd-v3.3.10# ./etcd
成功後能夠看見如下提示:
2018-11-11 15:46:43.134431 I | etcdmain: etcd Version: 3.3.10 2018-11-11 15:46:43.134941 I | etcdmain: Git SHA: 27fc7e2 2018-11-11 15:46:43.135324 I | etcdmain: Go Version: go1.10.4 2018-11-11 15:46:43.135572 I | etcdmain: Go OS/Arch: linux/amd64 2018-11-11 15:46:43.135781 I | etcdmain: setting maximum number of CPUs to 1, total number of available CPUs is1 2018-11-11 15:46:43.136055 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd 2018-11-11 15:46:43.136331 N | etcdmain: the server is already initialized as member before, starting as etcd member... 2018-11-11 15:46:43.136847 I | embed: listening for peers on http://localhost:2380 2018-11-11 15:46:43.137159 I | embed: listening for client requests on localhost:2379 2018-11-11 15:46:43.138055 I | etcdserver: name = default 2018-11-11 15:46:43.138328 I | etcdserver: data dir = default.etcd 2018-11-11 15:46:43.138718 I | etcdserver: member dir = default.etcd/member 2018-11-11 15:46:43.139011 I | etcdserver: heartbeat = 100ms 2018-11-11 15:46:43.139280 I | etcdserver: election = 1000ms 2018-11-11 15:46:43.139545 I | etcdserver: snapshot count = 100000 2018-11-11 15:46:43.139839 I | etcdserver: advertise client URLs = http://localhost:2379 2018-11-11 15:46:43.141035 I | etcdserver: restarting member 8e9e05c52164694d in cluster cdf818194e3a8c32 at commit index 46 2018-11-11 15:46:43.141923 I | raft: 8e9e05c52164694d became follower at term 2 2018-11-11 15:46:43.142228 I | raft: newRaft 8e9e05c52164694d [peers: [], term: 2, commit: 46, applied: 0, lastindex: 46, lastterm: 2] 2018-11-11 15:46:43.143985 W | auth: simple token is not cryptographically signed 2018-11-11 15:46:43.145713 I | etcdserver: starting server... [version: 3.3.10, cluster version: to_be_decided] 2018-11-11 15:46:43.148015 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32 2018-11-11 15:46:43.149041 N | etcdserver/membership: set the initial cluster version to 3.3 2018-11-11 15:46:43.149478 I | etcdserver/api: enabled capabilities for version 3.3 2018-11-11 15:46:45.043137 I | raft: 8e9e05c52164694d is starting a new election at term 2 2018-11-11 15:46:45.043461 I | raft: 8e9e05c52164694d became candidate at term 3 2018-11-11 15:46:45.043495 I | raft: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 3 2018-11-11 15:46:45.043519 I | raft: 8e9e05c52164694d became leader at term 3 2018-11-11 15:46:45.043535 I | raft: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 3 2018-11-11 15:46:45.044348 I | etcdserver: published {Name:default ClientURLs:[http://localhost:2379]} to cluster cdf818194e3a8c32 2018-11-11 15:46:45.044593 E | etcdmain: forgot to set Type=notify in systemd service file? 2018-11-11 15:46:45.044737 I | embed: ready to serve client requests 2018-11-11 15:46:45.045232 N | embed: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
從上面的輸出中,咱們能夠看到不少信息。如下是幾個比較重要的信息:
2018-11-11 15:46:43.138055 I | etcdserver: name = default
name表示節點名稱,默認爲default。
2018-11-11 15:46:43.138328 I | etcdserver: data dir = default.etcd
data-dir 保存日誌和快照的目錄,默認爲當前工做目錄default.etcd/目錄下。
2018-11-11 15:46:43.148015 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32
在http://localhost:2380和集羣中其餘節點通訊。
2018-11-11 15:46:43.139839 I | etcdserver: advertise client URLs = http://localhost:2379
在http://localhost:2379提供HTTP API服務,供客戶端交互。
2018-11-11 15:46:43.139011 I | etcdserver: heartbeat = 100ms
heartbeat爲100ms,該參數的做用是leader多久發送一次心跳到followers,默認值是100ms。
2018-11-11 15:46:43.139280 I | etcdserver: election = 1000ms
election爲1000ms,該參數的做用是從新投票的超時時間,若是follow在該時間間隔沒有收到心跳包,會觸發從新投票,默認爲1000ms。
2018-11-11 15:46:43.139545 I | etcdserver: snapshot count = 100000
snapshot count爲10000,該參數的做用是指定有多少事務被提交時,觸發截取快照保存到磁盤。
集羣和每一個節點都會生成一個uuid。
啓動的時候會運行raft,選舉出leader。
採用這種方式啓動的etcd只是一個程序,若是啓動etcd的窗口被關閉的話則etcd便會被關閉
,因此若是要長期使用的話最好是爲etcd開啓一個服務,此處便不提供開啓服務的方法,若是有須要讀者能夠自行百度。
打開另外一個窗口輸入:
root@ubuntu:/opt/etcd-v3.3.10# ./etcd -version etcd Version: 3.3.10 Git SHA: 27fc7e2 Go Version: go1.10.4 Go OS/Arch: linux/amd64
etcd廠商爲咱們提供提供了一個命令行客戶端—etcdctl,供用戶直接跟etcd服務打交道,而無需基於 HTTP API方式。能夠方便咱們在對服務進行測試或者手動修改數據庫內容。
etcdctl支持的命令大致上分爲數據庫操做和非數據庫操做兩類。
可使用 ./etcdctl -h 查看etcdctl的用法:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl -h
注意:etcd的數據庫操做圍繞對鍵值和目錄的CRUD完整生命週期的管理。
etcd在鍵的組織上採用了層次化的空間結構(相似於文件系統中目錄的概念),用戶指定的鍵能夠爲單獨的名字,如:testkey,此時實際上放在根目錄/下面,也能夠爲指定目錄結構,如/cluster1/node2/testkey,則將建立相應的目錄結構。
指定某個鍵的值
語法:
-ttl '0' 該鍵值的超時時間(單位爲秒),不配置(默認爲0)則永不超時 –swap-with-value value 若該鍵如今的值是value,則進行設置操做 –swap-with-index '0' 若該鍵如今的索引值是指定索引,則進行設置操做
例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl set --ttl '5' key "Hello world" Hello world root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl get key Hello world # 等待幾秒,再執行 root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl get key Error: 100: Key not found (/key) [8]
第一個get是5秒內的操做,第二get是5秒後的操做,此刻key的值已經消失了。
對指定鍵進行修改
語法:
–ttl '0' 超時時間(單位爲秒),不配置(默認爲 0)則永不超時。
舉例:
# 先設置一個5秒的值 root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl set --ttl '5' key "Hello world" Hello world # 再修改值 root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl update key "Hello world2" Hello world2 # 等待10秒,再次執行 root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl get key Hello world2
能夠發現,即便10秒,也能夠get到。說明ttl和value同時更新了!
刪除某個鍵值。
語法:
–dir 若是鍵是個空目錄或者鍵值對則刪除 –recursive 刪除目錄和全部子鍵 –with-value 檢查現有的值是否匹配 –with-index ‘0’檢查現有的index是否匹配
舉例:
# 刪除 root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl rm key PrevNode.Value: Hello world2 # 再次獲取 root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl rm key Error: 100: Key not found (/key) [11]
若是給定的鍵不存在,則建立一個新的鍵值。
語法:
–ttl '0' 超時時間(單位爲秒),不配置(默認爲 0)。則永不超時
舉例:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl mk /test/key "Hello world" Hello world
當鍵存在的時候,執行該命令會報錯,例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl mk /test/key "Hello world" Error: 105: Key already exists (/test/key) [33]
若是給定的鍵目錄不存在,則建立一個新的鍵目錄。
語法:
–ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。
舉例:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl mkdir dir2
當鍵目錄存在的時候,執行該命令會報錯,例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl mkdir dir2 Error: 105: Key already exists (/dir2) [13]
建立一個鍵目錄。若是目錄不存在就建立,若是目錄存在更新目錄TTL。
語法:
–ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。
舉例:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl setdir dir3
若是重複執行,會報錯
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl setdir dir3 Error: 102: Not a file (/dir3) [34]
更新一個已經存在的目錄。
語法:
–ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。
舉例:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl updatedir dir2
若是重複執行,不會報錯!
刪除一個空目錄,或者鍵值對
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl rmdir dir2
若是重複執行,會報錯
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl rmdir dir2 Error: 100: Key not found (/dir2) [36]
若目錄不空會報錯,例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl set /dir/key hi hi root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl rmdir /dir Error: 108: Directory not empty (/dir) [37]
列出目錄(默認爲根目錄)下的鍵或者子目錄,默認不顯示子目錄中內容。
語法:
–sort 將輸出結果排序 –recursive 若是目錄下有子目錄,則遞歸輸出其中的內容 -p 對於輸出爲目錄,在最後添加/進行區分
例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl ls /test /dir2 /dir3
若是有值,則輸出,不然不輸出!
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl ls test /test/key
非數據庫操做包括:備份、監測、節點管理等
備份etcd的數據。
語法:
–data-dir etcd的數據目錄 –backup-dir 備份到指定路徑
例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl backup --data-dir default.etcd --backup-dir /xx/xx 2018-11-11 16:43:34.119969 I | failed creating backup snapshot dir /xx/xx/member/snap: expected "/xx/xx/member/snap" to be empty, got ["db"]
提示 /xx/xx 目錄不存在!
那換一個存在的目錄,好比/opt/backup。注意:bakcup這個目錄能夠不用建立,它會自動建立!
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl backup --data-dir default.etcd --backup-dir /opt/backup 2018-11-11 16:44:44.845409 I | ignoring EntryConfChange raft entry 2018-11-11 16:44:44.845901 I | ignoring member attribute update on /0/members/8e9e05c52164694d/attributes 2018-11-11 16:44:44.846307 I | ignoring member attribute update on /0/members/8e9e05c52164694d/attributes
查看備份目錄/opt/backup/
root@ubuntu:/opt/etcd-v3.3.10# ll /opt/backup/ total 12 drwx------ 3 root root 4096 Nov 11 16:44 ./ drwxr-xr-x 4 root root 4096 Nov 11 16:44 ../ drwx------ 4 root root 4096 Nov 11 16:44 member/
監測一個鍵值的變化,一旦鍵值發生更新,就會輸出最新的值並退出。
監測一個鍵值的變化,一旦鍵值發生更新,就執行給定命令。
關於 watch 和 exec-watch,請參考連接:
http://www.javashuo.com/article/p-mklsetss-kn.html
我沒有作出來,主要是由於,開起新的窗口以後,get key沒法獲取到值
設置一個新的值
./etcdctl set key "Hello world"
執行報錯:
Error: unknown command "set" for "etcdctl" Did you mean this? get put del user Run 'etcdctl --help' for usage. Error: unknown command "set" for "etcdctl" Did you mean this? get put del user
原來的窗口是能夠執行的,可是新的窗口一直報錯,各類無賴ing...
member
list 列出etcd實例
add 添加etcd實例
remove 刪除etcd實例
查看集羣中存在的節點,例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl member list 1d64cbbe0759c8f8: name=ubuntu peerURLs=http://192.168.75.129:2380 clientURLs=http://192.168.75.129:2379 isLeader=true
刪除集羣中存在的節點,例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl member remove 1d64cbbe0759c8f8 Received an error trying to remove member 1d64cbbe0759c8f8: client: etcd cluster is unavailable or misconfigured; error #0: client: etcd member http://192.168.75.129:2379 has no leader
提示報錯,集羣中沒有leader
向集羣中新加節點,例如:
root@ubuntu:/opt/etcd-v3.3.10# ./etcdctl member add etcd3 http://192.168.75.129:2380 Added member named etcd3 with ID 6c40942fac2f358f to cluster ETCD_NAME="etcd3" ETCD_INITIAL_CLUSTER="etcd3=http://192.168.75.129:2380,default=http://localhost:2380" ETCD_INITIAL_CLUSTER_STATE="existing"
針對以上配置參數作些解釋:
ETCD_NAME :ETCD的節點名,在集羣中應該保持惟一,可使用 hostname。 ETCD_DATA_DIR:ETCD的數據存儲目錄,服務運行數據保存的路徑,默認爲 ${name}.etcd。 ETCD_SNAPSHOT_COUNTER:多少次的事務提交將觸發一次快照,指定有多少事務(transaction)被提交時,觸發截取快照保存到磁盤。 ETCD_HEARTBEAT_INTERVAL:ETCD節點之間心跳傳輸的間隔,單位毫秒,leader 多久發送一次心跳到 followers。默認值是 100ms。 ETCD_ELECTION_TIMEOUT:該節點參與選舉的最大超時時間,單位毫秒,從新投票的超時時間,若是 follow 在該時間間隔沒有收到心跳包,會觸發從新投票,默認爲 1000 ms。 ETCD_LISTEN_PEER_URLS:該節點與其餘節點通訊時所監聽的地址列表,多個地址使用逗號隔開,其格式能夠劃分爲scheme://IP:PORT,這裏的scheme能夠是http、https。和同伴通訊的地址,好比 http://ip:2380 ,若是有多個,使用逗號分隔。須要全部節點都可以訪問,因此不要使用 localhost。 ETCD_LISTEN_CLIENT_URLS:該節點與客戶端通訊時監聽的地址列表,對外提供服務的地址:好比 http://ip:2379 ,http://127.0.0.1:2379 ,客戶端會鏈接到這裏和 etcd 交互 ETCD_INITIAL_ADVERTISE_PEER_URLS:該成員節點在整個集羣中的通訊地址列表,這個地址用來傳輸集羣數據的地址。所以這個地址必須是能夠鏈接集羣中全部的成員的。該節點同伴監聽地址,這個值會告訴集羣中其餘節點。 ETCD_INITIAL_CLUSTER:配置集羣內部全部成員地址,其格式爲:ETCD_NAME=ETCD_INITIAL_ADVERTISE_PEER_URLS,若是有多個使用逗號隔開,集羣中全部節點的信息,格式爲 node1=http://ip1:2380 ,node2=http://ip2:2380 ,…。注意:這裏的 node1 是節點的 –name 指定的名字;後面的 ip1:2380 是 –initial-advertise-peer-urls 指定的值 ETCD_ADVERTISE_CLIENT_URLS:廣播給集羣中其餘成員本身的客戶端地址列表 ETCD_INITIAL_CLUSTER_STATE:新建集羣的時候,這個值爲new;假如已經存在的集羣,這個值爲 existing。 ETCD_INITIAL_CLUSTER_TOKEN:初始化集羣token,建立集羣的token,這個值每一個集羣保持惟一。這樣的話,若是你要從新建立集羣,即便配置和以前同樣,也會再次生成新的集羣和節點 uuid;不然會致使多個集羣之間的衝突,形成未知的錯誤。
注意:全部ETCD_MY_FLAG的配置參數也能夠經過命令行參數進行設置,可是命令行指定的參數優先級更高,同時存在時會覆蓋環境變量對應的值。
關於etcd api接口,請參考連接:
http://www.javashuo.com/article/p-bdknnihq-ch.html
以上內容,本文參考連接:
http://www.javashuo.com/article/p-boozrrii-hn.html
http://www.javashuo.com/article/p-mklsetss-kn.html
說明:本腳本,只能在本地服務器安裝。請確保etcd-v3.3.10-linux-amd64.tar.gz文件和shell腳本在同一目錄下。
腳本附帶了使用systemctl命令啓動etcd服務
請仔細閱讀開頭部分的注意事項
#/bin/bash # 單擊版etcd安裝腳本 # 本腳本,只能在本地服務器安裝。 # 請確保etcd-v3.3.10-linux-amd64.tar.gz文件和當前腳本在同一目錄下。 # 務必使用root用戶執行此腳本! # 確保能夠直接執行python3,由於倒數第4行,有一個json格式化輸出。若是不須要能夠忽略 #set -e # 輸入本機ip while true do echo '請輸入本機ip' echo 'Example: 192.168.0.1' echo -e "etcd server ip=\c" read ETCD_Server if [ "$ETCD_Server" == "" ];then echo 'No input etcd server IP' else #echo 'No input etcd server IP' break fi done # etcd啓動服務 cat > /lib/systemd/system/etcd.service <<EOF [Unit] Description=etcd - highly-available key value store Documentation=https://github.com/coreos/etcd Documentation=man:etcd After=network.target Wants=network-online.target [Service] Environment=DAEMON_ARGS= Environment=ETCD_NAME=%H Environment=ETCD_DATA_DIR=/var/lib/etcd/default EnvironmentFile=-/etc/default/%p Type=notify User=etcd PermissionsStartOnly=true #ExecStart=/bin/sh -c "GOMAXPROCS=\$(nproc) /usr/bin/etcd \$DAEMON_ARGS" ExecStart=/usr/bin/etcd \$DAEMON_ARGS Restart=on-abnormal #RestartSec=10s #LimitNOFILE=65536 [Install] WantedBy=multi-user.target Alias=etcd3.service EOF # 主機名 name=`hostname` # etcd的http鏈接地址 initial_cluster="http://$ETCD_Server:2380" # 判斷進程是否啓動 A=`ps -ef|grep /usr/bin/etcd|grep -v grep|wc -l` if [ $A -ne 0 ];then # 殺掉進程 killall etcd fi # 刪除etcd相關文件 rm -rf /var/lib/etcd/* rm -rf /etc/default/etcd # 設置時區 ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 判斷壓縮文件 if [ ! -f "etcd-v3.3.10-linux-amd64.tar.gz" ];then echo "當前目錄etcd-v3.3.10-linux-amd64.tar.gz文件不存在" exit fi # 安裝etcd tar zxf etcd-v3.3.10-linux-amd64.tar.gz -C /tmp/ cp -f /tmp/etcd-v3.3.10-linux-amd64/etcd /usr/bin/ cp -f /tmp/etcd-v3.3.10-linux-amd64/etcdctl /usr/bin/ # etcd配置文件 cat > /etc/default/etcd <<EOF ETCD_NAME=$name ETCD_DATA_DIR="/var/lib/etcd/" ETCD_LISTEN_PEER_URLS="http://$ETCD_Server:2380" ETCD_LISTEN_CLIENT_URLS="http://$ETCD_Server:2379,http://127.0.0.1:4001" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://$ETCD_Server:2380" ETCD_INITIAL_CLUSTER="$ETCD_Servernitial_cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-sdn" ETCD_ADVERTISE_CLIENT_URLS="http://$ETCD_Server:2379" EOF # 臨時腳本,添加用戶和組 cat > /tmp/foruser <<EOF #!/bin/bash if [ \`cat /etc/group|grep etcd|wc -l\` -eq 0 ];then groupadd -g 217 etcd;fi if [ \`cat /etc/passwd|grep etcd|wc -l\` -eq 0 ];then mkdir -p /var/lib/etcd && useradd -g 217 -u 111 etcd -d /var/lib/etcd/ -s /bin/false;fi if [ \`cat /etc/profile|grep ETCDCTL_API|wc -l\` -eq 0 ];then bash -c "echo 'export ETCDCTL_API=3' >> /etc/profile" && bash -c "source /etc/profile";fi EOF # 執行腳本 bash /tmp/foruser # 啓動服務 systemctl daemon-reload systemctl enable etcd.service chown -R etcd:etcd /var/lib/etcd systemctl restart etcd.service #netstat -anpt | grep 2379 # 查看版本 etcdctl -v # 訪問API, -s 去掉curl的統計信息. python3 -m json.tool 表示json格式化 curl $initial_cluster/version -s | python3 -m json.tool # 刪除臨時文件 rm -rf /tmp/foruser /tmp/etcd-v3.3.10-linux-amd64
執行腳本,輸出:
請輸入本機ip Example: 192.168.0.1 etcd server ip=192.168.75.129 etcdctl version: 3.3.10 API version: 2 { "etcdserver": "3.3.10", "etcdcluster": "3.3.0" }
若是須要清空etcd的值,使用如下命令
rm -rf /var/lib/etcd/member/*
重啓etcd
service etcd restart
查看etcd的全部的值,其中 --endpoints 用來指定etcd服務器地址
etcdctl get / --prefix --keys-only --endpoints=192.168.0.88:2379