在分布式系統(tǒng)上管理服務(wù)是運(yùn)維團(tuán)隊(duì)面臨的最困難的問(wèn)題之一缀遍。在生產(chǎn)中突破新軟件并學(xué)習(xí)如何可靠地運(yùn)營(yíng)是非常重要的。本文是一則實(shí)例饱须,講述為什么學(xué)習(xí)運(yùn)營(yíng)Kubernetes很重要域醇,以及為什么很難。本文是關(guān)于Kubernetes bug導(dǎo)致的一小時(shí)中斷故障的事后剖析冤寿。
為什么選擇在Kubernetes之上構(gòu)建歹苦?如何將Kubernetes集成到現(xiàn)有基礎(chǔ)設(shè)施中青伤?本文作者給出的方法是建立 (和改進(jìn)) 對(duì)Kubernetes集群的可靠性的信任督怜,以及構(gòu)建在Kubernetes之上的抽象。
我們最近在Kubernetes之上構(gòu)建了一個(gè)分布式的cron作業(yè)調(diào)度系統(tǒng)狠角,這是一個(gè)令人興奮的容器編排的新平臺(tái)号杠。Kubernetes現(xiàn)在非常流行,并且有許多令人興奮的承諾:最令人興奮的是丰歌,程序員不需要知道或關(guān)心他們的應(yīng)用程序運(yùn)行的是什么機(jī)器姨蟋。
什么是Kubernetes?
Kubernetes是一個(gè)分布式系統(tǒng),用于調(diào)度程序在集群中運(yùn)行立帖。你可以告訴Kubernetes運(yùn)行一個(gè)程序的5個(gè)副本眼溶,它將在工作節(jié)點(diǎn)上動(dòng)態(tài)調(diào)度它們。容器自動(dòng)調(diào)度以增加利用率晓勇,節(jié)省資金堂飞,強(qiáng)大的deployment primitives允許逐步推出新的代碼,安全上下文和網(wǎng)絡(luò)策略允許企業(yè)以安全的方式運(yùn)行多租戶的工作負(fù)載绑咱。
Kubernetes有很多不同類型的調(diào)度能力绰筛。它可以調(diào)度長(zhǎng)時(shí)間運(yùn)行的HTTP服務(wù)、在集群中每臺(tái)機(jī)器上運(yùn)行的daemonsets描融、每小時(shí)運(yùn)行的cron作業(yè)等等铝噩。
為什么是Kubernetes?
每個(gè)基礎(chǔ)設(shè)施項(xiàng)目都是從業(yè)務(wù)需求開(kāi)始的,我們的目標(biāo)是提高現(xiàn)有分布式cron作業(yè)系統(tǒng)的可靠性和安全性窿克。我們的要求是:
建立和運(yùn)營(yíng)一支小團(tuán)隊(duì)(只有2人在項(xiàng)目中全職工作)骏庸。
在20臺(tái)機(jī)器上可靠地安排大約500個(gè)不同的cron作業(yè)毛甲。
我們決定在Kubernetes之上建立的幾個(gè)原因:
希望構(gòu)建一個(gè)現(xiàn)有的開(kāi)源項(xiàng)目。
kubernetes包含一個(gè)分布式cron作業(yè)調(diào)度器敞恋,不必自己編寫丽啡。
kubernetes是一個(gè)非常活躍的項(xiàng)目硬猫,經(jīng)常接受捐贈(zèng)补箍。
kubernetes是用Go寫的,很容易學(xué)啸蜜。幾乎所有Kubernetes的bug都是由團(tuán)隊(duì)中沒(méi)有經(jīng)驗(yàn)的程序員做的坑雅。
如果我們能夠成功地運(yùn)營(yíng)Kubernetes,可以在未來(lái)的Kubernetes上構(gòu)建衬横,例如裹粤,目前正在開(kāi)發(fā)基于kubernet的系統(tǒng)來(lái)訓(xùn)練機(jī)器學(xué)習(xí)模型。
我們以前使用Chronos作為cron作業(yè)調(diào)度系統(tǒng),但它不再是滿足可靠性要求,而且大部分都沒(méi)有維護(hù)(在過(guò)去9個(gè)月中1次提交, 最后一次合并請(qǐng)求的時(shí)間是2016年3月))Chronos未維護(hù)的,我們認(rèn)為不值得繼續(xù)投資改善現(xiàn)有的集群蜂林。
如果你正考慮Kubernetes遥诉,請(qǐng)記住:不要僅僅因?yàn)槠渌驹谑褂肒ubernetes而使用它。建立一個(gè)可靠的集群需要花費(fèi)大量的時(shí)間噪叙,使用它的業(yè)務(wù)案例并不是很突出矮锈。把你的時(shí)間用在聰明的方法上。
可靠性是什么意思?
說(shuō)到運(yùn)營(yíng)服務(wù)睁蕾,“可靠”這個(gè)詞本身并沒(méi)有什么意義苞笨。要討論可靠性,首先需要建立一個(gè)SLO(服務(wù)級(jí)別目標(biāo))子眶。
我們有三個(gè)主要目標(biāo):
99.99%的cron作業(yè)應(yīng)該在預(yù)定運(yùn)行時(shí)間的20分鐘內(nèi)開(kāi)始運(yùn)行瀑凝。20分鐘是一個(gè)很寬的窗口,但是我們采訪了內(nèi)部客戶臭杰,沒(méi)有人要求更高的精確度粤咪。
Jobs應(yīng)該運(yùn)行99.99%的時(shí)間(不被終止)。
向Kubernetes的遷移不會(huì)導(dǎo)致任何面向客戶的事件渴杆。
這意味著:
Kubernetes API的短暫停機(jī)時(shí)間是可以接受的(如果停機(jī)10分鐘寥枝,只要在5分鐘內(nèi)恢復(fù)即可)。
調(diào)度錯(cuò)誤(cron作業(yè)運(yùn)行完全丟失并且根本無(wú)法運(yùn)行)是不可接受的将塑。我們非常重視安排錯(cuò)誤報(bào)告脉顿。
要謹(jǐn)慎對(duì)待pod evictions 和安全終止實(shí)例,以免作業(yè)過(guò)于頻繁地終止点寥。
需要一個(gè)好的遷移計(jì)劃艾疟。
建立一個(gè)Kubernetes集群
我們建立第一個(gè)Kubernetes集群的基本方法是從零開(kāi)始構(gòu)建集群,而不是使用kubeadm或kops之類的工具。使用Puppet(常用的配置管理工具)調(diào)配了配置蔽莱。從頭開(kāi)始構(gòu)建很好弟疆,原因有兩個(gè):能夠深入地集成Kubernetes在架構(gòu)中,并且深入理解其內(nèi)部盗冷。
我們希望將Kubernetes整合到現(xiàn)有的基礎(chǔ)架構(gòu)中怠苔。與現(xiàn)有系統(tǒng)無(wú)縫集成,以便進(jìn)行日志記錄仪糖,證書管理柑司,加密,網(wǎng)絡(luò)安全锅劝,監(jiān)控攒驰,AWS實(shí)例管理,部署故爵,數(shù)據(jù)庫(kù)代理玻粪,內(nèi)部DNS服務(wù)器,配置管理以及更多诬垂。整合所有這些系統(tǒng)有時(shí)需要一點(diǎn)創(chuàng)造力劲室,但總體上比試圖讓kubeadm / kops成為我們想要的更容易。
在信任并了解如何操作這些現(xiàn)有系統(tǒng)后结窘,我們希望繼續(xù)在新的Kubernetes群集中使用很洋。例如,安全證書管理是一個(gè)非常棘手的問(wèn)題晦鞋,已經(jīng)有辦法頒發(fā)和管理證書蹲缠。通過(guò)適當(dāng)?shù)恼瞎卓耍覀儽苊饬藶镵ubernetes創(chuàng)建新的CA悠垛。
準(zhǔn)確了解設(shè)置的參數(shù)是如何影響Kubernetes設(shè)置的。例如娜谊,在配置用于身份驗(yàn)證的證書/CAs時(shí)确买,使用了超過(guò)12個(gè)參數(shù)。了解這些參數(shù)有助于在遇到身份驗(yàn)證問(wèn)題時(shí)更容易調(diào)試設(shè)置纱皆。
對(duì)Kubernetes建立信心
在Kubernetes之初湾趾,團(tuán)隊(duì)中沒(méi)有人使用過(guò)Kubernetes。如何從“沒(méi)有人用過(guò)Kubernetes”到“我們有信心在生產(chǎn)中運(yùn)行Kubernetes”?
戰(zhàn)略0:與其他公司交談
我們向其他公司詢問(wèn)了Kubernetes的經(jīng)歷派草。 他們都以不同的方式或在不同的環(huán)境中使用Kubernetes(運(yùn)行HTTP服務(wù)搀缠,裸機(jī),Google Kubernetes引擎等)近迁。
在談到Kubernetes這樣龐大而復(fù)雜的系統(tǒng)時(shí)艺普,重要的是認(rèn)真思考自己的用例,做自己的實(shí)驗(yàn),建立對(duì)自己環(huán)境的信心歧譬,并做出決定岸浑。 例如,你不該讀這篇博客文章并得出結(jié)論:“Stripe正在成功使用Kubernetes瑰步,所以它也適用于我們矢洲!”
以下是我們?cè)谂c幾家運(yùn)營(yíng)Kubernetes集群的公司溝通后后學(xué)到的:
優(yōu)先考慮企業(yè)etcd集群的可靠性(etcd是存儲(chǔ)所有Kubernetes集群狀態(tài)的地方)。
某些Kubernetes功能比其他功能更穩(wěn)定缩焦,因此請(qǐng)小心Alpha功能读虏。一些公司只有在穩(wěn)定后才能使用穩(wěn)定特性(例如,如果某個(gè)功能在1.8版本中保持穩(wěn)定袁滥,則在使用它之前會(huì)等待1.9或1.10)掘譬。
考慮使用托管的Kubernetes系統(tǒng),如GKE / AKS / EKS呻拌。從頭開(kāi)始建立高可用性Kubernetes系統(tǒng)是一項(xiàng)巨大的工作葱轩。 AWS在此項(xiàng)目中沒(méi)有托管的Kubernetes服務(wù),所以這不適合我們藐握。
注意由覆蓋網(wǎng)絡(luò)/軟件定義網(wǎng)絡(luò)引入的額外網(wǎng)絡(luò)延遲靴拱。
策略1:閱讀代碼。
我們計(jì)劃很大程度上依賴于Kubernetes的一個(gè)組件猾普,即cronjob控制器袜炕。這個(gè)組件當(dāng)時(shí)處于alpha階段,這讓我們有點(diǎn)擔(dān)心初家。我們?cè)谝粋€(gè)測(cè)試集群中嘗試了它偎窘,但是如何判斷它在生產(chǎn)中是否適合我們呢?
值得慶幸的是,所有cronjob控制器的核心功能只有400行Go溜在。通過(guò)源代碼快速讀取顯示:
cron作業(yè)控制器是一個(gè)無(wú)狀態(tài)的服務(wù)(與其他Kubernetes組件一樣陌知,除了etcd)。
每10秒鐘掖肋,這個(gè)控制器調(diào)用syncAll函數(shù):go wait.Until(jm.syncAll仆葡,10 * time.Second,stopCh)
syncAll函數(shù)從Kubernetes API中獲取所有cron作業(yè)志笼,遍歷該列表沿盅,確定下一步應(yīng)該運(yùn)行哪些作業(yè),然后啟動(dòng)這些作業(yè)纫溃。
核心邏輯似乎相對(duì)容易理解腰涧。更重要的是,如果在這個(gè)控制器中有一個(gè)bug紊浩,它可能是我們可以修復(fù)的東西窖铡。
策略2:做負(fù)載測(cè)試
在開(kāi)始認(rèn)真構(gòu)建集群之前揍很,我們做了一些負(fù)載測(cè)試。我們并不擔(dān)心Kubernetes集群能夠處理多少節(jié)點(diǎn)(計(jì)劃部署大約20個(gè)節(jié)點(diǎn))万伤,但是確實(shí)想讓某些Kubernetes能夠處理我們希望運(yùn)行的那么多的cron作業(yè)(大約每分鐘50個(gè))窒悔。
在一個(gè)3節(jié)點(diǎn)集群中運(yùn)行了測(cè)試,創(chuàng)建了1000個(gè)cron作業(yè)敌买,每個(gè)任務(wù)每分鐘運(yùn)行一次简珠。這些工作中的每一個(gè)都簡(jiǎn)單地運(yùn)行bash -c 'echo hello world'。我們選擇簡(jiǎn)單的作業(yè)虹钮,是因?yàn)橄M麥y(cè)試集群的調(diào)度和編排能力聋庵,而不是集群的總計(jì)算能力。
測(cè)試集群無(wú)法處理每分鐘1000個(gè)cron作業(yè)芙粱。每個(gè)節(jié)點(diǎn)每秒最多只能啟動(dòng)一個(gè)pod祭玉,而集群能夠每分鐘運(yùn)行200個(gè)cron作業(yè)。由于我們只希望每分鐘運(yùn)行大約50個(gè)cron作業(yè)春畔,所以我們認(rèn)為這些限制不是阻礙因素脱货。
策略3:優(yōu)先構(gòu)建和測(cè)試高可用性etcd集群。
在設(shè)置Kubernetes時(shí)律姨,最重要的事情之一就是運(yùn)行etcd振峻。Etcd是Kubernetes集群的核心,它是存儲(chǔ)集群中所有數(shù)據(jù)的地方择份。除了etcd之外扣孟,其他一切都是無(wú)狀態(tài)的。如果etcd沒(méi)有運(yùn)行荣赶,不能對(duì)Kubernetes集群進(jìn)行任何更改(盡管現(xiàn)有的服務(wù)將繼續(xù)運(yùn)行!)
這張圖顯示了etcd是Kubernetes集群的核心——API服務(wù)器是etcd前面的無(wú)狀態(tài)REST/認(rèn)證端點(diǎn)凤价,然后其他組件通過(guò)API服務(wù)器與etcd對(duì)話。 在運(yùn)行時(shí)拔创,有兩個(gè)要點(diǎn)需要牢記:
設(shè)置復(fù)制,這樣集群不會(huì)死如果你失去了一個(gè)節(jié)點(diǎn)利诺。我們現(xiàn)在有三個(gè)etcd副本。
確保足夠的I / O帶寬伏蚊。我們的etcd版本有一個(gè)問(wèn)題立轧,一個(gè)具有高fsync延遲的節(jié)點(diǎn)可能觸發(fā)連續(xù)的leader elections格粪,導(dǎo)致集群無(wú)法使用躏吊。通過(guò)確保所有節(jié)點(diǎn)的I/O帶寬都比etcd的寫入數(shù)量多,從而彌補(bǔ)了這一點(diǎn)帐萎。
設(shè)置復(fù)制不是一個(gè)設(shè)置-忘記操作比伏。我們仔細(xì)地測(cè)試后發(fā)現(xiàn)可能會(huì)丟失一個(gè)etcd節(jié)點(diǎn),并且集群優(yōu)雅地恢復(fù)了疆导。
以下是為建立etcd集群所做的一些工作:
設(shè)置復(fù)制
監(jiān)控etcd服務(wù)是可用的
寫一些簡(jiǎn)單的工具,以便輕松創(chuàng)建新的etcd節(jié)點(diǎn)赁项,并加入到集群當(dāng)中
編寫一些簡(jiǎn)單的工具,以便我們可以輕松創(chuàng)建新的etcd節(jié)點(diǎn)并將它們加入到群集中
補(bǔ)丁etcd的高集成,這樣我們可以在生產(chǎn)環(huán)境中運(yùn)行超過(guò)1個(gè) etcd集群
測(cè)試從一個(gè)etcd備份中恢復(fù)
測(cè)試可以在不停機(jī)情況下重建整個(gè)集群
很高興很早就做了這個(gè)測(cè)試。某個(gè)周五的早晨悠菜,在我們的生產(chǎn)集群中舰攒,一個(gè)etcd節(jié)點(diǎn)停止了對(duì)ping的響應(yīng)。我們得到了警報(bào)悔醋,終止了節(jié)點(diǎn)摩窃,帶來(lái)了一個(gè)新的節(jié)點(diǎn),加入到集群中芬骄,同時(shí)Kubernetes繼續(xù)運(yùn)行猾愿。
策略4:逐步將工作遷移到Kubernetes
我們的目標(biāo)之一是將工作遷移到Kubernetes而不造成任何中斷。成功進(jìn)行生產(chǎn)遷移的秘訣不是避免犯錯(cuò)(這是不可能的)账阻,而是設(shè)計(jì)你的遷移以減少錯(cuò)誤的影響蒂秘。
我們很幸運(yùn)有多種職位可以遷移到新集群,所以可以遷移一些低影響的工作崗位淘太,接受一兩次失敗姻僧。
在開(kāi)始遷移之前,構(gòu)建了易于使用的工具蒲牧,如果有必要段化,可以在不到五分鐘的時(shí)間內(nèi)在舊系統(tǒng)和新系統(tǒng)之間來(lái)回移動(dòng)作業(yè)。這種簡(jiǎn)單的工具減少了錯(cuò)誤的影響 - 如果遷移一個(gè)沒(méi)有計(jì)劃的依賴的工作造成,沒(méi)有什么大不了的显熏!可以將其移回原處,解決問(wèn)題晒屎,然后再試喘蟆。
以下是我們采用的整體遷移策略:
根據(jù)他們的重要程度大致排序
將一些重復(fù)的工作遷移到Kubernetes。如果發(fā)現(xiàn)新的情況鼓鲁,快速回滾蕴轨,修復(fù)問(wèn)題,然后重試骇吭。
策略5:調(diào)查 Kubernetes bug 并修復(fù)它們
我們?cè)陧?xiàng)目開(kāi)始時(shí)制定了一個(gè)規(guī)則:如果Kubernetes做了一些意外的事情橙弱,必須調(diào)查,找出原因燥狰,并提出補(bǔ)救措施棘脐。
調(diào)查每個(gè)問(wèn)題都很耗時(shí),但很重要龙致。如果只是簡(jiǎn)單地將Kubernetes的”古怪行為”看作是復(fù)雜的分布式系統(tǒng)的功能蛀缝,我們擔(dān)心,因?yàn)樗鼈儠?huì)被調(diào)用導(dǎo)致產(chǎn)生bug集群目代。
在使用了這種方法之后屈梁,我們發(fā)現(xiàn)并且修復(fù)了Kubernetes的幾個(gè)bug嗤练。
以下是測(cè)試中發(fā)現(xiàn)的一些問(wèn)題:
名稱超過(guò)52個(gè)字符的Cronjob無(wú)法安排作業(yè)。
Pods有時(shí)會(huì)永遠(yuǎn)停留在掛起狀態(tài)在讶。
調(diào)度程序會(huì)每3個(gè)小時(shí)崩潰一次煞抬。
Flannel的hostgw后端沒(méi)有替換過(guò)時(shí)的路由表項(xiàng)
修復(fù)這些bug讓我們對(duì)Kubernetes項(xiàng)目的使用感覺(jué)好得多——不僅它運(yùn)行得比較好,而且也接受補(bǔ)丁并有一個(gè)良好的PR審查過(guò)程构哺。
Kubernetes有bug此疹,像所有的軟件一樣。特別是遮婶,我們非常頻繁地使用調(diào)度器(cron作業(yè)總是在創(chuàng)建新的pods)蝗碎,而調(diào)度器使用緩存有時(shí)會(huì)導(dǎo)致bug、回退和崩潰旗扑。緩存是困難的!但是代碼庫(kù)是可接近的蹦骑,我們已經(jīng)能夠處理遇到的bug。
值得一提的是臀防,Kubernetes的pod驅(qū)逐邏輯眠菇。Kubernetes有一個(gè)稱為節(jié)點(diǎn)控制器的組件,它負(fù)責(zé)將pod驅(qū)逐出去袱衷,如果節(jié)點(diǎn)沒(méi)有響應(yīng)捎废,則將它們移到另一個(gè)節(jié)點(diǎn)。allnodes會(huì)暫時(shí)無(wú)響應(yīng)(例如致燥,由于網(wǎng)絡(luò)或配置問(wèn)題)登疗,在這種情況下,Kubernetes可以終止集群中的所有pod嫌蚤。
如果運(yùn)行的是大型Kubernetes集群辐益,請(qǐng)仔細(xì)閱讀節(jié)點(diǎn)控制器文檔,仔細(xì)地考慮設(shè)置脱吱,并進(jìn)行廣泛測(cè)試智政。每次通過(guò)創(chuàng)建網(wǎng)絡(luò)分區(qū)測(cè)試對(duì)這些設(shè)置的配置更改(例如,pod-驅(qū)逐超時(shí))箱蝠,就會(huì)發(fā)生令人驚訝的事情续捂。最好在測(cè)試中發(fā)現(xiàn)這些意外,而不是在生產(chǎn)中發(fā)現(xiàn)宦搬。
策略6:有意引起Kubernetes集群?jiǎn)栴}
之前討論過(guò)在Stripe中進(jìn)行游戲日練習(xí)牙瓢。這個(gè)想法是要想出你最終會(huì)在生產(chǎn)中發(fā)生的情況,然后在生產(chǎn)中故意造成這些情況床三,從而確保能夠處理它們一罩。
在集群上進(jìn)行了幾次練習(xí)之后,經(jīng)常發(fā)現(xiàn)諸如監(jiān)視或配置錯(cuò)誤等問(wèn)題撇簿。很高興在早期發(fā)現(xiàn)這些問(wèn)題聂渊,而不是六個(gè)月后突然發(fā)現(xiàn)。
以下是運(yùn)行的一些比賽日練習(xí):
終止Kubernetes API服務(wù)器
終止所有Kubernetes API服務(wù)器并將其恢復(fù)(這非常有效)
終止etcd節(jié)點(diǎn)
從API服務(wù)器中關(guān)閉Kubernetes集群中的工作節(jié)點(diǎn)(以便它們無(wú)法通信)四瘫。這導(dǎo)致節(jié)點(diǎn)上的所有pods被遷移到其他節(jié)點(diǎn)汉嗽。
很高興看到Kubernetes如何應(yīng)對(duì)我們投入的大量干擾。 Kubernetes的設(shè)計(jì)是為了適應(yīng)錯(cuò)誤 - 它有存儲(chǔ)所有狀態(tài)的etcd集群找蜜,一個(gè)只是該數(shù)據(jù)庫(kù)的REST接口的API服務(wù)器饼暑,以及一個(gè)協(xié)調(diào)所有集群管理的無(wú)狀態(tài)控制器集合。
如果任何Kubernetes核心組件(API服務(wù)器洗做,控制器管理器或調(diào)度程序)被中斷或重新啟動(dòng)弓叛,一旦它們出現(xiàn),它們將從etcd讀取相關(guān)狀態(tài)并繼續(xù)無(wú)縫運(yùn)行诚纸。這是我們希望的事情之一撰筷,而且在實(shí)踐中實(shí)際運(yùn)作良好。
以下是測(cè)試中發(fā)現(xiàn)的一些問(wèn)題:
“沒(méi)有得到paged畦徘,來(lái)修復(fù)監(jiān)控毕籽。“
“當(dāng)銷毀API服務(wù)器實(shí)例并將其恢復(fù)后井辆,需要人工干預(yù)关筒。最好解決這個(gè)問(wèn)題”保“
“有時(shí)執(zhí)行etcd故障轉(zhuǎn)移時(shí)蒸播,API服務(wù)器會(huì)啟動(dòng)超時(shí)請(qǐng)求,直至重新啟動(dòng)萍肆×猓”
在運(yùn)行這些測(cè)試后,針對(duì)發(fā)現(xiàn)的問(wèn)題開(kāi)發(fā)了補(bǔ)救措施:改進(jìn)了監(jiān)控匾鸥,發(fā)現(xiàn)了固定配置問(wèn)題蜡塌,并提交了Kubernetes bug。
使cron作業(yè)易于使用
簡(jiǎn)單地探討一下我們是如何使基于kubernetes的系統(tǒng)易于使用的勿负。
最初的目標(biāo)是設(shè)計(jì)一個(gè)運(yùn)行cron作業(yè)的系統(tǒng)馏艾,團(tuán)隊(duì)有信心運(yùn)營(yíng)和維護(hù)。一旦建立了對(duì)Kubernetes的信心奴愉,就需要工程師們輕松地配置和增加新的cron作業(yè)琅摩。我們開(kāi)發(fā)了一個(gè)簡(jiǎn)單的YAML配置格式,這樣用戶就不需要了解Kubernetes的內(nèi)部結(jié)構(gòu)來(lái)使用這個(gè)系統(tǒng)锭硼。這是我們開(kāi)發(fā)的格式:
name: job-name-here
kubernetes:
schedule: '15 */2 * * *'
command:
ruby
"/path/to/script.rb"
resources:
requests:
cpu: 0.1
memory: 128M
limits:
memory: 1024M
沒(méi)有做什么特別的事情——我們編寫了一個(gè)簡(jiǎn)單的程序房资,將這種格式轉(zhuǎn)換為Kubernetes cron作業(yè)配置,將其應(yīng)用于kubectl檀头。
我們還編寫了一個(gè)測(cè)試套件轰异,以確保作業(yè)名稱不會(huì)太長(zhǎng)岖沛,并且所有名稱都是惟一的。我們目前不使用cgroups來(lái)強(qiáng)化對(duì)大多數(shù)作業(yè)的內(nèi)存限制搭独,但計(jì)劃將來(lái)推出婴削。
我們的簡(jiǎn)單格式易于使用,而且由于自動(dòng)生成了來(lái)自相同格式的Chronos和Kubernetes cron作業(yè)定義牙肝,所以在兩個(gè)系統(tǒng)之間遷移作業(yè)非常簡(jiǎn)單唉俗。這是使我們的增量遷移工作良好的關(guān)鍵部分。將作業(yè)遷移到Kubernetes時(shí)配椭,可以用一個(gè)簡(jiǎn)單的三行配置更改虫溜,在不到十分鐘的時(shí)間內(nèi)將其移回。
監(jiān)控Kubernetes
監(jiān)測(cè)Kubernetes集群的內(nèi)部狀態(tài)非常令人愉悅股缸。我們使用kube-state-metrics軟件包進(jìn)行監(jiān)測(cè)衡楞,并使用一個(gè)名為veneurl - Prometheus的小型Go程序來(lái)獲取Prometheus的度量標(biāo)準(zhǔn),將它們作為statsd指標(biāo)發(fā)布到我們的監(jiān)控系統(tǒng)中乓序。
例如寺酪,以下是過(guò)去一小時(shí)內(nèi)集群中未決Pod的數(shù)量圖表。Pending意味著等待分配一個(gè)工作節(jié)點(diǎn)來(lái)運(yùn)行替劈〖娜福可以看到上午11點(diǎn)的數(shù)字峰值,很多cron作業(yè)在每小時(shí)的第0分鐘運(yùn)行陨献。
還有一個(gè)監(jiān)視器盒犹,用于檢查有沒(méi)有任何Pod在Pending狀態(tài)中卡住 - 每個(gè)Pod在5分鐘內(nèi)開(kāi)始在worker節(jié)點(diǎn)上運(yùn)行,否則會(huì)收到警報(bào)眨业。
Kubernetes未來(lái)計(jì)劃
設(shè)置Kubernetes急膀,到順暢地運(yùn)行生產(chǎn)代碼并將所有cron作業(yè)遷移到新集群,花了五個(gè)月的時(shí)間龄捡,三位工程師全職工作卓嫂。我們投資學(xué)習(xí)Kubernetes的一個(gè)重要原因是希望能夠在Stripe中更廣泛地使用Kubernetes。
以下是適用于運(yùn)行Kubernetes(或任何其他復(fù)雜分布式系統(tǒng))的原則:
為企業(yè)的Kubernetes項(xiàng)目聘殖,以及所有基礎(chǔ)設(shè)施項(xiàng)目晨雳,定義清晰的商業(yè)原因。了解業(yè)務(wù)案例和用戶的需求使項(xiàng)目變得更加容易奸腺。
積極削減范圍餐禁。避免使用許多Kubernetes的基本特性來(lái)簡(jiǎn)化集群。這讓我們可以更快速地發(fā)送消息突照,例如帮非,由于pod-to-pod聯(lián)網(wǎng)不是我們項(xiàng)目的必需條件,可以關(guān)閉節(jié)點(diǎn)之間的所有網(wǎng)絡(luò)連接,并將Kubernetes的網(wǎng)絡(luò)安全性推遲末盔。
花大量時(shí)間學(xué)習(xí)如何正確地運(yùn)營(yíng)Kubernetes集群筑舅。仔細(xì)測(cè)試邊界情況。分布式系統(tǒng)非常復(fù)雜庄岖,有很多潛在的問(wèn)題豁翎。以前面的例子為例:如果節(jié)點(diǎn)控制器由于配置與API服務(wù)器失去聯(lián)系角骤,那么它可以殺死集群中的所有pods隅忿。學(xué)習(xí)Kubernetes在每次配置更改后的表現(xiàn)如何,需要時(shí)間和精心的關(guān)注邦尊。
通過(guò)專注于這些原則背桐,我們已經(jīng)有信心在生產(chǎn)中使用Kubernetes。我們將繼續(xù)開(kāi)發(fā)Kubernetes的使用蝉揍,例如链峭,我們正在關(guān)注AWS EKS的發(fā)布。我們正在完成另一個(gè)系統(tǒng)的工作又沾,訓(xùn)練機(jī)器學(xué)習(xí)模型弊仪,并且正在探索將一些HTTP服務(wù)遷移到Kubernetes。隨著我們繼續(xù)在生產(chǎn)中運(yùn)行Kubernetes時(shí)杖刷,我們計(jì)劃對(duì)開(kāi)源項(xiàng)目做出貢獻(xiàn)励饵。
原文作者:Julia Evans
原文鏈接: