使用Nomad构建弹性基础架构:重新启动任务
Nomad是一個(gè)功能強(qiáng)大、靈活的調(diào)度器,適用于長(zhǎng)期運(yùn)行的服務(wù)和批處理任務(wù)。通過(guò)廣泛的驅(qū)動(dòng)程序,Nomad可以調(diào)度基于容器的工作負(fù)載、原始二進(jìn)制文件、java應(yīng)用程序等等。Nomad操作簡(jiǎn)單,易伸縮,與HashiCorp Consul(服務(wù)注冊(cè)),Vault(證書管理)產(chǎn)品無(wú)縫集成。
Nomad為開發(fā)人員提供了自助服務(wù)基礎(chǔ)設(shè)施。Nomad任務(wù)使用高級(jí)聲明格式語(yǔ)法進(jìn)行描述,該語(yǔ)法是版本控制的,并將基礎(chǔ)結(jié)構(gòu)作為代碼進(jìn)行推廣。一旦任務(wù)提交給Nomad,它就負(fù)責(zé)部署和確保服務(wù)的可用性。運(yùn)行Nomad的好處之一是提高了計(jì)算基礎(chǔ)設(shè)施的可靠性和彈性。
歡迎來(lái)到我們關(guān)于用Nomad構(gòu)建彈性基礎(chǔ)設(shè)施的系列文章,在這里我們將探討Nomad如何處理意外故障、停機(jī)和集群基礎(chǔ)設(shè)施的日常維護(hù),通常不需要操作員干預(yù)。
在第一篇文章中,我們將了解Nomad如何自動(dòng)重啟失敗和無(wú)響應(yīng)的任務(wù),以及如何將反復(fù)失敗的任務(wù)重新調(diào)度到其他節(jié)點(diǎn)。
Tasks and job 聲明
一個(gè)Nomad task是由其驅(qū)動(dòng)程序在Nomad客戶端節(jié)點(diǎn)上執(zhí)行的命令、服務(wù)、應(yīng)用程序或其他工作負(fù)載。task可以是短時(shí)間的批處理作業(yè)(batch)或長(zhǎng)時(shí)間運(yùn)行的服務(wù)(service),例如web應(yīng)用程序、數(shù)據(jù)庫(kù)服務(wù)器或API。
Tasks是在用HCL語(yǔ)法的聲明性job規(guī)范中定義的。Job文件提交給Nomad服務(wù)端,服務(wù)端決定在何處以及如何將job文件中定義的task分配給客戶端節(jié)點(diǎn)。另一種概念化的理解是:job規(guī)范表示工作負(fù)載的期望狀態(tài),Nomad服務(wù)端創(chuàng)建并維護(hù)其實(shí)際狀態(tài)。
job定義的層次是:job→group→task。每個(gè)job文件只有一個(gè)job,但是一個(gè)job可能有多個(gè)group,每個(gè)group可能有多個(gè)task。group包含一組要放在同一個(gè)節(jié)點(diǎn)上的task。
下面是一個(gè)定義Redis工作負(fù)載的簡(jiǎn)單job文件:
job "example" {datacenters = ["dc1"]type = "service"constraint {attribute = "${attr.kernel.name}"value = "linux"}group "cache" {count = 1task "redis" {driver = "docker"config {image = "redis:3.2"}resources {cpu = 500 # 500 MHzmemory = 256 # 256MB}}} }job作者可以為他們的工作負(fù)載定義約束和資源。約束(constraint)通過(guò)內(nèi)核類型和版本等屬性限制了工作負(fù)載在節(jié)點(diǎn)上的位置。資源(resources)需求包括運(yùn)行task所需的內(nèi)存、網(wǎng)絡(luò)、CPU等。
有三種類型的job:system、service和batch,它們決定Nomad將用于此job中task的調(diào)度器。service 調(diào)度器被設(shè)計(jì)用來(lái)調(diào)度永遠(yuǎn)不會(huì)宕機(jī)的長(zhǎng)壽命服務(wù)。batch作業(yè)對(duì)短期性能波動(dòng)的敏感性要小得多,壽命也很短,幾分鐘到幾天就可以完成。system調(diào)度器用于注冊(cè)應(yīng)該在滿足作業(yè)約束的所有客戶端上運(yùn)行的作業(yè)。當(dāng)某個(gè)客戶端加入到集群或轉(zhuǎn)換到就緒狀態(tài)時(shí)也會(huì)調(diào)用它。
Nomad允許job作者為自動(dòng)重新啟動(dòng)失敗和無(wú)響應(yīng)的任務(wù)指定策略,并自動(dòng)將失敗的任務(wù)重新調(diào)度到其他節(jié)點(diǎn),從而使任務(wù)工作負(fù)載具有彈性。
重啟失敗的任務(wù)
任務(wù)失敗可能發(fā)生在任務(wù)未能成功完成時(shí),例如批處理(batch)類型作業(yè)或服務(wù)(service)由于致命錯(cuò)誤或內(nèi)存耗盡而失敗。
Nomad將根據(jù)job文件的restart節(jié)中的指令在同一個(gè)節(jié)點(diǎn)上重啟失敗的任務(wù)。attempts指定允許重啟的次數(shù),delay指定Nomad在重啟任務(wù)之前應(yīng)該等待多長(zhǎng)時(shí)間,interval限制嘗試重新啟動(dòng)到間隔時(shí)間的時(shí)間量。使用(fail)模式指定在給定間隔內(nèi)的所有重啟嘗試都已耗盡之后,如果job沒(méi)有運(yùn)行,Nomad應(yīng)該做什么。
默認(rèn)的失敗模式是fail,它告訴Nomad不要嘗試重啟job。這是對(duì)非冪等job的推薦值,這些job在幾次失敗后不太可能成功。另一個(gè)選項(xiàng)是delay,告訴Nomad在重啟作業(yè)之前等待interval指定的時(shí)間。
下面的restart節(jié)告訴Nomad在30分鐘內(nèi)最多重啟2次,每次重啟之間延遲15秒,在2次重啟之后不要再嘗試重啟。這也是非批處理類型job的默認(rèn)重啟策略。
group "cache" {...restart {attempts = 2interval = "30m"delay = "15s"mode = "fail"}task "redis" {...} }這種本地重啟行為旨在使任務(wù)對(duì)bug、內(nèi)存泄漏和其他臨時(shí)問(wèn)題具有彈性。這類似于使用過(guò)程管理器,例如systemd、upstart或Nomad外部的runit。
重啟沒(méi)有響應(yīng)的任務(wù)
另一個(gè)常見(jiàn)的場(chǎng)景是需要重啟一個(gè)任務(wù),該任務(wù)還沒(méi)有失敗,但已經(jīng)變得沒(méi)有響應(yīng)或不健康。
Nomad將根據(jù)check_restart節(jié)中的指令重啟沒(méi)有響應(yīng)的任務(wù)。這將與Consul健康檢查功能結(jié)合。當(dāng)健康檢查失敗limit次時(shí),Nomad將重啟任務(wù)。limit值為1表示在第一次失敗時(shí)重啟。默認(rèn)值0則表示禁止基于健康檢查的重啟。
失敗必須是連續(xù)的。一次健康檢查將重置計(jì)數(shù),因此在passing狀態(tài)和失敗狀態(tài)之間交替進(jìn)行的服務(wù)可能不會(huì)重啟。使用grace指定重啟后恢復(fù)健康檢查的等待時(shí)間。設(shè)置 ignore_warnings = true 讓Nomad將警告狀態(tài)當(dāng)作一個(gè)passing狀態(tài),而不觸發(fā)重啟。
下面的check_restart策略告訴Nomad在其健康檢查連續(xù)失敗3次后重啟Redis任務(wù),在重啟任務(wù)后等待90秒以恢復(fù)健康檢查,并在警告狀態(tài)下重啟(除了失敗之外)。
task "redis" {...service {check_restart {limit = 3grace = "90s"ignore_warnings = false}} }在傳統(tǒng)的數(shù)據(jù)中心環(huán)境中,重啟失敗的任務(wù)通常由流程管理器(process supervisor)處理,該管理器需要由操作員配置。自動(dòng)檢測(cè)和重新啟動(dòng)不健康的任務(wù)更加復(fù)雜,需要定制腳本集成監(jiān)控系統(tǒng)或操作員干預(yù)。而對(duì)于Nomad,它們會(huì)自動(dòng)發(fā)生,不需要操作員干預(yù)。
重新調(diào)度失敗任務(wù)
在指定的重啟次數(shù)之后沒(méi)有成功運(yùn)行的任務(wù)可能會(huì)失敗,原因是它們運(yùn)行的節(jié)點(diǎn)出現(xiàn)了問(wèn)題,例如硬件故障、內(nèi)核死鎖或其他不可恢復(fù)的錯(cuò)誤。
使用reschedule節(jié),操作員告訴Nomad在什么情況下要將失敗的作業(yè)重新調(diào)度(reschedule)到另一個(gè)節(jié)點(diǎn)。
Nomad更喜歡重新調(diào)度到以前沒(méi)有用于此任務(wù)的節(jié)點(diǎn)。與restart節(jié)一樣,您可以使用attempts指定Nomad應(yīng)該嘗試的重新調(diào)度的次數(shù),delay指定Nomad應(yīng)該在重新調(diào)度嘗試之間等待多長(zhǎng)時(shí)間,interval指定重新調(diào)度嘗試限制的間隔時(shí)間。
另外,使用delay_function指定用于計(jì)算初始延遲后的后續(xù)重新調(diào)度嘗試的函數(shù)。選項(xiàng)有常數(shù)(constant)、指數(shù)(exponential)和斐波那契數(shù)(fibonacci)。對(duì)于service任務(wù),斐波那契調(diào)度具有快速重新調(diào)度的特性,它可以在短時(shí)間內(nèi)從中斷中恢復(fù),同時(shí)減慢速度以避免在較長(zhǎng)時(shí)間內(nèi)中斷時(shí)出現(xiàn)中斷。當(dāng)使用指數(shù)或斐波那契delay_function時(shí),使用max_delay設(shè)置延遲時(shí)間的上限,在此之后延遲時(shí)間不會(huì)增加。將unlimited設(shè)置為true或false以允許無(wú)限制的重新調(diào)度嘗試。
要完全禁用重新調(diào)度,設(shè)置?attempts = 0?和 unlimited = false。
下面的reschedule?節(jié)告訴Nomad嘗試重新調(diào)度任務(wù)組無(wú)限次,并在隨后的嘗試之間以指數(shù)級(jí)增加延遲,開始延遲30秒,最多1小時(shí)。
group "cache" { ... reschedule { delay = "30s" delay_function = "exponential" max_delay = "1hr" unlimited = true } }reschedule?節(jié)不適用于system作業(yè),因?yàn)樗鼈冊(cè)诿總€(gè)節(jié)點(diǎn)上都運(yùn)行。
從Nomad 0.8.4版本開始,reschedule?節(jié)在部署期間應(yīng)用。
在傳統(tǒng)的數(shù)據(jù)中心中,節(jié)點(diǎn)故障將由監(jiān)控系統(tǒng)檢測(cè)到,并觸發(fā)報(bào)警給操作員。然后操作人員需要手動(dòng)進(jìn)行干預(yù),要么恢復(fù)失敗的節(jié)點(diǎn),要么將工作負(fù)載遷移到另一個(gè)節(jié)點(diǎn)。有了重新調(diào)度功能,操作員可以為最常見(jiàn)的故障場(chǎng)景進(jìn)行規(guī)劃,Nomad將自動(dòng)響應(yīng),無(wú)需人工干預(yù)。Nomad應(yīng)用了合理的默認(rèn)值,這樣大多數(shù)用戶都可以在本地重新啟動(dòng)和重新調(diào)度,而不必考慮各種重啟參數(shù)。
總結(jié)
在我們用Nomad構(gòu)建彈性基礎(chǔ)架構(gòu)系列的第一篇文章中,我們介紹了Nomad如何通過(guò)自動(dòng)重新啟動(dòng)和重新調(diào)度失敗和無(wú)響應(yīng)的任務(wù),為計(jì)算基礎(chǔ)架構(gòu)提供彈性。
對(duì)于失敗的任務(wù),操作員使用restart節(jié)指定Nomad的本地重啟策略。當(dāng)與Consul和check_restart節(jié)一起使用時(shí),Nomad將根據(jù)重啟參數(shù)在本地重啟無(wú)響應(yīng)的任務(wù)。操作員通過(guò)reschedule 節(jié)指定Nomad重新調(diào)度失敗任務(wù)的策略。
在下一篇文章中,我們將討論Nomad客戶端如何通過(guò)驅(qū)動(dòng)健康檢查和活躍的心跳來(lái)實(shí)現(xiàn)快速、準(zhǔn)確的調(diào)度以及自我修復(fù)。
總結(jié)
以上是生活随笔為你收集整理的使用Nomad构建弹性基础架构:重新启动任务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: GO 语言websocket编程
- 下一篇: 使用Nomad构建弹性基础架构:计划和自