您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何實現分布式協調Kubernet,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
單一的應用程序,就是之前在單個節點上運行的單個實例,包括了很多在數據庫更新狀態的調度jobs(現在也同樣發布商務events)。單體程序創建在java中,并且大量使用Spring,所以job看起來是這個樣子的:
Spring之后會確認提到過的 doSomethingEveryMinute方法每分鐘執行一次。問題是,如果我們目前不在Kubernetes上主持單體程序,并且跟多個實例一起運行,這個job就每分鐘會在每個實例上被執行一次,而不僅僅只是每分鐘執行了一次而已。如果job有類似發送通知郵件或更新數據庫這樣的副作用的話,這就是一個問題了。所以我們要怎樣避免這個?當然,解決方案還是很多的,顯而易見的選擇就是利用Kubernetes Jobs,讓Kubernetes自己周期性調度jobs。問題就是這個作用只在Kubernetes1.3版本及以上版本中可用,但是1.3還沒有發布。但是即使我們能夠使用這樣一個功能,從技術角度來說,這也是不太可行的。我們的jobs被高度耦合到已經存在的代碼庫,并且提取每個job到它自己的應用程序,程序可能會有錯誤,而且如果一次性完成的話會非常耗費時間。所以我們最初的計劃是提取所有的調度jobs到一個應用程序,這個應用程序在Kubernetes中只能作為一個實例來運行。但由于現有代碼的本質,和高耦合性,即使是這樣也很難實現。那么,有沒有一種很輕松的辦法允許我們目前在單體應用中保持jobs,并且當我們從這個應用中提取功能到獨立的服務的時候,逐漸替代他們呢?其實還是有的。
要解決這個,我們需要做一些分布式協調,比如,當jobs被Spring執行的時候,如果這個節點不是“leader節點”,為運行調度jobs負責,我們就只需要傳回信息(而且,不要和job一起運行代碼)。有一些項目能夠幫助我們來處理諸如zookeeper和hazelcast之類的東西。但是僅僅只是為了決定哪個節點執行調度jobs,以此來設置、保留zookeeper集群就太勞師動眾了。我們需要一些易于管理的東西,假如我們能夠利用Kubernetes會怎么樣呢?Kubernetes已經在cover下(使用 RAFT consensus algorithm)處理了leader選舉。結果證明,這個功能通過使用gcr.io/google_containers/leader-elector Docker鏡像已經被暴露給了終端用戶。之前已經有一個很棒的博客帖子很細節地描述過這個是如何運行的了,點擊這個網址查看:http://blog.kubernetes.io/2016/01/simple-leader-election-with-Kubernetes.html。所以在這里我就不多加贅述了,但是我會講一講我們是如何利用鏡像來解決我們的問題的。
我們做的就是帶來gcr.io/google_containers/leader-elector容器到我們的pod,這樣就可以讓單體應用的實例都運行一個leader選舉的實例。這是證明Kubernetes pod有用的典型例子。
以下是一個在我們的配置resource中定義好的pod的摘錄:
我們開啟leader選舉以及我們的單體應用程序。注意,我們將 --election=monolith-jobs當作第一個參數。這就意味著leader選舉知道容器屬于哪一個組。所以指定這個組的容器會是leader選舉進程中的一部分,這個組之中只有一個容器會被選舉為leader。 --http=localhost:4040的第二個參數同樣是非常重要的。它在4040端口打開了一個網頁服務器,在這個端口,我們可以查詢到目前leader的pod名字,然后以這個格式返回:
這是我們決定要不要運行我們的job的一個小把戲。我們要做的事情就是檢查即將執行調度pod的名字是否跟選舉出來的leader一致,如果一致,我們就應該繼續執行,并且執行job,或者其它的我們應該返回的東西。比如:
所以我們來看看ClusterLeaderService是如何被實施的。首先,我們必須從應用程序獲得pod的名字。Kubernetes將pod名字存儲在/etc/hostname ,Java將這個/etc/hostname暴露在HOSTNAME環境變量,這就是我們將在這個例子中引用的。另一個方法就是使用 Downward API將pod名字暴露到環境變量選擇。比如:
從這里,我們可以看到 metadata.name (也就是pod的名字)會與 MY_POD_NAME環境變量聯系在一起。但是現在讓我們來看看 ClusterLeaderService的實施是看起來是怎么樣的:
在這里例子中,我們正在從 RESTAssured 項目使用 JsonPath來查詢選舉者網頁服務,并且從回應中提取pod的名字。然后我們簡單地將本地容器的名字跟leader相比較,如果他們是相同的,那么我們就知道這個實例就是leader!就是這樣!
事實證明,上述工作運行地很不錯!如果leader節點要掛掉了,那么另一個就會自動選舉上。但這個過程會花上一點時間,要一分鐘左右。所以這個還是要權衡一下的。假如你的工作中不允許錯過任意一個job執行,那么這個選擇對你來說是不合適的。但在我們上述的例子中,中間有那么一分鐘job沒有被準確執行,對我們來說無傷大雅。所以我覺得這個方法十分簡單,而且當移植一個現有的包含調度jobs的應用程序的時候很有價值,因為調度jobs總有各種各樣很難提取的原因。
關于“如何實現分布式協調Kubernet”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。