從0到1學習邊緣容器系列 3 應用容災之邊緣自治

2022-01-10 23:17:31 字數 3593 閱讀 2579

邊緣計算使用的邊緣裝置數量龐大、分布全國各地,網路環境複雜,網際網路、乙太網、5g、wifi 等形態均有可能。因此,雲端的控制中心和邊緣端的裝置之間網路環境較複雜,網路質量差次不齊沒有保障。

kubernetes 傳統工作模式是所有元件 list-watch kube-apiserver,然後 reconcile 各種資源到期望狀態。各節點的健康都強依賴於其與 kube-apiserver 通訊的穩定。kubernetes 在傳統的集群環境上工作很完美,因為大多數集群都能保證在乙個區域網內。然而,在邊緣計算的業務場景下,有乙個穩定的網路環境著實是一件奢侈的事情。

(注:此文提到的網路環境,都是指節點與雲端的網路環境,而不是業務執行所在環境。)

我們來以乙個常見的廠房模型來介紹一下使用者在弱網環境下使用傳統 kubernetes 遇到的問題以及 tke 邊緣容器團隊在此類場景下提出的解決方案。

廠房a在北京地區,廠房b在廣州地區。二者之間是不能互通的。

使用者通過 kubernetes 管理平台進行workload的管理,master 與 worker 節點所在的廠房之間的網路環境網路環境是不能保證的,可能弱網a斷網,網路b仍然正常。使用者在這樣的場景下,提出了幾個需求:

對於使用者來說,這些訴求是他們的基本需求,也是其業務上雲的關鍵因素。使用者想要既享受 kubernetes 帶來方便的管理運維,同時也要具備弱網環境下的容災能力。這對傳統標準 kubernentes 解決方案提出了挑戰。

我們來溫習一下標準的 kubernentes 下,如果節點斷網失聯並且發生異常重啟的行為後,會出現哪些現象呢?

我們依次來看,首先,在傳統的模式下,節點是否健康取決於節點上 kubelet 元件的心跳或者續租。如果網路斷了,雲端元件當然會認為節點是不可用狀態。這個狀態可以提示使用者,該節點可能有異常,需要運維介入。同時,由於 kubelet 還在接管所有本機 pod,即使業務容器異常退出,容器也是可以繼續被拉起的。失聯的節點上所有的 pod ,它們的 ip 都會被從 endpoint list 中摘除,導致微服務不能訪問到這個節點,在傳統 kubernentes 集群中,這是乙個高可用的措施。但是在邊緣集群內,這個「節點不可用=服務不可用」等式是否還成立呢?這個地方是需要**的,其實很多業務場景下,使用者希望節點即使和雲端斷網,該節點上的 pod 也要能繼續對外提供服務。

因此我們團隊認為,在邊緣容器的場景下,單純與雲端網路失聯是不能被粗暴地認為「服務不可用」的。為此我們特意設計了第二件利器——「分布式節點健康檢查」外掛程式,來解決這個痛點,該功能會在後續文章進行詳細介紹。

下面重頭戲來了,斷網的節點重啟一下,容器還會在嗎?服務還可用嗎?回答是,容器當然不在嘍。而且容器不在了,服務肯定不能訪問了。使用者最關鍵的需求,顯然在傳統的 kubernentes 模式下,是不能滿足的。

那麼來看看我們邊緣計算的利器——邊緣自治功能能達到的效果吧。

我們為了達到最符合使用者的效果,配合使用了分布式節點健康檢查外掛程式功能,來保證節點在斷網情況下即使節點被置為notready 狀態,但是服務還是繼續可用。同時該節點上的 pod 也不會在新的節點上重新拉起新的 pod 副本。

我們在極端網路環境下,將執行業務的多個節點手動執行重啟操作來模擬節點異常重啟場景。節點重啟之後,節點元件正常啟動,之前的 pod 也會被自動被拉起,並且執行正常,處於 running 狀態。

那服務以及網路呢?我們測試後發現,重啟多個節點之後,我們在節點手動請求 pod ip,可以訪問成功;進入 pod a 內部分別請求在同乙個節點上的 pod b 以及另乙個節點上的 pod c(需要同乙個廠房環境),都可以訪問成功;在 pod a 解析 同一廠房的 service a, 可以解析並成功。最後,在外部對於該廠房內部的服務進行請求,訪問成功。

如此看來,邊緣自治功能,有效解決了傳統 kubernetes 在弱網環境下所不能解決的使用者痛點。

我們團隊為邊緣自治功能打磨了很久,涉及方面眾多,修改以及設計的地方比較多,本文不太介紹具體**實現細節。有興趣的同學可以和tke邊緣容器同學共同進行學習**。在此我簡單分享一些設計原理。

kubernetes 是典型的通過資料進行互動的架構。解決資料問題就能提供乙個夯實的基礎。所以弱網環境的邊緣自治,首當其衝的,最最最需要解決的問題就是資料問題。

考慮到弱網、斷網情況,需要保證節點的元件與雲端元件「通訊」,或者說讓節點認為此時還是可以「通訊」的。如上圖所示,我們在邊緣端加了一層映象 lite-apiserver 元件。邊緣節點上所有對 kube-apiserver 的請求都會發往 lite-apiserver,並由 lite-apiserver **到 kube-apiserver。對於邊緣節點來說,lite-apiserver 提供的功能就是 kube-apiserver 一樣,但是一方面 lite-apiserver 只對本節點有效,另一方面相比較標準的 kube-apiserver,我們對於 lite-apiserver 進行了裁剪,大幅度降低了其資源占用。我們在沒有修改原生 kube-apiserver 的情況下,實現了。在網路通暢的情況下,lite-apiserver 元件對於節點元件來說是透明的。當網路異常情況,lite-apiserver 元件會把本節點需要的資料返回給節點上元件,保證節點元件不會受網路異常情況影響。

ok,lite-apiserver 機制保證了斷網情況下,節點也不會和「apiserver」失聯。既然節點可以拉取到本節點對應的資料,那麼業務 pod 也就能夠被 kubelet 成功拉起來。下一步就是解決 pod 之間的互相訪問的問題了。

在邊緣容器場景下,考慮到適配性以及易用性,我們採用了 flannel 元件的 vxlan 模式作為網路解決方案。flannel 元件保證了跨節點之前的網路訪問。節點上的flannel 以及每個 pod 都有一些對應屬於自己的網路資訊,我們這裡採用了網路快照機制,將專屬於這些元件的網路資訊定期快照,從而保證了斷網環境下重啟後網路可用。並且實現了同節點、跨節點 pod 之間的網路互通。

使用者業務對外正常提供服務,以及集群內微服務之間互相呼叫,這些問題都會涉及到網域名稱解析。

如上圖所示,在傳統 kubernetes上,通過在集群中建立乙個kube-dns deployment 來解決是來解決網域名稱問題。但是邊緣計算集群,所有節點可能是不在乙個區域網,很可能是跨可用區的,各節點和 kube-dns 的訪問無法保證,乙個 kube-dns 的 deployment 不能滿足邊緣容器的需求。

在邊緣容器場景下,採用 daemonset 方式部署kube-dns,保證每個節點都有可用的 kube-dns,同時修改每個節點上 kubelet 啟動引數--cluster-dns,將其指向本機ip。這樣就保證了,即使斷網情況下,也能解析 kubernetes service 的網域名稱。

總結而言就是 lite-apiserver 機制為基礎, kube-proxy、flannel、kube-dns 以及網路快照機制保證了邊緣容器集群在弱網環境下的網路可靠性。

後續我們還會有一系列工作,來加強在弱網環境下的工作穩定性。

從0到1學習記錄

競爭會讓你把注意力都放在競爭對手身上,忽視了自己的發展。競爭會造成非常低水平的重複和跟風。不存在完美的市場均衡,在經濟理論之外的現實世界裡,每個企業的成功,恰恰是因為它打破了均衡,它做到了其他企業不能做的事情,也就是從0到1的事情,而不是它跟其他企業做一樣的事兒。谷歌把自己定義成什麼,取決於什麼能給...

Docker從0到1實操學習

1 解除安裝舊版本 yum remove docker docker client docker client latest docker common docker latest docker latest logrotate docker logrotate docker engine 2 需要...

gluon學習系列1 線性回歸 從0開始1

錯誤修正前 from mxnet import ndarray from mxnet import autograd import matplotlib.pyplot as plt true w 2,5 true b 1.5 num batch 1000 x ndarray.random norma...