etcd集羣搭建(高可用)

1、etcd介紹:java

ETCD 是一個高可用的分佈式鍵值數據庫,可用於服務發現。ETCD 採用 raft 一致性算法,基於 Go 語言實現。etcd做爲一個高可用鍵值存儲系統,天生就是爲集羣化而設計的。因爲Raft算法在作決策時須要多數節點的投票,因此etcd通常部署集羣推薦奇數個節點,推薦的數量爲三、5或者7個節點構成一個集羣。node

2、特色

實際上,etcd做爲一個受到Zookeeper與doozer啓發而催生的項目,除了擁有與之相似的功能外,更具備如下4個特色{![引自Docker官方文檔]}。linux

  • 簡單:基於HTTP+JSON的API讓你用curl命令就能夠輕鬆使用。
  • 安全:可選SSL客戶認證機制。
  • 快速:每一個實例每秒支持一千次寫操做。
  • 可信:使用Raft算法充分實現了分佈式。

3、etcd關鍵詞彙git

  • 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開始Leader競選。
  • Term:某個節點成爲Leader到下一次競選開始的時間週期,稱爲一個Term。
  • Index:數據項編號。Raft中經過Term和Index來定位數據。

4、etcd應用場景:github

  一、服務發現:算法

  服務發現(Service Discovery)要解決的是分佈式系統中最多見的問題之一,即在同一個分佈式集羣中的進程或服務如何才能找到對方並創建鏈接。從本質上說,服務發現就是想要了解集羣中是否有進程在監聽udp或tcp端口,而且經過名字就能夠進行查找和鏈接。數據庫

二、消息發佈與訂閱:安全

在分佈式系統中,最爲適用的組件間通訊方式是消息發佈與訂閱機制。具體而言,即構建一個配置共享中心,數據提供者在這個配置中心發佈消息,而消息使用者則訂閱他們關心的主題,一旦相關主題有消息發佈,就會實時通知訂閱者。經過這種方式能夠實現分佈式系統配置的集中式管理與實時動態更新服務器

  • 應用中用到的一些配置信息存放在etcd上進行集中管理。這類場景的使用方式一般是這樣的:應用在啓動的時候主動從etcd獲取一次配置信息,同時,在etcd節點上註冊一個Watcher並等待,之後每次配置有更新的時候,etcd都會實時通知訂閱者,以此達到獲取最新配置信息的目的。
  • 分佈式搜索服務中,索引的元信息和服務器集羣機器的節點狀態信息存放在etcd中,供各個客戶端訂閱使用。使用etcd的key TTL功能能夠確保機器狀態是實時更新的。
  • 分佈式日誌收集系統。這個系統的核心工做是收集分佈在不一樣機器上的日誌。收集器一般按照應用(或主題)來分配收集任務單元,所以能夠在etcd上建立一個以應用(或主題)命名的目錄P,並將這個應用(或主題)相關的全部機器ip,以子目錄的形式存儲在目錄P下,而後設置一個遞歸的etcd Watcher,遞歸式地監控應用(或主題)目錄下全部信息的變更。這樣就實現了在機器IP(消息)發生變更時,可以實時通知收集器調整任務分配。
  • 系統中信息須要動態自動獲取與人工干預修改信息請求內容的狀況。一般的解決方案是對外暴露接口,例如JMX接口,來獲取一些運行時的信息或提交修改的請求。而引入etcd以後,只須要將這些信息存放到指定的etcd目錄中,便可經過HTTP接口直接被外部訪問。

三、負載均衡:架構

在分佈式系統中,爲了保證服務的高可用以及數據的一致性,一般都會把數據和服務部署多份,以此達到對等服務,即便其中的某一個服務失效了,也不影響使用。這樣的實現雖然會致使必定程度上數據寫入性能的降低,可是卻能實現數據訪問時的負載均衡。由於每一個對等服務節點上都存有完整的數據,因此用戶的訪問流量就能夠分流到不一樣的機器上。

  • etcd自己分佈式架構存儲的信息訪問支持負載均衡。etcd集羣化之後,每一個etcd的核心節點均可以處理用戶的請求。因此,把數據量小可是訪問頻繁的消息數據直接存儲到etcd中也是個不錯的選擇,如業務系統中經常使用的二級代碼表。二級代碼表的工做過程通常是這樣,在表中存儲代碼,在etcd中存儲代碼所表明的具體含義,業務系統調用查表的過程,就須要查找表中代碼的含義。因此若是把二級代碼表中的小量數據存儲到etcd中,不只方便修改,也易於大量訪問。
  • 利用etcd維護一個負載均衡節點表。etcd能夠監控一個集羣中多個節點的狀態,當有一個請求發過來後,能夠輪詢式地把請求轉發給存活着的多個節點。相似KafkaMQ,經過Zookeeper來維護生產者和消費者的負載均衡。一樣也能夠用etcd來作Zookeeper的工做。

四、分佈式通知與協調:

這裏討論的分佈式通知與協調,與消息發佈和訂閱有些類似。二者都使用了etcd中的Watcher機制,經過註冊與異步通知機制,實現分佈式環境下不一樣系統之間的通知與協調,從而對數據變動進行實時處理。實現方式一般爲:不一樣系統都在etcd上對同一個目錄進行註冊,同時設置Watcher監控該目錄的變化(若是對子目錄的變化也有須要,能夠設置成遞歸模式),當某個系統更新了etcd的目錄,那麼設置了Watcher的系統就會收到通知,並做出相應處理。

  • 經過etcd進行低耦合的心跳檢測。檢測系統和被檢測系統經過etcd上某個目錄關聯而非直接關聯起來,這樣能夠大大減小系統的耦合性。
  • 經過etcd完成系統調度。某系統有控制檯和推送系統兩部分組成,控制檯的職責是控制推送系統進行相應的推送工做。管理人員在控制檯作的一些操做,實際上只須要修改etcd上某些目錄節點的狀態,而etcd就會自動把這些變化通知給註冊了Watcher的推送系統客戶端,推送系統再作出相應的推送任務。
  • 經過etcd完成工做彙報。大部分相似的任務分發系統,子任務啓動後,到etcd來註冊一個臨時工做目錄,而且定時將本身的進度進行彙報(將進度寫入到這個臨時目錄),這樣任務管理者就可以實時知道任務進度。

五、分佈式鎖:

由於etcd使用Raft算法保持了數據的強一致性,某次操做存儲到集羣中的值必然是全局一致的,因此很容易實現分佈式鎖。鎖服務有兩種使用方式,一是保持獨佔,二是控制時序。

  • 保持獨佔,即全部試圖獲取鎖的用戶最終只有一個能夠獲得。etcd爲此提供了一套實現分佈式鎖原子操做CAS(CompareAndSwap)的API。經過設置prevExist值,能夠保證在多個節點同時建立某個目錄時,只有一個成功,而該用戶便可認爲是得到了鎖。
  • 控制時序,即全部試圖獲取鎖的用戶都會進入等待隊列,得到鎖的順序是全局惟一的,同時決定了隊列執行順序。etcd爲此也提供了一套API(自動建立有序鍵),對一個目錄建值時指定爲POST動做,這樣etcd會自動在目錄下生成一個當前最大的值爲鍵,存儲這個新的值(客戶端編號)。同時還可使用API按順序列出全部當前目錄下的鍵值。此時這些鍵的值就是客戶端的時序,而這些鍵中存儲的值能夠是表明客戶端的編號。

5、搭建集羣

主機信息:

角色 系統 節點
master CentOS-7 192.168.10.5
node-1 CentOS-7 192.168.10.6
node-2 CentOS-7 192.168.10.7

 

 

 

 

 

 

配置阿里epel源:

mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

 

安裝配置存儲etcd(高可用): 

一、在三臺安裝etcd(集羣)、作高可用
[root@node1 ~]# yum -y install etcd
[root@node2 ~]# yum -y install etcd
[root@master ~]# yum -y install etcd

[root@master ~]# etcd --version
etcd Version: 3.2.22
Git SHA: 1674e68
Go Version: go1.9.4
Go OS/Arch: linux/amd64
2 配置文件修改
master節點
[root@master ~]# egrep -v "^$|^#" /etc/etcd/etcd.conf
ETCD_DATA_DIR
="/var/lib/etcd/default.etcd" #etcd數據保存目錄 ETCD_LISTEN_PEER_URLS="http://192.168.10.5:2380" #集羣內部通訊使用的URL ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" #供外部客戶端使用的url ETCD_NAME="etcd01" #etcd實例名稱 ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.5:2380" #廣播給集羣內其餘成員訪問的URL ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379" #廣播給外部客戶端使用的url ETCD_INITIAL_CLUSTER="etcd01=http://192.168.10.5:2380,etcd02=http://192.168.10.6:2380,etcd03=http://192.168.10.7:2380" #初始集羣成員列表 ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" #集羣的名稱 ETCD_INITIAL_CLUSTER_STATE="new" #初始集羣狀態,new爲新建集羣
node-1
[root@node1 etcd]# egrep -v "^$|^#" /etc/etcd/etcd.conf ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="http://192.168.10.6:2380" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_NAME="etcd02" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.6:2380" ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379" ETCD_INITIAL_CLUSTER="etcd01=http://192.168.10.5:2380,etcd02=http://192.168.10.6:2380,etcd03=http://192.168.10.7:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="exist"
node-2
[root@node2 ~]# egrep -v "^$|^#" /etc/etcd/etcd.conf ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="http://192.168.10.7:2380" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_NAME="etcd03" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.7:2380" ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379" ETCD_INITIAL_CLUSTER="etcd01=http://192.168.10.5:2380,etcd02=http://192.168.10.6:2380,etcd03=http://192.168.10.7:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="exist"

分別進行啓動:

[root@master etcd]# systemctl start etcd
[root@master etcd]# systemctl status etcd
● etcd.service - Etcd Server
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-01-08 17:28:34 CST; 2h 32min ago
 Main PID: 114077 (etcd)
    Tasks: 7
   Memory: 48.7M
   CGroup: /system.slice/etcd.service
           └─114077 /usr/bin/etcd --name=etcd01 --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://0.0.0.0:2379

Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 became candidate at term 16
Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 received MsgVoteResp from 4c5d727d37966a87 at term 16
Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 [logterm: 11, index: 44] sent MsgVote request to 315fd62e577c4037 at term 16
Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 [logterm: 11, index: 44] sent MsgVote request to f617da66fb9b90ad at term 16
Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 received MsgVoteResp from f617da66fb9b90ad at term 16
Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 [quorum:2] has received 2 MsgVoteResp votes and 0 vote rejections
Jan 08 20:00:08 master etcd[114077]: 4c5d727d37966a87 became leader at term 16
Jan 08 20:00:08 master etcd[114077]: raft.node: 4c5d727d37966a87 elected leader 4c5d727d37966a87 at term 16
Jan 08 20:00:09 master etcd[114077]: the clock difference against peer 315fd62e577c4037 is too high [4.285950016s > 1s]
Jan 08 20:00:09 master etcd[114077]: the clock difference against peer f617da66fb9b90ad is too high [4.120954945s > 1s]

[root@master etcd]# netstat -tunlp|grep etcd
tcp        0      0 192.168.10.5:2380       0.0.0.0:*               LISTEN      114077/etcd         
tcp6       0      0 :::2379                 :::*                    LISTEN      114077/etcd 

三、etc集羣測試

  集羣數據操做命令:

查看集羣節點
[root@node1 etcd]# etcdctl member list 315fd62e577c4037: name
=etcd03 peerURLs=http://192.168.10.7:2380 clientURLs=http://0.0.0.0:2379 isLeader=false 4c5d727d37966a87: name=etcd01 peerURLs=http://192.168.10.5:2380 clientURLs=http://0.0.0.0:2379 isLeader=true f617da66fb9b90ad: name=etcd02 peerURLs=http://192.168.10.6:2380 clientURLs=http://0.0.0.0:2379 isLeader=false

查看集羣健康狀態:

[root@master etcd]# etcdctl cluster-health
member 315fd62e577c4037 is healthy: got healthy result from http://0.0.0.0:2379
member 4c5d727d37966a87 is healthy: got healthy result from http://0.0.0.0:2379
member f617da66fb9b90ad is healthy: got healthy result from http://0.0.0.0:2379
cluster is healthy

 

 

  設置鍵值:

在一個節點設置值
[root@master etcd]# etcdctl set /test/key "test kubernetes" test kubernetes

在另外一個節點獲取值

[root@node1 etcd]# etcdctl get /test/key
test kubernetes

  • key存在的方式和zookeeper相似,爲 /路徑/key
  • 設置完以後,其餘集羣也能夠查詢到該值
  • 若是dirkey不存在,該命令會建立對應的項

 更新鍵值:

[root@master etcd]# etcdctl update /test/key "test kubernetes cluster"
test kubernetes cluster
[root@node1 etcd]# etcdctl
get /test/key test kubernetes cluster

刪除鍵值:

[root@master etcd]# etcdctl rm /test/key
PrevNode.Value: test kubernetes cluster

當鍵不存在時,會報錯 [root@node1 etcd]# etcdctl
get /test/key Error: 100: Key not found (/test/key) [15]

 etcd幫助:

[root@master etcd]# etcdctl help
NAME:
   etcdctl - A simple command line client for etcd.

WARNING:
   Environment variable ETCDCTL_API is not set; defaults to etcdctl v2.
   Set environment variable ETCDCTL_API=3 to use v3 API or ETCDCTL_API=2 to use v2 API.

USAGE:
   etcdctl [global options] command [command options] [arguments...]
   
VERSION:
   3.2.22
   
COMMANDS:
     backup          backup an etcd directory
     cluster-health  check the health of the etcd cluster
     mk              make a new key with a given value
     mkdir           make a new directory
     rm              remove a key or a directory
     rmdir           removes the key if it is an empty directory or a key-value pair
     get             retrieve the value of a key
     ls              retrieve a directory
     set             set the value of a key
     setdir          create a new directory or update an existing directory TTL
     update          update an existing key with a given value
     updatedir       update an existing directory
     watch           watch a key for changes
     exec-watch      watch a key for changes and exec an executable
     member          member add, remove and list subcommands
     user            user add, grant and revoke subcommands
     role            role add, grant and revoke subcommands
     auth            overall auth controls
     help, h         Shows a list of commands or help for one command

 參考文檔:

https://github.com/etcd-io/etcd

https://yq.aliyun.com/articles/623228

https://blog.csdn.net/hxpjava1/article/details/78275995

相關文章
相關標籤/搜索