概述
etcd 是兼具一致性和高可用性的鍵值資料庫,為雲原生架構中重要的基礎元件,由CNCF
孵化託管。etcd 在微服務和 Kubernates 叢集中不僅可以作為服務註冊與發現,還可以作為 key-value 儲存的中介軟體。
先決條件
- 執行的 etcd 叢集個數成員為奇數。
- etcd 是一個 leader-based 分散式系統。確保主節點定期向所有從節點傳送心跳,以保持叢集穩定。
- 保持穩定的 etcd 叢集對 Kubernetes 叢集的穩定性至關重要。因此,請在專用機器或隔離環境上執行 etcd 叢集,以滿足所需資源需求]。
- 確保不發生資源不足。
叢集的效能和穩定性對網路和磁碟 IO 非常敏感。任何資源匱乏都會導致心跳超時,從而導致叢集的不穩定。不穩定的情況表明沒有選出任何主節點。在這種情況下,叢集不能對其當前狀態進行任何更改,這意味著不能排程新的 pod。
相關術語
Raft
:etcd所採用的保證分散式系統強一致性的演算法。Node
:節點 ,Raft狀態機的一個例項,具有唯一標識。Member
: 成員,一個etcd例項。承載一個Node,且可為客戶端請求提供服務。Cluster
:叢集,由多個Member構成可以協同工作的etcd叢集。Peer
:同伴,Cluster
中其他成員。Proposal
:提議,一個需要完成 raft 協議的請求(例如寫請求,配置修改請求)。Client
: 向etcd叢集傳送HTTP請求的客戶端。WAL
:預寫式日誌,etcd用於持久化儲存的日誌格式。snapshot
:etcd防止WAL檔案過多而設定的快照,儲存etcd資料狀態。Proxy
:etcd的一種模式,為etcd叢集提供反向代理服務。Leader
:Raft演算法中通過競選而產生的處理所有資料提交的節點。Follower
:競選失敗的節點作為Raft中的從屬節點,為演算法提供強一致性保證。Candidate
:當Follower超過一定時間接收不到Leader的心跳時轉變為Candidate開始競選。Term
:某個節點成為Leader到下一次競選時間,稱為Ubuntu一個Term。Index
:資料項編號。Raft中通過Term和Index來定位資料。
ETCD 部署
原始碼安裝
基於master分支構建etcd
git clone https://github.com/etcd-io/etcd.git
cd etcd
./build # 如指令碼格式為dos的,需要將其格式修改為unix,否則報錯。
啟動命令
--listen-client-urls
於 --listen-peer-urls
不能為域名
--listen-client-urls
於 --advertise-client-urls
./etcd --name=etcd \
--data-dir=/var/lib/etcd/ \
--listen-client-urls=https://10.0.0.1:2379 \
--listen-peer-urls=https://10.0.0.1:2380 \
--advertise-client-urls=https://hketcd:2379 \
--initial-advertise-peer-urls=https://hketcd:2380 \
--cert-file="/etc/etcd/pki/server.crt" \
--key-file="/etc/etcd/pki/server.key" \
--client-cert-auth=true \
--trusted-ca-file="/etc/etcd/pki/ca.crt" \
--auto-tls=false \
--peer-cert-file="/etc/etcd/pki/peer.crt" \
--peer-key-file="/etc/etcd/pki/peer.key" \
--peer-client-cert-auth=true \
--peer-trusted-ca-file="/etc/etcd/pki/ca.crt" \
--peer-auto-tls=false
其他方式
- CentOS 可以使用
yum install etcd -y
- Ubuntu 可以預構建的二進位制檔案
安裝報錯
certificate: x509: certificate specifies an incompatible key usage
原因:此處證書用於
serverAuth
與clientAuth
,缺少clientAuth
導致解決:
extendedKeyUsage=serverAuth, clientAuth
WARNING: 2020/11/12 14:11:42 grpc: addrConn.createTransport failed to connect to {0.0.0.0:2379 <nil> 0 <nil>}. Err: connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate". Reconnecting...
{"level":"warn","ts":"2020-11-12T14:11:46.415+0800","caller":"embed/config_logging.go:198","msg":"rejected connection","remote-addr":"127.0.0.1:52597","server-name":"","error":"tls: failed to verify client certificate: x509: certificate specifies an incompatible key usage"}
原因:證書使用的者不對。
解決:檢視
subjectAltName
是否與請求地址一致。
error "tls: failed to verify client's certificate: x509: certificate specifies an incompatible key usage", ServerName ""
原因:
ETCD_LISTEN_PEER_URLS
與ETCD_LISTEN_CLIENT_URLS
不能用域名
error verifying flags, expected IP in URL for binding (https://hketcd:2380). See 'etcd --help'
error #0: x509: certificate has expired or is not yet valid
原因:證書還未生效
解決:因伺服器時間不對導致,校對時間後正常
配置檔案詳解
etcdctl 使用
etcdctl --key-file=/etc/etcd/pki/client.key \
--cert-file=/etc/etcd/pki/client.crt \
--ca-file=/etc/etcd/pki/ca.crt \
--endpoint="https://node01.k8s.test:2379" \
cluster-health
member 288506ee270a7733 is healthy: got healthy result from https://node03.k8s.test:2379
member 863156df9b1575d1 is healthy: got healthy result from https://node02.k8s.test:2379
member ff386de9dc0b3c40 is healthy: got healthy result from https://node01.k8s.test:2379
v3 版本客戶端使用
export ETCDCTL_API=3
etcdctl --key=/etc/etcd/pki/client.key \
--cert=/etc/etcd/pki/client.crt \
--cacert=/etc/etcd/pki/ca.crt \
--endpoints="https://master.k8s:2379" \
endpoint health
etcdctl \
--key=/etc/etcd/pki/client.key \
--cert=/etc/etcd/pki/client.crt \
--cacert=/etc/etcd/pki/ca.crt \
--endpoints="https://master.k8stx.com:2379" \
endpoint status
日誌獨立
etcd日誌預設輸出到 /var/log/message
如果想獨立日誌為一個檔案,可以使用rsyslogd過濾器功能,使etcd的日誌輸出到單獨的檔案內。
- 新建
/etc/rsyslog.d/xx.conf
檔案。 - 在新建檔案內寫入內容如下
if $programname == 'etcd' then /var/log/etcd.log
# 停止往其他檔案內寫入,如果不加此句,會繼續往/var/log/message寫入。
if $programname == 'etcd' then stop
也可以
if ($programname == 'etcd') then {
action(type="omfile" file="/var/log/etcd.log")
stop
}