原雲生時代下,自動化運維指令碼真的沒前途了嗎

Linksla發表於2022-09-16
無論 K8s 這些如何鼓吹,自動化運維指令碼都無可避免。然而大家都不喜歡寫他們:
  • 職業上沒有安全感:運維代表了薪水低,大家都不喜歡說自己是做運維的。後端程式設計師尤其不喜歡墜落到運維崗位。指令碼代表了不正規,不是正兒八經的語言。這就體現為了“我要寫 golang”,和 PHP 程式設計師喜歡轉 golang 一樣。

  • 技術上不先進:指令碼能有什麼前途?未來不是屬於 Kubernetes 的麼?先進的技術應該解決什麼樣的問題?應該如何解決問題?

都是寫業務的,誰也不要瞧不起誰

我在騰訊遊戲做過兩年運維開發,做過遊戲大區的開區指令碼,合併大區的指令碼,故障之後自動申請機器替換修復的指令碼等等。當時我就在想,這個算做遊戲開發麼。這個和寫遊戲後臺的服務的區別是什麼?
最近一年在寫微信小程式。發現在微信生態下有很多業務程式碼是分不清楚是傳統的後臺開發,還是運維自動化的。比如說你要提供一個一鍵申請微信小程式的業務功能,這個裡面就涉及到給微信第三方平臺上傳程式碼,提交稽核,稽核透過之後觸發部署等工作。從業務上這是一個面向使用者的功能按鈕,但是性質上更接近於傳統運維的自動化工作。
一般人們是以是否啟動了新程式,部署了新程式碼,來區分這是一段後臺程式碼,還是運維指令碼。
另外一個說法是在網路路由領域,有 control plane v.s. data plane 的區分。似乎運維指令碼更接近 control plane 的工作。data plane 的高併發顯然更 hard-core 呀。
我覺得無論是讓介面弄得更美觀,還是處理資料庫操作的冪等,還是部署新程式。這些工作都是一個系統的業務,不要瞧不起誰。都是用程式碼來操作計算機,都是程式設計。當年大家都還瞧不起切圖仔呢,說不好熟悉哪個語言,哪套 API 就一定沒前途,或者有前途。真正的工程師只應關注問題是不是業務上高優先順序的,問題解決的方式是否恰當,是否高效。只有這樣才不會被人以是否熟悉 java/golang 去評判自己值多少錢。

隨意能部署一套是註定無法穩定的

部署的目的就是“複製一套環境”。這個包括了

  • 我給客戶1部署一套,給客戶2部署一套
  • 我在廣州部署一套,在美國部署一套
  • 我給開發環境部署一套,給生產環境部署一套

既要保證一致性,又要能相容差異性的需求。當然主要的訴求,還是要保證像一個模子出來的。常見的技術包括:

  • 運維指令碼修改已有的軟硬體配置

  • 維護一套映象的狀態,例如狀態資料庫,CMDB 這些

  • Infrastructure as Code,簡稱 IaC。 主要是要用 git 倉庫把散落的運維指令碼管理起來

  • Immutable server / infrastructure,透過縮短一個 state 的生命週期,來避免 state drift。 主要體現為每次都申請一個新的虛擬機器來部署

  • 映象狀態 + IaC + Immutable: 面向 YAML 開發,Kubernetes 這樣的模型

我曾經嘗試過很多種方案,目前我傾向於認為:無論用什麼先進技術,都無法做到隨意能部署一套新的環境。不要迷信 Kubernetes,也不要鄙視運維指令碼。

  • Immutable 是個假象: 不是所有的 state 都可以很廉價地變成 immutable 的。比如資料庫,比如 s3 的 bucket。我們都無法每次申請一個虛擬機器那樣,從零開始。絕大多數部署要用的 api,都是 mutable 風格的。Immutable 是建立在 mutable api 上的假象
  • All abstraction leaks: 所有的抽象在故障的時候都會洩露。YAML 再漂亮。當 YAML apply 的時候報錯了,仍然是需要知道里面的每個 resource 代表了什麼,實際是怎麼被 apply 的。當引擎故障了,引擎蓋子就要被掀開。
  • 無數不穩定的依賴: 你構建依賴了 npm,依賴了 Ubuntu 的 repository。 完全 reproducible 是不現實的。 今天能執行的指令碼,不要指望明天一定能工作。誰也沒法隔離所有的依賴變化。
  • State + Version 的組合爆炸: 如果我們不能完全杜絕 mutable state,也無法拒絕新的程式碼,新的版本。那就會有無數種組合的可能性。比如一個執行了一半的指令碼,你 ctrl+c,然後再執行會怎麼樣?誰也無法保證一定沒有問題。 你今天是三個服務,明天變成了四個線上服務,這中間業務再變,部署也一定會跟著變

  • 從一個 State 到另外一個 State 的變化過程: 比如微信小程式從版本1,要升級到版本2。我們希望先發一個體驗版,看看是不是ok。然後提交稽核,稽核透過之後,再正式升級到版本2。這個 state 的遷移如何用 immutable 的 declaration 來描述?不還是得用指令碼的方式來寫嘛。

以上種種原因,使得我們無法保證交付一份自動化的指令碼,就可以保證每個猴子,都可以點一下就獲得一個新環境。這個指令碼一定要不斷被維護,複雜環境的搭建總是需要有人來不斷地維護。每個開發者,透過 docker 是可以構建一個區域性的環境,但稍微大一點規模的環境,就不要指望能讓任何一個猴子,今天可以複製一份,明天也一定能複製一份出來。

多租戶才是終極解決辦法

部署指令碼自動化肯定是要的,要不然機器全被格式化了,就完全沒法快速恢復了。去另外一個地域,開一套新的區服,沒有自動化肯定也是不行的。
但是完全指望自動化指令碼來複制大量的環境,也是非常脆弱的。每套部署出來的環境需要有人來維護,部署指令碼也會報錯,不能指望所有人都可以玩得轉整套系統的部署。
比較好的平衡是由一個固定的人群來維護部署指令碼,和維護部署出來的多套環境。然後再這幾套環境上提供“多租戶”的能力。新的客戶來了,租用一套給他用。新的開發者來了要開發,也是在其上租用一個租戶。
這樣的多租戶系統,更接近一個作業系統的定位。我們寫指令碼的,要會包裝自己,你看我們是商業作業系統的研發人員。
來源:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70013542/viewspace-2914954/,如需轉載,請註明出處,否則將追究法律責任。

相關文章