etcd install & configuration

鋼閘門發表於2021-11-20

概述

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

其他方式

安裝報錯

certificate: x509: certificate specifies an incompatible key usage

原因:此處證書用於serverAuthclientAuth,缺少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_URLSETCD_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

原因:證書還未生效

解決:因伺服器時間不對導致,校對時間後正常

配置檔案詳解

config

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的日誌輸出到單獨的檔案內。

  1. 新建/etc/rsyslog.d/xx.conf檔案
  2. 在新建檔案內寫入內容如下
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
}

相關文章