etcd 集羣的管理 - 暴走漫畫容器實踐系列 Part4

搭建完 etcd 集羣后,接下來就是集羣的管理了。集羣的管理主要包括節點的重啓,監控以及集羣的運行時更改(Runtime Reconfiguration)。node

關於節點的重啓、監控相對來講比較簡單,這裏主要介紹下集羣的運行時更改。json

1. 在什麼狀況下須要集羣的運行時更改?

讓咱們來看看須要集羣的運行時更改的幾個場景。他們中的絕大多數只須要運用到重配置中的 「添加/刪除」 節點操做的組合。安全

1.1. 維護和升級多個機器

  • 若是你由於進行諸如硬件升級或者斷網等計劃維護,而須要移動多個節點到新機器上,最好是逐個節點移動,一次操做一個。app

  • 移動 leader 節點是安全的,只不過 leader 節點下線後,須要耗費更多的時間選舉新節點,因此建議最後移動。ssh

  • 若是你的集羣有超過 50M 的數據,最好進行節點的遷移(見3.1節 遷移節點),而不要經過刪除舊節點,增長新節點來實現節點的移動。curl

1.2. 更改集羣的大小

如上一篇博客所說的,增長集羣節點的個數,容錯能力越強,讀性能也越好。不過相應的,寫性能也會降低。減小集羣節點的個數,容錯能力降低,不過寫性能也會提升。性能

更改集羣大小也須要集羣運行時更改。this

1.3. 替換一個壞掉的節點

若是一個節點的機器由於硬件出錯而宕機了,那須要儘快用新機器替換。替換的操做就是簡單地分爲兩步:(經過集羣運行時更改)先刪除壞掉的節點,再添加新的節點(見2節 集羣節點的操做)。不過,若是你的集羣有超過 50M 的數據,最好進行節點遷移(見3.1節 遷移節點)url

1.4. 集羣多數宕機(Majority Failure)後的重啓

若是你的集羣出現了多數宕機(例如超過(N-1)/2的節點當機),或者全部的節點都更改了 IP,你就須要手動操做,重啓(恢復)集羣了。基本步驟包括:1.基於原先的數據建立新集羣;2.強制讓一個節點成爲 leader 節點,並最終經過運行時更改添加新節點的方式將其餘節點添加到這個新的集羣中。日誌

2. 集羣運行時更改的操做

知道了什麼樣的狀況下須要運行時更改,下面讓咱們來了解下具體的運行時更改的操做。

通常來講,這些操做須要確保集羣的多數節點是正常服務的,而且一次只操做一個節點。

  • 升級單個節點的 peerURLs,須要執行一個更新節點操做

  • 替換一個節點,須要先執行一個添加節點操做,再執行一個刪除節點操做

  • 將集羣大小從 3 更改到 5,須要執行兩個添加節點操做

  • 將集羣大小從 5 下降到 3,須要執行兩個刪除節點操做

下面的全部例子都是利用 etcdctl 命令實現操做,其本質是調用 etcd 的 REST API。你也可使用其餘你習慣的客戶端。

2.1 更新一個節點

若是你想更新一個節點的 IP(peerURLS),首先你須要知道那個節點的 ID。你能夠列出全部節點,找出對應節點的 ID。

$ 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

在本例中,咱們假設要更新 ID 爲 a8266ecf031671f3 的節點的 peerURLs 爲:http://10.0.1.10:2380

$ etcdctl member update a8266ecf031671f3 http://10.0.1.10:2380
Updated member with ID a8266ecf031671f3 in cluster

2.2 刪除一個節點

假設咱們要刪除 ID 爲 a8266ecf031671f3 的節點

$ etcdctl member remove a8266ecf031671f3
Removed member a8266ecf031671f3 from cluster

執行完後,目標節點會自動中止服務,而且打印一行日誌:

etcd: this member has been permanently removed from the cluster. Exiting.

若是刪除的是 leader 節點,則須要耗費額外的時間從新選舉 leader

2.3 增長一個新的節點

增長一個新的節點分爲兩步:

  • 經過 etcdctl 或對應的 API 註冊新節點

  • 使用恰當的參數啓動新節點

先看第一步,假設咱們要新加的節點取名爲 infra3, peerURLshttp://10.0.1.13:2380

$ etcdctl member add infra3 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 在註冊完新節點後,會返回一段提示,包含3個環境變量。而後在第二部啓動新節點的時候,帶上這3個環境變量便可。

$ 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個節點,在新節點成功啓動以前,新集羣並不能正確的造成。由於原先的單節點集羣沒法完成leader的選舉。
直到新節點啓動完,和原先的節點創建鏈接之後,新集羣才能正確造成。

3. 遷移節點和災難恢復

3.1 遷移節點

移動節點有兩種方式:1. 刪除舊的節點,增長新的節點; 2. 遷移節點。當集羣的數據超過 50M 的時候,建議經過遷移節點的方式來移動節點。

遷移節點的核心就是數據目錄的遷移。由於 etcd 的各個節點會將本身的 ID 存放在本身的數據目錄下面,因此遷移節點不會改變節點的 ID。

遷移節點的步驟簡單來講,包括如下幾步:

  • 中止須要遷移的節點的服務

  • 從老機器上拷貝數據目錄到新機器上

  • 經過集羣運行時更改的更新操做,改變節點的 peerURLs 值爲新機器的 IP:port

  • 在新機器上指定拷貝過來的數據目錄,啓動 etcd 的節點服務

下面經過一個例子具體說明。

假設咱們已有的集羣是這樣的:

name peerURLs
infra0 10.0.1.10:2380
infra1 10.0.1.11:2380
infra2 10.0.1.12:2380
$ etcdctl member list
84194f7c5edd8b37: name=infra0 peerURLs=http://10.0.1.10:2380 clientURLs=http://127.0.0.1:2379,http://10.0.1.10:2379
b4db3bf5e495e255: name=infra1 peerURLs=http://10.0.1.11:2380 clientURLs=http://127.0.0.1:2379,http://10.0.1.11:2379
bc1083c870280d44: name=infra2 peerURLs=http://10.0.1.12:2380 clientURLs=http://127.0.0.1:2379,http://10.0.1.12:2379

咱們要移動 infra1 從 10.0.1.11 到 10.0.1.13

1. 中止 infra1 的 etcd 進程
$ssh 10.0.1.11
$ kill `pgrep etcd`
2. 從 10.0.1.11 拷貝etcd的數據目錄到 10.0.1.13 的機器上
$ tar -cvzf infra1.etcd.tar.gz %data_dir%
$ scp infra1.etcd.tar.gz 10.0.1.13:~/
3. 變動 infra1 的 peerURLs
$ curl http://10.0.1.10:2379/v2/members/b4db3bf5e495e255 -XPUT \
-H "Content-Type: application/json" -d '{"peerURLs":["http://10.0.1.13:2380"]}'

或者利用 etcdctl

etcdctl member update b4db3bf5e495e255 http://10.0.1.13:2380
4. 在新機器上使用 infra1 的數據和配置啓動 etcd
$ ssh 10.0.1.13
$ tar -xzvf infra1.etcd.tar.gz -C %data_dir%
$ etcd -name infra1 \
> -listen-peer-urls http://10.0.1.13:2380 \
> -listen-client-urls http://10.0.1.13:2379,http://127.0.0.1:2379 \
> -advertise-client-urls http://10.0.1.13:2379,http://127.0.0.1:2379

3.2 災難恢復

總的來講,etcd 的集羣仍是至關可靠的,可是也不能排除極端狀況的出現。當出現災難性的多數節點宕機,就不得不進行災難恢復了。

災難恢復須要如下幾個步驟:

1 備份數據

備份操做須要在一臺還'活着'的節點上進行

$ etcdctl backup \
      --data-dir %data_dir% \
      --backup-dir %backup_data_dir%

這個命令會備份原數據到 %backup_data_dir% 目錄下,並從新相關的元數據(例如 節點的 id 和 集羣的 id)。
這意味着在 %backup_data_dir% 中只包含原先的數據,而不包含原先的身份信息。

接下來咱們就能夠基於備份的數據建立一個單節點的集羣。

2 從備份數據中重建單節點集羣
$ etcd \
      -data-dir=%backup_data_dir% \
      -force-new-cluster \
      ...

...部分省略了其餘相關的參數,例如-peer-urls -client-urls 等等

這時候,應該就成功建立了一個新的只包含一個節點的集羣,幷包含以前的全部數據。
當你確認新集羣正常後,就能夠刪除原來集羣的數據,暫停新集羣,將新集羣的數據目錄拷貝回原先數據的位置,並從新啓動。

$ pkill etcd
$ rm -rf %data_dir%
$ mv %backup_data_dir% %data_dir%
$ etcd \
    -data-dir=%data_dir% \
    ...
3 恢復集羣

如今已經有了一個擁有以前數據的單節點的集羣了。接下來,你能夠經過添加節點的操做,重建出一個一樣大小的集羣。值得注意的是,若是你仍是使用以前的其餘機器來重建這個新的集羣,必定殺掉以前的etcd 進程,而且清除掉以前的數據。

相關文章
相關標籤/搜索