原文地址:runtime reconfiguration
etcd帶有增量運行時重新配置的支持。允許我們在集群運行的時候更新集群成員關系。
僅當大多數集群成員都在運行時,才能處理重新配置請求,強烈建議在生產環境中集群的大小應該始終大於2。從兩個成員的集群中移除一個成員是不安全的。兩個成員的集群中大多數成員始終是2,如果在刪除過程中出現故障,集群將很難繼續運行需要重新從主要成員失敗中重新啟動集群。
為了更好的理解運行時重新配置設計,請閱讀運行時重新配置設計。
重新配置使用案例
本節將介紹一些重新配置集群的常見原因。 其中大多數原因僅涉及添加或刪除成員的組合,群集重新配置操作下將對此進行說明。
循環或更新多機
如果由於計划的維護(硬件升級,網絡停機等)而需要移動多個群集成員,建議一次修改一個成員。
移除領導者是安全的,但是在選舉過程中會出現短暫的停機時間。 如果群集包含的版本為v2的數據超過50MB,則建議遷移成員的數據目錄。
改變集群大小
增加群集大小可以增強容錯能力並提供更好的讀取性能,由於客戶端可以從任何成員讀取,因此增加成員數量將增加整體序列化讀取吞吐量。
減小群集大小可以提高群集的寫入性能,但需要權衡降低彈性。寫入集群之前,會將其復制到集群的大多數成員。 減小群集大小可減少大多數操作,並且每次寫入的提交速度都會更快。
替換一個失敗的主機
如果計算機由於硬件故障,數據目錄損壞或其他致命情況而失敗,應該盡快更換它。 發生故障但尚未移除的主機會對集群產生不利影響,並降低對其他故障的容忍度。
要更換主機,請按照說明從群集中刪除成員,然后在其位置添加新成員。如果群集擁有的空間超過50MB,則建議遷移仍可訪問的失敗成員的數據目錄。
多數主機失敗后重啟集群
如果大多數群集丟失或所有節點的IP地址都已更改,則必須采取手動操作才能安全恢復。恢復過程中的基本步驟包括使用舊數據創建新集群,強制單個成員充當領導者,最后使用運行時配置一次將新成員添加到該新集群中。
集群重新配置操作
考慮到這些用例,可以針對每個用例進行描述。進行任何更改之前,必須有多數etcd成員可以獲取。 對於對etcd的任何類型的寫入,這基本上是相同的要求。
必須按順序完成對集群的所有更改:
- 要更新單個成員節點URL,請執行更新操作.
- 要替換正常的單個成員,請刪除舊成員,然后添加新成員.
- 要從3名增加到5名成員,請執行兩次添加操作
- 成員數量要從5減少到3,請執行兩次刪除操作
這些示例都使用etcd附帶的etcdctl
命令行工具進行。如果不使用etcdctl
工具改變成員關系,使用v2HTTP成員API或者v3gRPC成員API。
更新一個成員
更新廣播客戶端URLs
要更新成員的發布客戶端URL,只需使用已更新的客戶端URL參數--advertise-client-urls
或環境變量ETCD_ADVERTISE_CLIENT_URLS
重新啟動該成員。重新啟動的成員將自行發布更新的URL。 錯誤更新的客戶端URL不會影響etcd群集的運行狀況。
更新廣播節點URLs
要更新成員的廣播節點URL,請首先通過成員命令顯式更新它,然后重新啟動該成員。由於更新節點URL會更改集群范圍的配置,並且可能影響etcd集群的運行狀況,因此需要采取其他措施。
要更新成員的廣播節點URL,請首先找到目標成員的ID。 列出具有etcdctl的所有成員:
$ etcdctl member list
6e3bd23ae5f1eae0: name=node2 peerURLs=http://localhost:23802 clientURLs=http://127.0.0.1:23792
924e2e83e93f2560: name=node3 peerURLs=http://localhost:23803 clientURLs=http://127.0.0.1:23793
a8266ecf031671f3: name=node1 peerURLs=http://localhost:23801 clientURLs=http://127.0.0.1:23791
本示例將更新
a8266ecf031671f3成員ID,並將其節點URLs值更改為http://10.0.1.10:2380
:
$ etcdctl member update a8266ecf031671f3 --peer-urls=http://10.0.1.10:2380
Updated member with ID a8266ecf031671f3 in cluster
移除一個成員
假設要移除的成員ID為a8266ecf031671f3。 使用remove
命令執行刪除:
$ etcdctl member remove a8266ecf031671f3
Removed member a8266ecf031671f3 from cluster
目標成員將在此時停止運行並在日志中打印出刪除內容:
etcd: this member has been permanently removed from the cluster. Exiting.
刪除領導者是安全的,但是當選擇新領導者時,群集將處於非活動狀態。 此持續時間通常是選舉超時時間加上投票過程的時間。
添加一個新成員
通過兩個步驟添加一個新的成員:
- 通過HTTP 成員API,gRPC成員API,或者是
etcdctl member add
命令添加一個新的成員到集群中。 - 通過新的集群配置啟動新的成員,新的集群配置包括被更新的成員(已存在的成員+新成員).
etcdctl
添加一個新的成員到集群中通過具體的成員名字和廣播節點URLs:
$ etcdctl member add infra3 --peer-urls=http://10.0.1.13:2380
added member 9bf1b35fc7761a23 to cluster
ETCD_NAME="infra3"
ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra3=http://10.0.1.13:2380"
ETCD_INITIAL_CLUSTER_STATE=existing
etcdctl
已將新成員通知集群,並打印出成功啟動集群所需的環境變量。 現在,使用新成員的相關參數啟動新的etcd進程:
$ export ETCD_NAME="infra3"
$ export ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra3=http://10.0.1.13:2380"
$ export ETCD_INITIAL_CLUSTER_STATE=existing
$ etcd --listen-client-urls http://10.0.1.13:2379 --advertise-client-urls http://10.0.1.13:2379 --listen-peer-urls http://10.0.1.13:2380 --initial-advertise-peer-urls http://10.0.1.13:2380 --data-dir %data_dir%
新成員將作為集群的一部分運行,並立即開始同步集群的其余部分。
如果添加多個成員,最佳做法是一次配置一個成員,並在添加更多新成員之前驗證它是否正確啟動.如果將新成員添加到1節點群集中,則群集無法在新成員啟動之前取得進展,因為它需要兩個成員作為多數才能達成共識。僅在etcdctl``member add
通知集群有關新成員的時間和新成員成功建立與現有成員的連接的時間之間,才發生此行為。
添加一個新的成員為領導者
從v3.4開始,etcd支持將新成員添加為領導者/非投票成員。激勵和設計可以在設計文檔中找到。為了使添加新成員的過程更安全,並減少添加新成員時的集群停機時間.建議將新成員作為學習者添加到集群中,直到同步完成為止。 這可以描述為三步過程:
- 通過gRPC成員API或者
etcdctl member add --learner
命令將新成員添加為學習者。 - 通過新的集群配置啟動新的成員,新的集群配置包括被更新的成員(已存在的成員+新成員)和之前的步驟相同.
- 通過gRPC成員API或
etcdctl member promote
命令將新添加的學習者提升為有投票權的成員。etcd服務器驗證升級請求以確保其運行安全.只有在其Raft日志達到領導者的水平之后,才能將學習者提升為有投票權的成員。如果學習者成員未趕上領導者的Raft日志,則成員升級請求將失敗(見提升成員錯誤案例部分獲取更多細節).這種情況下,用戶應該等待並重試。
在v3.4中,etcd服務器將群集可以擁有的學習者數量限制為一個。 主要考慮因素是限制由於領導者向學習者傳播數據而導致的領導者額外工作量。
使用etcdctl member add
和參數--learner
添加一個新成員作為學習者到集群中.
$ etcdctl member add infra3 --peer-urls=http://10.0.1.13:2380 --learner
Member 9bf1b35fc7761a23 added to cluster a7ef944b95711739
ETCD_NAME="infra3"
ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra3=http://10.0.1.13:2380"
ETCD_INITIAL_CLUSTER_STATE=existing
新的etcd程序添加新的學習者成員啟動后,使用etcdctl member promote
將學習者提升為投票成員。
$ etcdctl member promote 9bf1b35fc7761a23
Member 9e29bbaa45d74461 promoted in cluster a7ef944b95711739
添加成員錯誤案例
在以下情況下,新主機不包含在枚舉節點列表中。 如果這是一個新集群,則必須將該節點添加到初始集群成員列表中。
$ etcd --name infra3 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \
--initial-cluster-state existing
etcdserver: assign ids error: the member count is unequal
exit 1
在這種情況下,使用了與用於加入集群的地址(10.0.1.13:2380)不同的地址(10.0.1.14:2380):
$ etcd --name infra4 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra4=http://10.0.1.14:2380 \
--initial-cluster-state existing
etcdserver: assign ids error: unmatched member while checking PeerURLs
exit 1
如果etcd開始使用已刪除成員的數據目錄,則etcd如果連接到集群中的任何活動成員,則會自動退出:
$ etcd
etcd: this member has been permanently removed from the cluster. Exiting.
exit 1
添加成員為領導者錯誤案例
當集群中含有一個領導者時不能添加領導者到集群中(v3.4):
$ etcdctl member add infra4 --peer-urls=http://10.0.1.14:2380 --learner
Error: etcdserver: too many learner members in cluster
提升成員為領導者錯誤案例
如果學習者與領導者同步,則只能被提升為有投票權的成員。
$ etcdctl member promote 9bf1b35fc7761a23
Error: etcdserver: can only promote a learner member which is in sync with leader
提升不是學習者的成員將失敗。
$ etcdctl member promote 9bf1b35fc7761a23
Error: etcdserver: can only promote a learner member
提升一個集群中不存在的成員將會失敗:
$ etcdctl member promote 12345abcde
Error: etcdserver: member not found
嚴格的重新配置檢查模式(-strict-reconfig-check
)
如上所述,添加新成員的最佳實踐是一次配置一個成員,並在添加更多新成員之前驗證它是否正確啟動。這種分步方法非常重要,因為如果未正確配置新添加的成員(例如,對等URL不正確),則群集可能會丟失仲裁。