運維冷思考:普通個體,能在多大程度上破壞系統(tǒng)?
事件背景
微盟是國內(nèi)移動互聯(lián)網(wǎng)營銷引領(lǐng)者,中國最大的微信公眾智能服務(wù)平臺,基于微信為企業(yè)提供開發(fā)、運營、培訓(xùn)、推廣一體化解決方案,幫助企業(yè)實現(xiàn)線上線下互通,社會化客戶關(guān)系管理,移動電商,輕應(yīng)用等。
2月23日19點,微盟出現(xiàn)了大規(guī)模系統(tǒng)故障,根據(jù)官方消息,這是一起運維部門核心員工在生產(chǎn)環(huán)境的“刪庫”操作引發(fā)的。截止發(fā)稿時,系統(tǒng)目前還處于修復(fù)階段,預(yù)計全部恢復(fù)將在2月28日晚上24點完成。在這期間,微盟啟動緊急響應(yīng)機(jī)制,并在騰訊云的大力支持下一起研究制定生產(chǎn)環(huán)境和數(shù)據(jù)修復(fù)方案。
歷史上類似的事件
說到“刪庫跑路”這檔子事,歷史上可以追溯到《西游記》,你是否還記得孫悟空大鬧地府,硬生生把閻王爺?shù)?ldquo;地獄數(shù)據(jù)庫”(Hell-DBMS),其實就是生死簿,改的面目全非的故事吧。
話說那孫猴子拿起大筆就把自己的名字,還有他的那些猴孫們的名字一起劃了,以此避免了生老病死的輪回。很顯然,這個地獄數(shù)據(jù)庫顯然是沒有做過任何備份,從頭到尾就那么一份,刪了之后就再也回不去了。當(dāng)然,這個只是我的一個玩笑,但是由此可見備份以及在系統(tǒng)故障情況下恢復(fù)能力的重要性。
IT歷史上此類事件其實不在少數(shù),2015年5月28日中午11時左右,攜程官網(wǎng)和APP同時崩潰,一時之間,攜程數(shù)據(jù)庫被物理刪除的說法在網(wǎng)上盛傳,直到深夜23:29,攜程才逐漸恢復(fù)。第二天,攜程發(fā)布官方解釋,稱是由于運維員工的錯誤操作,刪除了生產(chǎn)服務(wù)器上的執(zhí)行代碼導(dǎo)致,最終的詳細(xì)報告官方并沒有公布。
另一個著名的事件是2017年2月,Gitlab.com數(shù)據(jù)庫也出現(xiàn)了誤刪,當(dāng)時由于遭受DDoS攻擊造成staging 數(shù)據(jù)庫(db2.staging)落后生產(chǎn)數(shù)據(jù)庫(db1.cluster)4GB的數(shù)據(jù),并且staging 數(shù)據(jù)庫由于PostgreSQL的問題處于hang狀態(tài),在試圖修復(fù)這個問題的過程中造成了刪錯庫的誤操作,最終造成很多項目代碼不同程度的丟失。
之后,又陸陸續(xù)續(xù)發(fā)生了順豐,廣西移動等類似的事件。
微盟的危機(jī)應(yīng)對值得我們借鑒
面對微盟的這次刪庫事件,對很多行業(yè)用戶造成了很大的影響,但是面對危機(jī),微盟所表現(xiàn)出來的社會責(zé)任感是值得我們借鑒和學(xué)習(xí)的。面對突如其來的故障,微盟并沒有試圖掩蓋真相,而是第一時間在其官方發(fā)表聲明,解釋事情的背后原因,并且明確告知了后階段的恢復(fù)計劃已經(jīng)明確的時間節(jié)點。
要知道,微盟也是此次事件的最大受害者,在幕后,我們可以想象會有多少個我們運維人的不眠之夜。在這期間,騰訊云給予了極大的支持和幫助,派駐了很多一流的技術(shù)專家,不計成本來支持微盟和微盟的客戶。
多一些真誠,少一些套路,有問題一起扛,是面對此類危機(jī)最好的方法。如果你試圖掩蓋,蓋不住了就撒謊,接著就像張宇唱的那樣“用一個謊言圓一個謊言”,必然會讓自己陷入更深層次的危機(jī)。危機(jī)之下,我們要的是公開的信息,這樣才能減少公眾的猜測,抵制黑公關(guān),并獲得大家的理解和支持。
為什么恢復(fù)時間這么長
那接下來的問題就是,既然微盟已經(jīng)在全力搶修,同時騰訊云也給予了極大的技術(shù)協(xié)助,那全面恢復(fù)的時間為什么還要這么久呢?
圈子外的同學(xué)可能覺得這個不應(yīng)該很復(fù)雜,感覺不就是重裝一下系統(tǒng)嗎,數(shù)據(jù)庫不是都應(yīng)該有備份嗎,直接恢復(fù)一下不就行了嗎。其實事情遠(yuǎn)遠(yuǎn)要比你想的要復(fù)雜得多。很多時候,人常常會有一個認(rèn)知上的偏差,對于一個自己沒有切身參與過的領(lǐng)域,我們會不自覺地對難度產(chǎn)生錯誤的判斷。這種所謂的迷之自信,是很難克服的。
這樣的例子很多,比如在看球賽的時候,有人就恨不得把電視砸了,總覺得某些球員怎么這么挫,但是真要是輪到你上場,你就能比他好嗎。再比如蘭州拉面,看起來也沒什么難度嗎,來回幾下子面就拉出來了,但要是換你上,你能拉出那碗面嗎。
其實,熟悉現(xiàn)代軟件架構(gòu)和運維的同學(xué)一定知道,現(xiàn)在軟件的架構(gòu)以及部署是及其復(fù)雜的,尤其在微服務(wù)大行其道的今天,每個微服務(wù)本身一個集群,微服務(wù)和微服務(wù)之間還有各種依賴關(guān)系,同時每個微服務(wù)都有可能會和數(shù)據(jù)庫打交道,光理清楚這些服務(wù)之間的依賴和配置就夠大家受得了。更何況這次的微盟事件不是一次局部的更新和發(fā)布,而是幾乎整體架構(gòu)的全局梳理,從這個意義上說,難度不亞于從頭搭建整個系統(tǒng),更何況是在如此巨大的業(yè)務(wù)壓力和輿論壓力之下。
再來看看數(shù)據(jù)庫,根據(jù)目前官方的信息推測,這次的數(shù)據(jù)庫應(yīng)該是在生產(chǎn)環(huán)境的本地庫發(fā)生了不可逆的刪除,否則不可能會需要這么長的時間。假定本地生產(chǎn)庫沒了,那唯一的方法就是借助遠(yuǎn)程災(zāi)備的全量備份庫來恢復(fù),但這也會引發(fā)出一系列的問題,比如遠(yuǎn)程庫容量大,需要大量的網(wǎng)絡(luò)傳輸時間,再比如,增量備份的完整性欠缺,另外,還會出現(xiàn)由于近期的數(shù)據(jù)Scheme變更引發(fā)的備份數(shù)據(jù)兼容性問題等等。這些都需要研發(fā)人員和運維人員的共同推進(jìn),這就會需要更多的時間。
運維進(jìn)化的冷思考
通過這次的事件,站在運維的全局視角來看,對我們又有哪些啟發(fā)呢。這里我提出了4個問題作為我們討論的主線。
問題1:一個普通個體,能在多大程度上破壞系統(tǒng)?
先說我的觀點:在信息時代,一個普通人完全可以摧毀一個系統(tǒng)。是的,你沒有聽錯。這種事情在信息時代以前,是很難想象的。在人類歷史上,一個個體決定一個民族,一個朝代歷史走向的事情,也不是沒有發(fā)生過,但必須是那些位高權(quán)重的大人物,你有沒有聽過,兩個普通人聊著聊著,就把人類文明和外星文明都改寫的事吧。
聽起來很荒唐,但是這樣的事情就發(fā)生在了劉慈欣的《三體》小說中,地球人葉文潔和三體人1379都是各自世界中的小人物,葉文潔處于對人類的失望,1379處于對生活的失望,在雙方建立了聯(lián)系后改變了人類世界與三體世界在接下來幾百年中的命運。雖然這只是小說中所描繪的場景,但是所有的邏輯都是自洽的,就連霍金在接受采訪時也表達(dá)了相同的觀點。
回到運維和 DevOps,你有沒有發(fā)現(xiàn),現(xiàn)在很多互聯(lián)網(wǎng)產(chǎn)品運維人員的權(quán)限其實是很大的,有時候大到可以直接摧毀一個系統(tǒng),這種現(xiàn)象在一些B輪或者C輪的企業(yè)中尤為普遍,我們先不談運維人員是否會處于惡意故意破壞自己的系統(tǒng),但是忙著中出錯的概率還是不小的。Gitlab.com的刪庫其實就是運維人員的誤操作導(dǎo)致的,由于過多的終端窗口反復(fù)切換,導(dǎo)致原本應(yīng)該在staging上執(zhí)行的刪庫操作實際發(fā)生在了生產(chǎn)環(huán)境,最終釀成大禍。
所以,這個問題帶給我們的啟示是,要充分重視個人在系統(tǒng)中可能產(chǎn)生的作用,必須對個人的行為進(jìn)行嚴(yán)格的監(jiān)管,避免由個人引發(fā)的系統(tǒng)性故障。這也就是為什么大型企業(yè)都會建立比較完善的分級和分層發(fā)布流程,層層監(jiān)管和審批,避免個人單點故障的無限放大。當(dāng)然,這些監(jiān)管和審批必須要納入到由技術(shù)驅(qū)動的DevOps流水線中來完成,而不是靠傳統(tǒng)的領(lǐng)導(dǎo)簽字來完成。
問題2:“人肉運維”還有多大的生存空間?
首先解釋一下“人肉運維”,我認(rèn)為那些在生產(chǎn)環(huán)境中直接敲命令來完成的各種運維操作都屬于人肉運維的范疇。我記得左耳朵耗子就說過“一個公司的運維能力的強弱和你在生產(chǎn)環(huán)境敲命令的多少成正比”,運維能力越弱,在生產(chǎn)環(huán)境上直接執(zhí)行各種命令的頻次就越高,運維能力越強,人直接和生產(chǎn)環(huán)境打交道的機(jī)會就越少。
所有對生產(chǎn)環(huán)境的變更,無論是系統(tǒng)參數(shù)、安全策略、網(wǎng)絡(luò)配置、應(yīng)用參數(shù)、環(huán)境參數(shù)、文件更新、數(shù)據(jù)庫更新都應(yīng)該是通過DevOps的流水線走正式的發(fā)布上線流程,所有的操作必須是由腳本或者自動化代碼來完成,任何個人都不應(yīng)具有直接在生產(chǎn)環(huán)境上執(zhí)行命名操作的場景。這樣做的好處有一下幾點:
- 發(fā)布流程的詳細(xì)過程可以被記錄和回溯;
- 發(fā)布流程可以被重復(fù),避免操作步驟的遺漏或錯誤,保證集群中節(jié)點狀態(tài)的一致性,這點對于集群擴(kuò)容場景非常重要;
- 避免生產(chǎn)環(huán)境中有人為產(chǎn)生的隨機(jī)錯誤;
所以,這個問題的結(jié)論顯而易見,我們應(yīng)該盡可能避免任何形式的人肉運維,我們的行為準(zhǔn)則是“人管代碼,代碼管機(jī)器”,而不是“人直接管機(jī)器”。
問題3:運維已經(jīng)積累了大量實踐,為什么依舊舉步維艱?
隨著軟件架構(gòu)復(fù)雜性的不斷提升,運維的理念和技術(shù)手段也在一直都在不停的演進(jìn),從早期的運維,到現(xiàn)在的DevOps,再到日漸完善的AIOps,我們已經(jīng)積累了大量的經(jīng)驗和最佳實踐,但是為什么似乎我們運維人依舊感覺舉步維艱。
我認(rèn)為其中的原因有兩個,一個是現(xiàn)在軟件架構(gòu)的發(fā)展速度在某種程度上超越了運維自身的發(fā)展。你如果回頭看一下,運維的技術(shù)體系一直在進(jìn)步,各種CI/CD的工具鏈,容器技術(shù),自動化部署工具,系統(tǒng)監(jiān)控方案都在日趨成熟,我們的運維能力的確在不斷增強。但是,與此同時,運維的對象也隨之變得越來越復(fù)雜,無論是依賴關(guān)系,還是集群規(guī)模都比以往任何時候都復(fù)雜,可以說“水漲船高”是現(xiàn)代運維所面臨的主要矛盾。
另一個原因是,很多運維的最佳實踐在實際工作中被“教條化”了,沒有達(dá)到這些實踐設(shè)計的初衷。比如為了防止人為的出錯,在做一些關(guān)鍵操作的時候,我們往往會有Peer機(jī)制(兩個人配對相互檢查),也會有Checklist機(jī)制(自己檢查),但是在實際執(zhí)行過程中,往往是形式主義占了上風(fēng),這一點不用我解釋你也能心領(lǐng)神會,所以這些機(jī)制并沒有發(fā)揮出應(yīng)該有的效果。因此我的建議是把這類方法完整嵌入到流水線的執(zhí)行步驟中去,而不是靠人為的方式來實施。我常說一句話“凡是靠人完成的東西都是不靠譜的,要靠技術(shù)手段才靠譜”。
另外,還有一個我認(rèn)為不太好的實踐,在實際工作中為了引起運維工程師的注意,我們會把系統(tǒng)設(shè)計成“危機(jī)敏感型”的,也就是說有事沒事都輸出很多告警信息,或者很多一般的操作都讓你反復(fù)確認(rèn)是否要執(zhí)行。比如,你發(fā)起某個命令執(zhí)行某個操作,系統(tǒng)就會先給出告警,然后讓你再次輸入“Y”來確定是否繼續(xù)執(zhí)行,看起來這是一種風(fēng)險更低和更穩(wěn)妥的設(shè)計,但是實際上這會造成一定的困擾。
我們一定都聽過“狼來了”的故事,當(dāng)你每次都覺得這些信息是無關(guān)緊要的話,你就會下意識忽略這些信息,那么當(dāng)真的狼來的時候,你就慘了。這個問題在以前的波音飛機(jī)的設(shè)計上也遇到過,因此我的建議是只在那些最有必要的操作上才啟用這種雙重確認(rèn)的機(jī)制。
問題4:運維部門是成本中心嗎?
在很多人的眼中,運維部門都被歸在成本中心,簡單來講就是花錢的部門。運維是成本中心的宿命論對于運維的發(fā)展其實是很不利的。如果運維部門長期處于機(jī)械性的發(fā)布執(zhí)行和生產(chǎn)環(huán)境救火的狀態(tài),那么就會陷入無止境的惡性循環(huán)。
很多時候,我們總是解決了看得見的問題,但是看不見的問題往往會在看不見的地方聚集,這類問題一旦出現(xiàn)就都是大問題。所以我們需要轉(zhuǎn)變運維是成本中心的思維定式,讓運維的同學(xué)能夠更積極去思考和解決系統(tǒng)性的問題。
我們一直說有兩種類型的待辦事項,一種是既重要又緊急的事,也就是運維同學(xué)經(jīng)常面對的各種救火型任務(wù)(生產(chǎn)環(huán)境Bug fix、Hotfix發(fā)布等),另一種是非常重要但是不緊急的事,也就是我常說的未雨綢繆型任務(wù)(自動化運維、監(jiān)控數(shù)據(jù)分析統(tǒng)計、模型獲取與優(yōu)化等)。理想情況下,應(yīng)該將更多的時間放在未雨綢繆型任務(wù)上,而只將少量的時間放在救火型任務(wù)。當(dāng)把未雨綢繆型任務(wù)做好了,那么救火的概率就下降了。但是現(xiàn)實情況正好相反,運維同學(xué)天天忙于各種發(fā)布,各種線上救火,根本沒有精力去償還各個時期欠下的技術(shù)債,這種模式就難逃成本中心的宿命。
關(guān)于未雨綢繆型任務(wù),我還想多說兩點。
首先,運維部門有必要在平時定期開展一些故障演練的實踐,結(jié)合混沌工程(Chaos Engineering)的思想,來確保系統(tǒng)的魯棒性和可維護(hù)性,以此來應(yīng)對各類突如其來的“黑天鵝”事件。這里我想強調(diào)“紙上得來終覺淺,絕知此事要躬行”,只有在實際故障演練的過程中,我們才有可能得到很多一手的寶貴實戰(zhàn)經(jīng)驗,光靠想是不行的。
其次,對于日常運維中遇到的各類看得見的問題,不能只是關(guān)注表面上的解決,而是要有“刨根問底”的精神。這里我強烈推薦《豐田模式:精益制造的14項管理原則》一書中的方法:問N個為什么。
舉個書中的例子,“工廠地上發(fā)現(xiàn)一大片油漬。通常的處理方式就是先清理地上的油,最多再檢查一下,機(jī)器哪個部位漏油,換掉有問題的零件就好了。但是按照豐田的思路,會引導(dǎo)員工繼續(xù)追問:為什么地上會有油?因為機(jī)器漏油了。為什么機(jī)器會漏油?因為一個零件老化,磨損嚴(yán)重,導(dǎo)致漏油。為什么零件會磨損嚴(yán)重?因為質(zhì)量不好。
為什么要用質(zhì)量不好的零件?因為采購成本低。為什么要控制采購成本?因為節(jié)省短期成本,是采購部門的績效考核標(biāo)準(zhǔn)“。當(dāng)你連續(xù)問了N個為什么之后,漏油的根本原因才找到。所以對漏油事件的根本解決方案,其實是改變對采購部門的績效考核標(biāo)準(zhǔn),這樣才能防止以后發(fā)生類似問題。
對于日常的運維工作也是如此,只有這樣才能發(fā)現(xiàn)和定位那些未雨綢繆型的任務(wù)。
好了,我的分享就到這里。困難的路越走越簡單,簡單的路越走越困難,祝好運!
作者簡介:
茹炳晟,業(yè)界知名實戰(zhàn)派軟件質(zhì)量和研發(fā)工程效能專家,中國商業(yè)聯(lián)合會互聯(lián)網(wǎng)應(yīng)用技術(shù)委員會智庫專家,暢銷書《測試工程師全棧技術(shù)進(jìn)階與實踐》的作者。
現(xiàn)任Dell EMC中國研發(fā)集團(tuán)資深架構(gòu)師,歷任eBay中國研發(fā)中心測試基礎(chǔ)架構(gòu)技術(shù)負(fù)責(zé)人,HP軟件中國研發(fā)中心資深架構(gòu)師、性能測試專家,Alcatel-Lucent高級技術(shù)主管,Cisco中國研發(fā)中心資深工程師等職位,具有超過16年的軟件研發(fā)經(jīng)驗和技術(shù)管理經(jīng)驗。