etcd介紹
etcd是什么
etcd 是云原生架構(gòu)中重要的基礎(chǔ)組件,由 CNCF 孵化托管。etcd 在微服務(wù)和 Kubernates 集群中不僅可以作為服務(wù)注冊于發(fā)現(xiàn),還可以作為 key-value 存儲(chǔ)的中間件。
http server:用于處理用戶發(fā)送的API請求及其他etcd節(jié)點(diǎn)的同步與心跳信息請求
store:用于處理etcd支持的各類功能的事務(wù),包括:數(shù)據(jù)索引、節(jié)點(diǎn)狀態(tài)變更、監(jiān)控與反饋、事件處理與執(zhí)行等等,是etcd對用戶提供大多數(shù)API功能的具體實(shí)現(xiàn)
raft:強(qiáng)一致性算法,是etcd的核心
wal(write ahead log):預(yù)寫式日志,是etcd的數(shù)據(jù)存儲(chǔ)方式。除了在內(nèi)存中存有所有數(shù)據(jù)的狀態(tài)及節(jié)點(diǎn)的索引外,還通過wal進(jìn)行持久化存儲(chǔ)。
- 在wal中,所有的數(shù)據(jù)提交前都會(huì)事先記錄日志
- entry是存儲(chǔ)的具體日志內(nèi)容
- snapshot是為了防止數(shù)據(jù)過多而進(jìn)行的狀態(tài)快照
etcd的特點(diǎn)
etcd的目標(biāo)是構(gòu)建一個(gè)高可用的分布式鍵值(key-value)數(shù)據(jù)庫。具有以下特點(diǎn):
- 簡單:安裝配置簡單,而且提供了 HTTP API 進(jìn)行交互,使用也很簡單
- 鍵值對存儲(chǔ):將數(shù)據(jù)存儲(chǔ)在分層組織的目錄中,如同在標(biāo)準(zhǔn)文件系統(tǒng)中
- 監(jiān)測變更:監(jiān)測特定的鍵或目錄以進(jìn)行更改,并對值的更改做出反應(yīng)
- 安全:支持 SSL 證書驗(yàn)證
- 快速:根據(jù)官方提供的 benchmark 數(shù)據(jù),單實(shí)例支持每秒 2k+ 讀操作
- 可靠:采用 raft 算法,實(shí)現(xiàn)分布式系統(tǒng)數(shù)據(jù)的可用性和一致性
etcd 采用 Go 語言編寫,它具有出色的跨平臺(tái)支持,很小的二進(jìn)制文件和強(qiáng)大的社區(qū)。etcd 機(jī)器之間的通信通過 raft 算法處理。
etcd的功能
etcd 是一個(gè)高度一致的分布式鍵值存儲(chǔ),它提供了一種可靠的方式來存儲(chǔ)需要由分布式系統(tǒng)或機(jī)器集群訪問的數(shù)據(jù)。它可以優(yōu)雅地處理網(wǎng)絡(luò)分區(qū)期間的 leader 選舉,以應(yīng)對機(jī)器的故障,即使是在 leader 節(jié)點(diǎn)發(fā)生故障時(shí)。
從簡單的 Web 應(yīng)用程序到 Kubernetes 集群,任何復(fù)雜的應(yīng)用程序都可以從 etcd 中讀取數(shù)據(jù)或?qū)?shù)據(jù)寫入 etcd。
etcd的應(yīng)用場景
最常用于服務(wù)注冊與發(fā)現(xiàn),作為集群管理的組件使用
也可以用于K-V存儲(chǔ),作為數(shù)據(jù)庫使用
關(guān)于etcd的存儲(chǔ)
etcd 是一個(gè)鍵值存儲(chǔ)的組件,其他的應(yīng)用都是基于其鍵值存儲(chǔ)的功能展開。
etcd 的存儲(chǔ)有如下特點(diǎn):
1、采用kv型數(shù)據(jù)存儲(chǔ),一般情況下比關(guān)系型數(shù)據(jù)庫快。
2、支持動(dòng)態(tài)存儲(chǔ)(內(nèi)存)以及靜態(tài)存儲(chǔ)(磁盤)。
3、分布式存儲(chǔ),可集成為多節(jié)點(diǎn)集群。
4、存儲(chǔ)方式,采用類似目錄結(jié)構(gòu)。
- 只有葉子節(jié)點(diǎn)才能真正存儲(chǔ)數(shù)據(jù),相當(dāng)于文件。
- 葉子節(jié)點(diǎn)的父節(jié)點(diǎn)一定是目錄,目錄不能存儲(chǔ)數(shù)據(jù)。
服務(wù)注冊與發(fā)現(xiàn)
分布式系統(tǒng)中最常見的問題之一:在同一個(gè)分布式集群中的進(jìn)程或服務(wù)如何才能找到對方并建立連接
服務(wù)發(fā)現(xiàn)就可以解決此問題。
從本質(zhì)上說,服務(wù)發(fā)現(xiàn)就是要了解集群中是否有進(jìn)程在監(jiān)聽 UDP 或者 TCP 端口,并且通過名字就可以進(jìn)行查找和鏈接
服務(wù)發(fā)現(xiàn)的三大支柱
強(qiáng)一致性、高可用的服務(wù)存儲(chǔ)目錄?;?Raft 算法的 etcd 天生就是這樣一個(gè)強(qiáng)一致性、高可用的服務(wù)存儲(chǔ)目錄。
一種注冊服務(wù)和服務(wù)健康狀況的機(jī)制。用戶可以在 etcd 中注冊服務(wù),并且對注冊的服務(wù)配置 key TTL,定時(shí)保持服務(wù)的心跳以達(dá)到監(jiān)控健康狀態(tài)的效果。
一種查找和連接服務(wù)的機(jī)制。通過在 etcd 指定的主題下注冊的服務(wù)業(yè)能在對應(yīng)的主題下查找到。為了確保連接,我們可以在每個(gè)服務(wù)機(jī)器上都部署一個(gè) Proxy 模式的 etcd,這樣就可以確保訪問 etcd 集群的服務(wù)都能夠互相連接。
etcd2 中引入的 etcd/raft 庫,是目前最穩(wěn)定、功能豐富的開源一致性協(xié)議之一。作為 etcd、TiKV、CockcorachDB、Dgraph 等知名分布式數(shù)據(jù)庫的核心數(shù)據(jù)復(fù)制引擎,etcd/raft 驅(qū)動(dòng)了超過十萬個(gè)集群,是被最為廣泛采用一致性協(xié)議實(shí)現(xiàn)之一
消息發(fā)布與訂閱
在多節(jié)點(diǎn)、分布式系統(tǒng)中,最適用的一種組件間通信方式就是消息發(fā)布與訂閱,即:
- 即構(gòu)建一個(gè)配置共享中心,數(shù)據(jù)提供者在這個(gè)配置中心發(fā)布消息,而消息使用者則訂閱他們關(guān)心的主題,一旦主題有消息發(fā)布,就會(huì)實(shí)時(shí)通知訂閱者。通過這種方式可以做到分布式系統(tǒng)配置的集中式管理與動(dòng)態(tài)更新
應(yīng)用中用到的一些配置信息放到etcd上進(jìn)行集中管理。這類場景的使用方式通常是:
- 應(yīng)用在啟動(dòng)的時(shí)候主動(dòng)從etcd獲取一次配置信息。
- 同時(shí),在etcd節(jié)點(diǎn)上注冊一個(gè)Watcher并等待
- 以后每次配置有更新的時(shí)候,etcd都會(huì)實(shí)時(shí)通知訂閱者,以此達(dá)到獲取最新配置信息的目的
分布式搜索服務(wù)中,索引的元信息和服務(wù)器集群機(jī)器的節(jié)點(diǎn)狀態(tài)存放在etcd中,供各個(gè)客戶端訂閱使用。使用etcd的key TTL功能可以確保機(jī)器狀態(tài)是實(shí)時(shí)更新的。
etcd中使用了Watcher機(jī)制,通過注冊與異步通知機(jī)制,實(shí)現(xiàn)分布式環(huán)境下不同系統(tǒng)之間的通知與協(xié)調(diào),從而對數(shù)據(jù)變更做到實(shí)時(shí)處理。實(shí)現(xiàn)方式:
- 不同系統(tǒng)都在etcd上對同一個(gè)目錄進(jìn)行注冊,同時(shí)設(shè)置Watcher觀測該目錄的變化(如果對子目錄的變化也有需要,可以設(shè)置遞歸模式)
- 當(dāng)某個(gè)系統(tǒng)更新了etcd的目錄,那么設(shè)置了Watcher的系統(tǒng)就會(huì)收到通知,并作出相應(yīng)處理。
etcd集群的部署
為了整個(gè)集群的高可用,etcd一般都會(huì)進(jìn)行集群部署,以避免單點(diǎn)故障。
引導(dǎo)etcd集群的啟動(dòng)有以下三種機(jī)制:
- 靜態(tài)
- etcd動(dòng)態(tài)發(fā)現(xiàn)
- DNS發(fā)現(xiàn)
靜態(tài)啟動(dòng)etcd集群
單機(jī)安裝
如果想要在一臺(tái)機(jī)器上啟動(dòng)etcd集群,可以使用 goreman 工具(go語言編寫的多進(jìn)程管理工具,是對Ruby下官方使用的foreman的重寫)
操作步驟:
- 安裝Go運(yùn)行環(huán)境
- 安裝goreman:go get github.com/mattn/goreman
- 配置goreman的配置加農(nóng)本 Procfile:
etcd1: etcd --name infra1 --listen-client-urls http://127.0.0.1:12379 --advertise-client-urls http://127.0.0.1:12379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
etcd2: etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
etcd3: etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
參數(shù)說明:
- –name:etcd集群中的節(jié)點(diǎn)名,這里可以隨意,可區(qū)分且不重復(fù)即可
- –listen-peer-urls:監(jiān)聽的用于節(jié)點(diǎn)之間通信的url,可監(jiān)聽多個(gè),集群內(nèi)部將通過這些url進(jìn)行數(shù)據(jù)交互(如選舉,數(shù)據(jù)同步等)
- –initial-advertise-peer-urls:建議用于節(jié)點(diǎn)之間通信的url,節(jié)點(diǎn)間將以該值進(jìn)行通信。
- –listen-client-urls:監(jiān)聽的用于客戶端通信的url,同樣可以監(jiān)聽多個(gè)。
- –advertise-client-urls:建議使用的客戶端通信 url,該值用于 etcd 代理或 etcd 成員與 etcd 節(jié)點(diǎn)通信。
- –initial-cluster-token:etcd-cluster-1,節(jié)點(diǎn)的 token 值,設(shè)置該值后集群將生成唯一 id,并為每個(gè)節(jié)點(diǎn)也生成唯一 id,當(dāng)使用相同配置文件再啟動(dòng)一個(gè)集群時(shí),只要該 token 值不一樣,etcd 集群就不會(huì)相互影響。
- –initial-cluster:也就是集群中所有的 initial-advertise-peer-urls 的合集。
- –initial-cluster-state:new,新建集群的標(biāo)志
啟動(dòng):goreman -f /opt/etcd/etc/procfile start
docker啟動(dòng)集群
etcd 使用
gcr.io/etcd-development/etcd 作為容器的主要加速器, quay.io/coreos/etcd 作為輔助的加速器:
- docker pull bitnami/etcd:3.4.7
- docker image tag bitnami/etcd:3.4.7 quay.io/coreos/etcd:3.4.7
鏡像設(shè)置好之后,啟動(dòng) 3 個(gè)節(jié)點(diǎn)的 etcd 集群,腳本命令如下:
- 該腳本是部署在三臺(tái)機(jī)器上,每臺(tái)機(jī)器置行對應(yīng)的腳本即可。
REGISTRY=quay.io/coreos/etcd
# For each machine
ETCD_VERSION=3.4.7
TOKEN=my-etcd-token
CLUSTER_STATE=new
NAME_1=etcd-node-0
NAME_2=etcd-node-1
NAME_3=etcd-node-2
HOST_1= 192.168.202.128
HOST_2= 192.168.202.129
HOST_3= 192.168.202.130
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
DATA_DIR=/var/lib/etcd
# For node 1
THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
docker run
-p 2379:2379
-p 2380:2380
--volume=${DATA_DIR}:/etcd-data
--name etcd ${REGISTRY}:${ETCD_VERSION}
/usr/local/bin/etcd
--data-dir=/etcd-data --name ${THIS_NAME}
--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://0.0.0.0:2380
--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://0.0.0.0:2379
--initial-cluster ${CLUSTER}
--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
# For node 2
THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
docker run
-p 2379:2379
-p 2380:2380
--volume=${DATA_DIR}:/etcd-data
--name etcd ${REGISTRY}:${ETCD_VERSION}
/usr/local/bin/etcd
--data-dir=/etcd-data --name ${THIS_NAME}
--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://0.0.0.0:2380
--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://0.0.0.0:2379
--initial-cluster ${CLUSTER}
--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
# For node 3
THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
docker run
-p 2379:2379
-p 2380:2380
--volume=${DATA_DIR}:/etcd-data
--name etcd ${REGISTRY}:${ETCD_VERSION}
/usr/local/bin/etcd
--data-dir=/etcd-data --name ${THIS_NAME}
--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://0.0.0.0:2380
--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://0.0.0.0:2379
--initial-cluster ${CLUSTER}
--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
動(dòng)態(tài)發(fā)現(xiàn)啟動(dòng)etcd集群
在實(shí)際環(huán)境中,集群成員的ip可能不會(huì)提前知道。這種情況下需要使用自動(dòng)發(fā)現(xiàn)來引導(dǎo)etcd集群,而不是事先指定靜態(tài)配置
協(xié)議原理
discovery service protocol 幫助新的 etcd 成員使用共享 URL 在集群引導(dǎo)階段發(fā)現(xiàn)所有其他成員。
該協(xié)議使用新的發(fā)現(xiàn)令牌來引導(dǎo)一個(gè)唯一的 etcd 集群。一個(gè)發(fā)現(xiàn)令牌只能代表一個(gè) etcd 集群。只要此令牌上的發(fā)現(xiàn)協(xié)議啟動(dòng),即使它中途失敗,也不能用于引導(dǎo)另一個(gè) etcd 集群。
獲取 discovery 的 token:
- 生成將標(biāo)識(shí)新集群的唯一令牌:UUID=$(uuidgen)
- 指定集群的大小:curl -X PUT http://:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size -d value=3
- 將該url地址,作為 --discovery 參數(shù)來啟動(dòng)etcd,節(jié)點(diǎn)會(huì)自動(dòng)使用該url目錄進(jìn)行etcd的注冊和發(fā)現(xiàn)服務(wù)。
在完成了集群的初始化后,當(dāng)再需要增加節(jié)點(diǎn)時(shí),需要使用etcdctl進(jìn)行操作,每次啟動(dòng)新的etcd集群時(shí),都使用新的token進(jìn)行注冊。
DNS自發(fā)現(xiàn)模式
etcd核心API
- KV 服務(wù),創(chuàng)建,更新,獲取和刪除鍵值對。
- 監(jiān)視,監(jiān)視鍵的更改。
- 租約,消耗客戶端保持活動(dòng)消息的基元。
- 鎖,etcd 提供分布式共享鎖的支持。
- 選舉,暴露客戶端選舉機(jī)制。
etcd典型應(yīng)用場景(K8s)
什么是k8s?
開源的,用于管理云平臺(tái)中多個(gè)主機(jī)上的容器化應(yīng)用。
與傳統(tǒng)應(yīng)用部署方式的區(qū)別:
傳統(tǒng)部署:
- 通過插件或腳本的方式安裝應(yīng)用。這樣做的缺點(diǎn)是應(yīng)用的運(yùn)行、配置、管理、所有生存周期將與當(dāng)前操作系統(tǒng)綁定,不利于應(yīng)用的升級更新、回滾等操作。
- 由于資源利用不足而無法擴(kuò)展,并且組織維護(hù)大量物理服務(wù)器的成本很高。
虛擬化部署:
- 虛擬化功能,允許在單個(gè)物理服務(wù)器的cpu上運(yùn)行多個(gè)虛擬機(jī)(VM)
- 應(yīng)用程序在VM之間隔離,提供安全級別
- 虛擬機(jī)非常重,可移植性、擴(kuò)展性差
容器化部署:
- 通過容器的方式實(shí)現(xiàn)部署,每個(gè)容器之間相互隔離,每個(gè)容器有自己的文件系統(tǒng),容器之間進(jìn)程不會(huì)相互影響,能區(qū)分計(jì)算資源。
- 相對于虛擬機(jī),容器能快速部署,由于容器與底層設(shè)施、機(jī)器文件系統(tǒng)是解耦的,所以它能在不同的云、不同版本操作系統(tǒng)之間進(jìn)行遷移。
- 容器占用資源少、部署快,每個(gè)應(yīng)用都可以被打包成一個(gè)容器鏡像,每個(gè)應(yīng)用與容器之間形成一對一的關(guān)系。每個(gè)應(yīng)用不需要與其余的應(yīng)用堆棧組合,也不依賴于生產(chǎn)環(huán)境的基礎(chǔ)結(jié)構(gòu),這使得從研發(fā)–>測試–>生產(chǎn)能提供一致的環(huán)境。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(
img-fm4iUxNG-1607939778399)(https://d33wubrfki0l68.cloudfront.net/26a177ede4d7b032362289c6fccd448fc4a91174/eb693/images/docs/container_evolution.svg)]
K8s提供了一個(gè)可彈性運(yùn)行分布式系統(tǒng)的框架,可以滿足實(shí)際生產(chǎn)環(huán)境所需要的擴(kuò)展要求、故障轉(zhuǎn)移、部署模式等
K8s提供如下功能:
- 服務(wù)發(fā)現(xiàn)與負(fù)載均衡
- 存儲(chǔ)編排
- 自動(dòng)部署和回滾
- 自動(dòng)二進(jìn)制打包:K8s允許指定每個(gè)容器所需CPU和內(nèi)存(RAM),當(dāng)容器制定了資源請求時(shí),K8s可以做出更好的決策來管理容器的資源。
- 自我修復(fù):K8s重新啟動(dòng)失敗的容器,替換容器,殺死不響應(yīng)用戶定義的運(yùn)行狀況檢查的容器,并且在準(zhǔn)備好服務(wù)之前將其通告給客戶端
- 密鑰與配置管理
K8s的特點(diǎn)
可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
可擴(kuò)展: 模塊化,插件化,可掛載,可組合
自動(dòng)化: 自動(dòng)部署,自動(dòng)重啟,自動(dòng)復(fù)制,自動(dòng)伸縮/擴(kuò)展
K8s組件
master(主節(jié)點(diǎn))組件:
kube-apiserver:對外提供調(diào)用的開放接口服務(wù)
ETCD:提供默認(rèn)的存儲(chǔ)系統(tǒng),保存所有集群數(shù)據(jù)
kube-controller-manager:運(yùn)行管理控制器,是集群中處理常規(guī)任務(wù)的后臺(tái)線程,包括:
- 節(jié)點(diǎn)控制器:
- 副本控制器:負(fù)責(zé)維護(hù)系統(tǒng)中每個(gè)副本中的pod(pod是最小的,管理,創(chuàng)建,計(jì)劃的最小單元)
- 端點(diǎn)控制器:填充endpoints對象(連接service 和 pods)
- service account和token控制器:
cloud-controller-manager:云控制器管理器負(fù)責(zé)與底層云提供商的平臺(tái)交互
kube-scheduler:監(jiān)視新創(chuàng)建沒有分配到node的pod,為pod選擇一個(gè)node
插件 addons:實(shí)現(xiàn)集群pod和service功能
- DNS
- 用戶界面
- 容器資源監(jiān)測
- Cluster-level Logging
node(計(jì)算節(jié)點(diǎn))組件:
kubelet:主要的節(jié)點(diǎn)代理,它會(huì)監(jiān)視已分配給節(jié)點(diǎn)的pod
kube-proxy:通過在主機(jī)上維護(hù)網(wǎng)絡(luò)規(guī)則并執(zhí)行連接轉(zhuǎn)發(fā)來實(shí)現(xiàn)k8s服務(wù)抽象
docker:運(yùn)行容器
RKT:運(yùn)行容器,作為docker工具的替代方案
supervisord:一個(gè)輕量級監(jiān)控系統(tǒng),用于保障kubelet和docker的運(yùn)行
fluentd:守護(hù)進(jìn)程,可提供cluster-level logging
K8s典型架構(gòu)圖
說明:
CNI:CNI(容器網(wǎng)絡(luò)接口)是Cloud Native Computing Foundation項(xiàng)目,由一個(gè)規(guī)范和庫(用于編寫用于在Linux容器中配置網(wǎng)絡(luò)接口的插件)以及許多受支持的插件組成。CNI僅涉及容器的網(wǎng)絡(luò)連接以及刪除容器時(shí)刪除分配的資源,通過json的語法定義了CNI插件所需要的輸入和輸出。
CRI:容器運(yùn)行時(shí)接口,一個(gè)能讓kubelet無需編譯就可以支持多種容器運(yùn)行時(shí)的插件接口。CRI包含了一組protocol buffer。gRPC API相關(guān)的庫。
OCI:主要負(fù)責(zé)是容器的生命周期管理,OCI的runtime spec標(biāo)準(zhǔn)中對于容器狀態(tài)的描述,以及對容器的創(chuàng)建、刪除、查看等操作進(jìn)行了定義。runc是對OCI標(biāo)準(zhǔn)的一個(gè)參考實(shí)現(xiàn)
-
API
+關(guān)注
關(guān)注
2文章
1461瀏覽量
61490 -
數(shù)據(jù)存儲(chǔ)
+關(guān)注
關(guān)注
5文章
947瀏覽量
50760 -
CNC
+關(guān)注
關(guān)注
7文章
269瀏覽量
34837
發(fā)布評論請先 登錄
相關(guān)推薦
評論