2018-11-20

使用Kubernetes和Docker進(jìn)行簡(jiǎn)單的leader選舉


Kubernetes簡(jiǎn)化了運(yùn)行在集群中的服務(wù)部署和運(yùn)維管理岛蚤,然而,它也簡(jiǎn)化了這些管理工作的部署。本篇文章將會(huì)展示如何在分布式應(yīng)用系統(tǒng)中使用Kubernetes來簡(jiǎn)單地運(yùn)行l(wèi)eader選舉。

概述

為了可靠性和伸縮性择同,分布式系統(tǒng)通常會(huì)復(fù)制多個(gè)服務(wù)任務(wù),但往往有必要指定一個(gè)副本作為leader負(fù)責(zé)協(xié)調(diào)所有的副本戈盈。

通常在leader選舉中奠衔,一組有機(jī)會(huì)成為leader的候選者都是可以確認(rèn)的。這些候選者都競(jìng)相宣布自己是leader塘娶,其中會(huì)有一個(gè)候選者脫穎而出成為leader归斤。一旦贏了選舉之后,leader將會(huì)繼續(xù)以leader身份發(fā)送“心跳”來更新他們的位置刁岸。而其它的候選者將會(huì)周期性地作出嘗試來成為leader脏里,這套機(jī)制確保了如果當(dāng)前的leader由于某些原因失效了,可以快速指定新的leader虹曙。

leader選舉的實(shí)現(xiàn)通常需要任一一套分布式協(xié)調(diào)系統(tǒng)比如ZooKeeper迫横、etcd或者Consul,使用它們來取得共識(shí)酝碳,或者交替實(shí)現(xiàn)自己的共識(shí)算法矾踱。接下來我們將會(huì)看到Kubernetes如何使得在應(yīng)用中進(jìn)行l(wèi)eader選舉明顯更容易。

Kubernetes中l(wèi)eader選舉的實(shí)現(xiàn)

leader選舉的第一個(gè)要求是對(duì)于有意成為leader的一組候選者的規(guī)范疏哗,Kubernetes已經(jīng)使用了Endpoints來表示一組包含服務(wù)的Pods副本呛讲,所以我們將重用這個(gè)相同的對(duì)象(旁白:你可能會(huì)認(rèn)為我們將使用ReplicationControllers,但它們被綁定到一個(gè)特定的二進(jìn)制軟件包,即使在執(zhí)行滾動(dòng)更新的過程中也通常需要一個(gè)leader)贝搁。

執(zhí)行l(wèi)eader選舉將使用Kubernetes API中的兩個(gè)屬性:

ResourceVersions——每個(gè)API都有一個(gè)唯一的ResourceVersions吗氏,用戶可以使用這些版本在Kubernetes對(duì)象上執(zhí)行Compare-and-Swap操作。

Annotations——每個(gè)API都可以被用于客戶端的任意鍵/值對(duì)注解雷逆。

鑒于這些原語(yǔ)弦讽,使用選主的代碼相對(duì)簡(jiǎn)單,可以在這兒找到相關(guān)代碼膀哲,運(yùn)行如下:

$ kubectl run leader-elector --image=gcr.io/google_containers/leader-elector:0.4 --replicas=3 -- --election=example

這將會(huì)創(chuàng)建一個(gè)有三個(gè)副本的leader選舉組:

$ kubectl get pods

NAME?????????READY??STATUS?RESTARTS?AGE

leader-elector-inmr1?1/1???Running?0????13s

leader-elector-qkq00?1/1???Running?0????13s

leader-elector-sgwcq?1/1???Running?0????13s

為了查看哪一個(gè)Pod被選為了leader往产,用戶可以訪問Pods的日志,在下面的位置替換為你自己的Pod的名字:

${pod_name}, (e.g. leader-elector-inmr1 from the above)

$ kubectl logs -f ${name}

leader is (leader-pod-name)

或者某宪,用戶可以直接檢查Endpoints對(duì)象:

# ‘example’ is the name of the candidate set from the above kubectl run … command

$ kubectl get endpoints example -o yams

現(xiàn)在需要驗(yàn)證leader選舉是否生效捂齐,在另外一個(gè)終端中執(zhí)行:

$ kubectl delete pods (leader-pod-name)

這個(gè)命令將會(huì)刪除已有的leader,因?yàn)镽eplication Controller管理Pods組缩抡,一個(gè)新的Pod將會(huì)替換掉已經(jīng)刪除的,從而確保副本數(shù)目仍然為3包颁。通過leader選舉瞻想,這三個(gè)Pod中將會(huì)有一個(gè)被選為leader,并且leader角色還會(huì)失效轉(zhuǎn)移到不同的Pod上娩嚼。因?yàn)镵ubernetes框架中Pod在終止前會(huì)有一個(gè)寬限期蘑险,通常是持續(xù)30~40秒。

leader選舉容器提供了一個(gè)簡(jiǎn)單的Web服務(wù)器岳悟,可以運(yùn)行在任何地址上(比如http://localhost:4040)佃迄,我們可以通過刪除一個(gè)已有的leader選舉組并創(chuàng)建一個(gè)新的來測(cè)試這個(gè)容器,此處可以另外傳入一個(gè)形如-http=(host):(port) 規(guī)格的配置到鏡像中贵少,這樣就會(huì)導(dǎo)致每一個(gè)組成員通過Webhook來獲得有關(guān)leader的服務(wù)信息呵俏。

# delete the old leader elector group

$ kubectl delete rc leader-elector

# create the new group, note the --http=localhost:4040 flag

$ kubectl run leader-elector --image=gcr.io/google_containers/leader-elector:0.4 --replicas=3 -- --election=example --http=0.0.0.0:4040

# create a proxy to your Kubernetes api server

$ kubectl proxy

接著可以訪問:

http://localhost:8001/api/v1/proxy/namespaces/default/pods/(leader-pod-name):4040/

然后就會(huì)看到:

{"name":"(name-of-leader-here)"}

leader選舉與sidecars

太好了,現(xiàn)在可以通過HTTP來進(jìn)行l(wèi)eader選舉和找出leader滔灶,但怎么能在您自己的應(yīng)用程序中使用它們呢普碎?這就需要引入Sidecars的概念。在Kubernetes中录平,Pods由一個(gè)或者多個(gè)容器組成麻车,通常,這意味著添加sidecars容器到主應(yīng)用程序中組成一個(gè)Pod(對(duì)于這個(gè)主題的更詳細(xì)的處理斗这,請(qǐng)看我以前的博客文章)动猬。

leader選舉容器可以作為一個(gè)Sidecars來從自己的應(yīng)用中使用,Pod中的任何容器對(duì)誰(shuí)是當(dāng)前的選主感興趣的都可以簡(jiǎn)單地通過http://localhost:4040 來訪問表箭,然后返回一個(gè)簡(jiǎn)單的JSON對(duì)象赁咙,其中包含了當(dāng)前選主的名字。既然Pod中的所有容器共享了相同的網(wǎng)絡(luò)命名空間,就不再需要服務(wù)發(fā)現(xiàn)了序目!

舉個(gè)例子臂痕,有一個(gè)簡(jiǎn)單的Node.js應(yīng)用程序連接到leader選舉Sidecar,然后打印出這個(gè)是否是當(dāng)前的選主猿涨,領(lǐng)導(dǎo)人選舉Sidecar將其標(biāo)識(shí)符設(shè)置為默認(rèn)的主機(jī)名握童。

var http = require('http');

// This will hold info about the current master

var master = {};

// The web handler for our nodejs application

var handleRequest = function(request, response) {

response.writeHead(200);

response.end("Master is " + master.name);

};

// A callback that is used for our outgoing client requests to the sidecar

var cb = function(response) {

var data = '';

response.on('data', function(piece) { data = data + piece; });

response.on('end', function() { master = JSON.parse(data); });

};

// Make an async request to the sidecar at http://localhost:4040

var updateMaster = function() {

var req = http.get({host: 'localhost', path: '/', port: 4040}, cb);

req.on('error', function(e) { console.log('problem with request: ' + e.message); });

req.end();

};

// Set up regular updates

updateMaster();

setInterval(updateMaster, 5000);

// set up the web server

var www = http.createServer(handleRequest);

www.listen(8080);

當(dāng)然,可以使用任何語(yǔ)言叛赚,選擇支持HTTP和JSON來使用這個(gè)Sidecar澡绩。

總結(jié)

希望我已經(jīng)向你展示了是多么容易為分布式應(yīng)用程序使用Kubernetes來構(gòu)建leader選舉。在以后的部分我們將向您展示Kubernetes是如何使得構(gòu)建分布式系統(tǒng)更容易俺附。與此同時(shí)肥卡,還前往Google容器引擎或kubernetes.io來開始使用Kubernetes。

本文翻譯:胡震

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末事镣,一起剝皮案震驚了整個(gè)濱河市步鉴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌璃哟,老刑警劉巖氛琢,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異随闪,居然都是意外死亡阳似,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門铐伴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撮奏,“玉大人,你說我怎么就攤上這事当宴⌒蟮酰” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵户矢,是天一觀的道長(zhǎng)定拟。 經(jīng)常有香客問我,道長(zhǎng)逗嫡,這世上最難降的妖魔是什么青自? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮驱证,結(jié)果婚禮上延窜,老公的妹妹穿的比我還像新娘。我一直安慰自己抹锄,他們只是感情好逆瑞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布荠藤。 她就那樣靜靜地躺著,像睡著了一般获高。 火紅的嫁衣襯著肌膚如雪哈肖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天念秧,我揣著相機(jī)與錄音淤井,去河邊找鬼。 笑死摊趾,一個(gè)胖子當(dāng)著我的面吹牛币狠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砾层,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼漩绵,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了肛炮?” 一聲冷哼從身側(cè)響起止吐,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侨糟,沒想到半個(gè)月后祟印,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粟害,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颤芬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悲幅。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖站蝠,靈堂內(nèi)的尸體忽然破棺而出汰具,到底是詐尸還是另有隱情,我是刑警寧澤菱魔,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布留荔,位于F島的核電站,受9級(jí)特大地震影響澜倦,放射性物質(zhì)發(fā)生泄漏聚蝶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一藻治、第九天 我趴在偏房一處隱蔽的房頂上張望碘勉。 院中可真熱鬧,春花似錦桩卵、人聲如沸验靡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胜嗓。三九已至高职,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辞州,已是汗流浹背怔锌。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留孙技,地道東北人产禾。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像牵啦,于是被迫代替她去往敵國(guó)和親亚情。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 她喜歡他,這在中文系是眾所周知的事裳瘪。 只是土浸,他有女朋友,這也是眾所周知的事彭羹。他是她的學(xué)長(zhǎng)黄伊,是校學(xué)生會(huì)的主席,品學(xué)兼...
    陶小小閱讀 226評(píng)論 0 2
  • 【日精進(jìn)打卡第0024天(8月18日):感恩】 張潁濤~同心校區(qū) 【知~學(xué)習(xí):名句分享——魚知水恩派殷,乃幸福之源也还最。...
    櫻桃_2fc4閱讀 114評(píng)論 0 0
  • 網(wǎng)友總結(jié)那些讓人崩潰的瞬間 真的一個(gè)都不想經(jīng)歷 ?歡迎關(guān)注微信公眾號(hào):搞笑有嘻哈
    搞笑有嘻哈閱讀 661評(píng)論 0 0
  • 貧窮還限制了你孩子的想象力 原創(chuàng):猛犸科學(xué)小怪獸今天 科學(xué)小怪獸拓轻,每天教你,給孩子講一個(gè)有趣科學(xué)故事 “115年之...
    科學(xué)小怪獸閱讀 103評(píng)論 0 0
  • 思鄉(xiāng)常夢(mèng)雁徘徊经伙,不見南邦雁北催扶叉。 潤(rùn)雨妝成春色樹,櫛風(fēng)綴就夜光杯帕膜。 易書迢遞邀新客枣氧,難越關(guān)山飲舊醅。 我自屏前遙問...
    周延龍閱讀 235評(píng)論 1 4