【導(dǎo)讀】新年快樂(lè)!本文介紹了etcd集群的工作原理和高可用技術(shù)細(xì)節(jié)。
etcd 簡(jiǎn)介
coreos 開(kāi)發(fā)的分布式服務(wù)系統(tǒng),內(nèi)部采用 raft 協(xié)議作為一致性算法。作為服務(wù)發(fā)現(xiàn)系統(tǒng),有以下的特點(diǎn):
簡(jiǎn)單:安裝配置簡(jiǎn)單,而且提供了 HTTP API 進(jìn)行交互,使用也很簡(jiǎn)單
安全:支持 SSL 證書(shū)驗(yàn)證
快速:根據(jù)官方提供的 benchmark 數(shù)據(jù),單實(shí)例支持每秒 2k+ 讀操作
可靠:采用 raft 算法,實(shí)現(xiàn)分布式系統(tǒng)數(shù)據(jù)的可用性和一致性
etcd 目前默認(rèn)使用 2379 端口提供 HTTP API 服務(wù),2380 端口和 peers(集群內(nèi)其他節(jié)點(diǎn))通信
雖然 etcd 也支持單點(diǎn)部署,但是在生產(chǎn)環(huán)境中推薦集群方式部署,一般 etcd 節(jié)點(diǎn)數(shù)會(huì)選擇 3、5、7。etcd 會(huì)保證所有的節(jié)點(diǎn)都會(huì)保存數(shù)據(jù),并保證數(shù)據(jù)的一致性和正確性。
工作原理
每個(gè) etcd cluster 都是有若干個(gè) member 組成的,每個(gè) member 是一個(gè)獨(dú)立運(yùn)行的 etcd 實(shí)例,單臺(tái)機(jī)器上可以運(yùn)行多個(gè) member。
在正常運(yùn)行的狀態(tài)下,集群中會(huì)有一個(gè) leader,其余的 member 都是 followers。leader 向 followers 同步日志,保證數(shù)據(jù)在各個(gè) member 都有副本。leader 還會(huì)定時(shí)向所有的 member 發(fā)送心跳報(bào)文,如果在規(guī)定的時(shí)間里 follower 沒(méi)有收到心跳,就會(huì)重新進(jìn)行選舉。
客戶(hù)端所有的請(qǐng)求都會(huì)先發(fā)送給 leader,leader 向所有的 followers 同步日志,等收到超過(guò)半數(shù)的確認(rèn)后就把該日志存儲(chǔ)到磁盤(pán),并返回響應(yīng)客戶(hù)端。
每個(gè) etcd 服務(wù)有三大主要部分組成:raft 實(shí)現(xiàn)、WAL 日志存儲(chǔ)、數(shù)據(jù)的存儲(chǔ)和索引。WAL 會(huì)在本地磁盤(pán)(就是之前提到的 --data-dir)上存儲(chǔ)日志內(nèi)容(wal file)和快照(snapshot)。
集群規(guī)劃
nameIPHOSTNAME
etcd01192.168.255.131master1
etcd02192.168.255.132master2
etcd03192.168.255.133master3
安裝
在安裝和啟動(dòng) etcd 服務(wù)的時(shí)候,各個(gè)節(jié)點(diǎn)需要知道集群中其他節(jié)點(diǎn)的信息(一般是 ip 和 port 信息)。根據(jù)你是否可以提前知道每個(gè)節(jié)點(diǎn)的 ip,有幾種不同的啟動(dòng)方案:
靜態(tài)配置:在啟動(dòng) etcd server 的時(shí)候,通過(guò) --initial-cluster 參數(shù)配置好所有的節(jié)點(diǎn)信息
etcd動(dòng)態(tài)發(fā)現(xiàn):通過(guò)已有的etcd集群作為數(shù)據(jù)交互點(diǎn),然后在擴(kuò)展新的集群時(shí)實(shí)現(xiàn)通過(guò)已有集群進(jìn)行服務(wù)發(fā)現(xiàn)的機(jī)制。比如官方提供的:discovery.etcd.io
DNS動(dòng)態(tài)發(fā)現(xiàn): 通過(guò)DNS查詢(xún)方式獲取其他節(jié)點(diǎn)地址信息。
一般生產(chǎn)環(huán)境都是使用靜態(tài)配置,我們這里也采用這種方法。并配置 SSL來(lái)保證通信安全。
1、安裝cfssl
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
2、創(chuàng)建ca證書(shū),客戶(hù)端,服務(wù)端,節(jié)點(diǎn)之間的證書(shū)
Etcd屬于server ,etcdctl 屬于client,二者之間通過(guò)http協(xié)議進(jìn)行通信。
ca證書(shū) 自己給自己簽名的權(quán)威證書(shū),用來(lái)給其他證書(shū)簽名
server證書(shū) etcd的證書(shū)
client證書(shū) 客戶(hù)端,比如etcdctl的證書(shū)
peer證書(shū) 節(jié)點(diǎn)與節(jié)點(diǎn)之間通信的證書(shū)
1) 創(chuàng)建目錄
mkdir -p /etc/etcd/pki
cd /etc/etcd/pki
cfssl print-defaults config 》 ca-config.json
cfssl print-defaults csr 》 ca-csr.json
2) 創(chuàng)建ca證書(shū)
修改ca-config.json
server auth表示client可以用該ca對(duì)server提供的證書(shū)進(jìn)行驗(yàn)證
client auth表示server可以用該ca對(duì)client提供的證書(shū)進(jìn)行驗(yàn)證
{
“signing”: {
“default”: {
“expiry”: “43800h”
},
“profiles”: {
“server”: {
“expiry”: “43800h”,
“usages”: [
“signing”,
“key encipherment”,
“server auth”,
“client auth”
]
},
“client”: {
“expiry”: “43800h”,
“usages”: [
“signing”,
“key encipherment”,
“client auth”
]
},
“peer”: {
“expiry”: “43800h”,
“usages”: [
“signing”,
“key encipherment”,
“server auth”,
“client auth”
]
}
}
}
}
創(chuàng)建證書(shū)簽名請(qǐng)求ca-csr.json
{
“CN”: “etcd”,
“key”: {
“algo”: “rsa”,
“size”: 2048
}
}
生成CA證書(shū)和私鑰
# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
3) 生成客戶(hù)端證書(shū)
vim client.json
{
“CN”: “client”,
“key”: {
“algo”: “ecdsa”,
“size”: 256
}
}
生成
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client -
# ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem client-key.pem client.pem
4) 生成server,peer證書(shū)
vim etcd.json
{
“CN”: “etcd”,
“hosts”: [
“127.0.0.1”,
“192.168.255.131”,
“192.168.255.132”,
“192.168.255.133”
],
“key”: {
“algo”: “ecdsa”,
“size”: 256
},
“names”: [
{
“C”: “CN”,
“L”: “SH”,
“ST”: “SH”
}
]
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server etcd.json | cfssljson -bare server
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer etcd.json | cfssljson -bare peer
3、安裝etcd二進(jìn)制文件
wget https://github.com/coreos/etcd/releases/download/v3.1.5/etcd-v3.1.5-linux-amd64.tar.gz
tar -xvf etcd-v3.1.5-linux-amd64.tar.gz
mv etcd-v3.1.5-linux-amd64/etcd* /usr/local/bin
4、service配置文件
vim /usr/lib/systemd/system/etcd.service, 三臺(tái)機(jī)器配置不一樣,需要替換為相應(yīng)的IP和name。
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
ExecStart=/usr/local/bin/etcd
--data-dir=/var/lib/etcd
--name=master1
--cert-file=/etc/etcd/pki/server.pem
--key-file=/etc/etcd/pki/server-key.pem
--trusted-ca-file=/etc/etcd/pki/ca.pem
--peer-cert-file=/etc/etcd/pki/peer.pem
--peer-key-file=/etc/etcd/pki/peer-key.pem
--peer-trusted-ca-file=/etc/etcd/pki/ca.pem
--listen-peer-urls=https://192.168.255.131:2380
--initial-advertise-peer-urls=https://192.168.255.131:2380
--listen-client-urls=https://192.168.255.131:2379,http://127.0.0.1:2379
--advertise-client-urls=https://192.168.255.131:2379
--initial-cluster-token=etcd-cluster-0
--initial-cluster=master1=https://192.168.255.131:2380,master2=https://192.168.255.132:2380,master3=https://192.168.255.133:2380
--initial-cluster-state=new
--heartbeat-interval=250
--election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
配置參數(shù)的含義
--name:方便理解的節(jié)點(diǎn)名稱(chēng),默認(rèn)為 default,在集群中應(yīng)該保持唯一,可以使用 hostname
--data-dir:服務(wù)運(yùn)行數(shù)據(jù)保存的路徑,默認(rèn)為 ${name}.etcd
--snapshot-count:指定有多少事務(wù)(transaction)被提交時(shí),觸發(fā)截取快照保存到磁盤(pán)
--heartbeat-interval:leader 多久發(fā)送一次心跳到 followers。默認(rèn)值是 100ms
--eletion-timeout:重新投票的超時(shí)時(shí)間,如果 follow 在該時(shí)間間隔沒(méi)有收到心跳包,會(huì)觸發(fā)重新投票,默認(rèn)為 1000 ms
--listen-peer-urls:和集群內(nèi)其他節(jié)點(diǎn)通信的地址, http://ip:2380,如果有多個(gè),使用逗號(hào)分隔。需要所有節(jié)點(diǎn)都能夠訪(fǎng)問(wèn),所以不要使用 localhost!
--listen-client-urls:節(jié)點(diǎn)與客戶(hù)端通信的地址,比如 http://ip:2379,http://127.0.0.1:2379,客戶(hù)端會(huì)連接到這里和 etcd 交互
--advertise-client-urls:對(duì)外通告的該節(jié)點(diǎn)客戶(hù)端監(jiān)聽(tīng)地址,http://ip:2379,這個(gè)值會(huì)通知集群中其他節(jié)點(diǎn)
--initial-advertise-peer-urls:節(jié)點(diǎn)與其他節(jié)點(diǎn)通信的地址,會(huì)通告給集群的其他成員。這個(gè)地址用來(lái)傳輸集群數(shù)據(jù)。因此這個(gè)地址必須是可以被集群中所有的成員訪(fǎng)問(wèn)http://ip:2380
--initial-cluster:集群中所有節(jié)點(diǎn)的信息,格式為 node1=http://ip1:2380,node2=http://ip2:2380,…。注意:這里的 node1 是節(jié)點(diǎn)的 --name 指定的名字;后面的 ip1:2380 是 --initial-advertise-peer-urls 指定的值
--initial-cluster-state:新建集群的時(shí)候,這個(gè)值為 new;假如已經(jīng)存在的集群,這個(gè)值為 existing
--initial-cluster-token:創(chuàng)建集群的 token,這個(gè)值每個(gè)集群保持唯一。這樣的話(huà),如果你要重新創(chuàng)建集群,即使配置和之前一樣,也會(huì)再次生成新的集群和節(jié)點(diǎn) uuid;否則會(huì)導(dǎo)致多個(gè)集群之間的沖突,造成未知的錯(cuò)誤
所有以--initial 開(kāi)頭的配置都是在 bootstrap(引導(dǎo)) 集群的時(shí)候才會(huì)用到,后續(xù)節(jié)點(diǎn)重啟時(shí)會(huì)被忽略。
5、創(chuàng)建存放etcd數(shù)據(jù)的目錄,啟動(dòng) etcd
mkdir /var/lib/etcd
systemctl daemon-reload && systemctl enable etcd && systemctl start etcd && systemctl status etcd
6、驗(yàn)證是否成功
在任意一臺(tái)機(jī)器(無(wú)論是不是集群節(jié)點(diǎn),前提是需要有etcdctl工具和ca證書(shū),server證書(shū))上執(zhí)行如下命令:
[root@master1] /etc/etcd/pki$ etcdctl --ca-file=/etc/etcd/pki/ca.pem --cert-file=/etc/etcd/pki/server.pem --key-file=/etc/etcd/pki/server-key.pem --endpoints=https://192.168.255.131:2379 cluster-health
2019-01-27 2026.909601 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
2019-01-27 2026.910165 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
member 5d7a44f5c39446c1 is healthy: got healthy result from https://192.168.255.132:2379
member e281e4e43dceb752 is healthy: got healthy result from https://192.168.255.133:2379
member ea5e4f12ed162d4b is healthy: got healthy result from https://192.168.255.131:2379
cluster is healthy
如果你沒(méi)有指定證書(shū),會(huì)報(bào)如下錯(cuò)誤
client: etcd cluster is unavailable or misconfigured; error #0: x509: certificate signed by unknown authority
查看集群成員
[root@master1] /etc/etcd/pki$ etcdctl --ca-file=/etc/etcd/pki/ca.pem --cert-file=/etc/etcd/pki/server.pem --key-file=/etc/etcd/pki/server-key.pem --endpoints=https://192.168.255.131:2379 member list
2019-01-27 2246.914338 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
5d7a44f5c39446c1: name=master2 peerURLs=https://192.168.255.132:2380 clientURLs=https://192.168.255.132:2379 isLeader=false
e281e4e43dceb752: name=master3 peerURLs=https://192.168.255.133:2380 clientURLs=https://192.168.255.133:2379 isLeader=false
ea5e4f12ed162d4b: name=master1 peerURLs=https://192.168.255.131:2380 clientURLs=https://192.168.255.131:2379 isLeader=true
etcd的使用
HTTP API
etcd 對(duì)外通過(guò) HTTP API 對(duì)外提供服務(wù),這種方式方便測(cè)試(通過(guò) curl 或者其他工具就能和 etcd 交互),也很容易集成到各種語(yǔ)言中(每個(gè)語(yǔ)言封裝 HTTP API 實(shí)現(xiàn)自己的 client 就行)。
etcdctl 命令行工具
除了 HTTP API 外,etcd 還提供了 etcdctl 命令行工具和 etcd 服務(wù)交互。這個(gè)命令行用 go 語(yǔ)言編寫(xiě),也是對(duì) HTTP API 的封裝,日常使用起來(lái)也更容易。
總結(jié)
etcd 默認(rèn)只保存 1000 個(gè)歷史事件,所以不適合有大量更新操作的場(chǎng)景,這樣會(huì)導(dǎo)致數(shù)據(jù)的丟失。etcd 典型的應(yīng)用場(chǎng)景是配置管理和服務(wù)發(fā)現(xiàn),這些場(chǎng)景都是讀多寫(xiě)少的。
相比于 zookeeper,etcd 使用起來(lái)要簡(jiǎn)單很多。不過(guò)要實(shí)現(xiàn)真正的服務(wù)發(fā)現(xiàn)功能,etcd 還需要和其他工具(比如 registrator、confd 等)一起使用來(lái)實(shí)現(xiàn)服務(wù)的自動(dòng)注冊(cè)和更新。一般etcd大多用于配置管理的場(chǎng)景,比如kubernetes。
目前 etcd 還沒(méi)有圖形化的工具。
原文標(biāo)題:快速搭建高可用 ETCD 集群
文章出處:【微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
責(zé)任編輯:haq
-
Linux
原文標(biāo)題:快速搭建高可用 ETCD 集群
文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論