來說說etcd
Kubernetes Container 叢集調度系統中後端採用 etcd 作為叢集狀態的儲存元件,而該 etcd 元件是由 CoreOS 公司開發並且開源貢獻給 CNCF 的 key/value 儲存專案。 etcd 主要負責將 Kubernetes API-Server 所處理過的資料進行加密儲存。 etcd 元件大多數會位於 Kubernetes 系統架構中的 Master Node 上。 API-Server 若要存取 etcd 上的資料必須先經過 etcd 的身分驗證流程確認使用者存取的身份與範圍是否合法,若身分確認無誤與存取範圍合法則將使用者所請求的資料透過 REST API 回傳資料給使用者。
Kubernetes 在通常情況下只會替系統管理員在 Master Node 上建立一個 etcd 元件,可能因為外在因素或是 etcd 請求負載過於龐大使得 etcd 元件發生故障,進而導致整體 Kubernetes發生API-Server 無法存取後端資料的問題。針對此問題系統管理員可以透過 Kubernetes Container 叢集調度技術建立一個高可用的 etcd 服務叢集,若單一個 etcd 元件發生故障時仍有其他 etcd 元件可以立即地補上作為備援使用。
etcd 怎麼在分散的世界保持一致
etcd 元件組成 etcd 叢集服務時首要任務就是確保後端資料是一制性的,以防使用者存取到錯誤的資料, etcd 採用的是 Raft 一至性共識演算法。
透過 Raft 演算法使得在同一個時間點上可以維持多個 etcd 元件儲存的狀態,這就保證了後端儲存的資料是保持一致,此外該演算法保證了當少數 etcd 元件崩潰或失效時仍不影響整體叢集的同步。
Raft 就是一種 leader-based 的共識算法並且使用心跳機制 (Heartbeat mechanism) 觸發同步與選舉,在該演算法裡面分別有三種身份第一種是 Leader 主要是叢集的領導人其他身份都必須跟領導人的資料同步,第二種是 Candidate 是當領導人無回應時欲參加該次選舉的節點稱為候選人,最後一種為 Follower 在選舉期間負責投票給候選人的節點如圖所示。

選舉的過程
-
一開始叢集各個節點身份都為Follower,並且節點上預設的選舉逾時時間(Election Time Out)與一般作業時間(Normal Operation)皆為範圍隨機亂數。在一般作業時間內節點會期待自己收到Leader週期性傳送過來的Heartbeat並且重置一般作業時間,若是超過一般作業時間節點都沒有收到Leader所傳送過來的Heartbeat該節點會當作目前沒有Leader的狀態,將觸發Leader的重選。
-
由於節點觸發Leader的重選此時節點將從Follower身份轉變為Candidate身份並且紀錄當前任期的號碼向叢集內其餘節點發送投票之請求,在觸發選舉後會有一段選舉逾時時間在該時間內,對於同一任期Follower只能選投一名Candidate,Candidate收到大於等於(2n+1) Follower的同意票,則該節點從Candidate身份轉變為叢集的新Leader。若在選舉逾時時間結束沒有收到(2n+1) Follower的同意票則視為當前選舉無效,再增加一次當前任期重新發起新一輪的選舉。而新的Leader需透過週期性的發送Heartbeat給各個節點來維持該Leader身份。
-
當發生在選舉逾時時間結束沒有收到(2n+1) Follower的同意票,無法選出Leader的情況,根據Raft演算法會讓節點縮短選舉逾時時間加速選出叢集的Leader以減少叢集無法同步的時間,另外在選舉期間節點可能會收到來自其他節點宣稱自己是Leader的心跳,該節點會確認心跳訊息內的任期編號是否大於當前任期,若是大於當前任期所有節點身份轉變為Follower身份並且與該Leader同步資料,若是心跳訊息的任期編號小於當前任期則無視該節點,繼續任期投票工作。
-
當叢集的Leader被選出之後,Leader會將使用者的每個請求都包裝成一個Commit並且透過Heartbeat週期性的複製到其他節點做為副本,當一個commit超過半數的節點都以複製並儲存才會能算該commit成功。此外該commit的元資料(metadata)會記錄當時commit的Leader任期號碼是多少,該任期號用來判斷節點之間副本不一致情形並且在每個一個節點儲存Commit都會有一個整數索引值來確認其在Commit目前已經儲存到第幾個位址如圖所示。

各個節點發生儲存內容不一致的情況,若任期三是第三節點繼續當Leader,在Leader發送Heartbeat的同時會將其他節點的資料強制覆蓋過去,利用Leader的強制性解決資料不統一的情況。第三節點發送一次Heartbeat強制同步個節點的index的Commit,如下圖所示。

後話
會繼續接著把 Kubernetes 的其他元件繼續講解一遍,如果有誤的地方歡迎大家指出謝謝~~
REF
- “Etcd | Coreos”. Coreos.Com, 2019, https://coreos.com/blog/etcd.
- Oliveira, Caio, et al. “Evaluating raft in docker on kubernetes.” International Conference on Systems Science. Springer, Cham, 2016.