值與應(yīng)用邊界)
最近有個(gè)朋友問(wèn)我說(shuō)他們公司的業(yè)務(wù)跑在幾十臺(tái)虛擬機(jī)上運(yùn)維靠人工擴(kuò)容靠加班。身邊的同行都在聊K8s老板也跟風(fēng)問(wèn)了一句“別人都在用我們是不是也該上”他被問(wèn)住了于是跑來(lái)找我聊了整整一個(gè)下午。這個(gè)問(wèn)題其實(shí)特別典型。K8sKubernetes從2015年正式發(fā)布到成為容器編排的事實(shí)標(biāo)準(zhǔn)速度之快在基礎(chǔ)設(shè)施領(lǐng)域幾乎沒(méi)有先例。但“大家都在用”不代表“你也要跟風(fēng)用”更不代表“用了K8s就萬(wàn)事大吉”。企業(yè)真正應(yīng)該關(guān)心的不是K8s火不火而是它到底解決了哪些傳統(tǒng)部署方式解決不了的問(wèn)題以及這些問(wèn)題的嚴(yán)重程度是否已經(jīng)到達(dá)了你的痛點(diǎn)閾值。這篇文章我就把這幾年和K8s打交道的經(jīng)驗(yàn)攤開(kāi)來(lái)講把它的核心價(jià)值拆成幾個(gè)層次它解決什么底層矛盾、設(shè)計(jì)理念為什么能成、企業(yè)實(shí)際能獲得什么收益以及最容易被忽略的——什么時(shí)候不該用K8s。話不多說(shuō)直接進(jìn)入正題。1. K8s到底解決了什么問(wèn)題先搞懂痛點(diǎn)在哪兒1.1 環(huán)境一致性從“在我機(jī)器上是好的”到“所有節(jié)點(diǎn)一個(gè)樣”在沒(méi)有容器之前開(kāi)發(fā)和運(yùn)維之間的矛盾從第一天就存在開(kāi)發(fā)在筆記本上代碼跑得飛起運(yùn)維部署到服務(wù)器上就是起不來(lái)。常見(jiàn)的解釋是“環(huán)境不一樣”——操作系統(tǒng)的版本不一樣依賴庫(kù)的版本不一樣配置文件的路徑不一樣甚至連系統(tǒng)時(shí)區(qū)都能導(dǎo)致問(wèn)題。處理辦法也五花八門有人寫(xiě)部署文檔幾十頁(yè)的文檔沒(méi)幾個(gè)人認(rèn)真讀有人用配置管理工具統(tǒng)一環(huán)境但每來(lái)一個(gè)新版本的操作系統(tǒng)就要重新適配一輪。K8s解決這個(gè)問(wèn)題的關(guān)鍵其實(shí)在容器層。容器把應(yīng)用代碼連同它依賴的運(yùn)行環(huán)境語(yǔ)言運(yùn)行時(shí)、系統(tǒng)庫(kù)、配置文件一起打包成鏡像。鏡像一旦構(gòu)建完成從開(kāi)發(fā)環(huán)境到測(cè)試環(huán)境再到生產(chǎn)環(huán)境跑的都是同一個(gè)東西。K8s作為容器的編排平臺(tái)負(fù)責(zé)把這套“同一個(gè)東西”穩(wěn)定地調(diào)度到集群里的任何一臺(tái)機(jī)器上。所以“環(huán)境不一致”這個(gè)老大難問(wèn)題在K8s體系里是天然不存在的。舉一個(gè)更直白的例子傳統(tǒng)虛擬機(jī)的交付物是一個(gè)“配置好的機(jī)器”但機(jī)器上裝了什么、補(bǔ)丁打到什么版本、哪個(gè)服務(wù)被意外停掉了你很難完全掌控。容器的交付物是鏡像鏡像的內(nèi)容是只讀的、可校驗(yàn)的。這就好比以前你送人一臺(tái)組裝電腦里面裝了什么全看裝機(jī)師傅的心情現(xiàn)在你打包的是整機(jī)鏡像拉到哪一臺(tái)服務(wù)器上都是同一個(gè)系統(tǒng)還能校驗(yàn)它的哈希值。1.2 伸縮性難題高峰期來(lái)了你的系統(tǒng)能扛住嗎第二個(gè)痛點(diǎn)是伸縮性。傳統(tǒng)方式下業(yè)務(wù)流量上來(lái)了運(yùn)維要做的事情是申請(qǐng)新的虛擬機(jī)、安裝運(yùn)行環(huán)境、拉取代碼、修改配置、啟動(dòng)服務(wù)、接入負(fù)載均衡。這一套流程手工走下來(lái)運(yùn)氣好要半小時(shí)運(yùn)氣不好要半天。等機(jī)器終于加好了流量高峰可能已經(jīng)過(guò)去了。K8s的做法是把“部署一組副本”變成一個(gè)聲明式的操作——你告訴集群“我有這個(gè)鏡像幫我跑3個(gè)副本”集群就會(huì)自動(dòng)把任務(wù)分配到合適的主機(jī)上。流量漲了你可以手動(dòng)把副本數(shù)改成6個(gè)也可以配置自動(dòng)擴(kuò)縮容讓系統(tǒng)根據(jù)CPU、內(nèi)存或者自定義的業(yè)務(wù)指標(biāo)動(dòng)態(tài)調(diào)整。我實(shí)測(cè)下來(lái)的經(jīng)驗(yàn)是一個(gè)配置好自動(dòng)擴(kuò)縮容的應(yīng)用遇到流量突增時(shí)從監(jiān)控指標(biāo)觸發(fā)到新增的Pod真正開(kāi)始接收流量通常在1到3分鐘以內(nèi)。這個(gè)速度是手工操作完全無(wú)法比的。而且K8s的擴(kuò)縮容是基于Pod粒度而不是整機(jī)粒度幾個(gè)應(yīng)用共享一臺(tái)服務(wù)器資源利用率也上去了。1.3 故障恢復(fù)凌晨?jī)牲c(diǎn)手機(jī)不響鈴嗎傳統(tǒng)的故障處理流程是報(bào)警響鈴、運(yùn)維被叫醒、排查日志、定位問(wèn)題、手動(dòng)重啟或切換流量。整個(gè)過(guò)程依賴人的響應(yīng)速度和經(jīng)驗(yàn)而且夜間被人為叫醒的次數(shù)多了人的狀態(tài)和判斷力都會(huì)下降。K8s的自愈機(jī)制改變的是“故障響應(yīng)”的底層邏輯——它把“檢查故障、決定重啟、執(zhí)行重啟”這套流程自動(dòng)化、制度化。當(dāng)應(yīng)用進(jìn)程異常退出時(shí)K8s會(huì)自動(dòng)拉起重啟當(dāng)整個(gè)節(jié)點(diǎn)宕機(jī)時(shí)節(jié)點(diǎn)上的工作負(fù)載會(huì)被自動(dòng)調(diào)度到其他健康的節(jié)點(diǎn)當(dāng)應(yīng)用不響應(yīng)健康檢查探針時(shí)K8s會(huì)先把流量摘掉然后重啟容器。這些動(dòng)作不用人參與。很多剛接觸K8s的人低估了這個(gè)能力覺(jué)得“重啟一下而已有什么了不起”。但實(shí)際在企業(yè)環(huán)境里這個(gè)“重啟一下”對(duì)應(yīng)的是全年無(wú)數(shù)個(gè)深夜電話和無(wú)數(shù)次手忙腳亂。K8s的核心價(jià)值之一就是把這些低水平但緊急的工作從人身上卸載掉讓人去做更有價(jià)值的事情。2. K8s的核心價(jià)值拆解聲明式、自愈與資源效率2.1 聲明式API告訴系統(tǒng)“要什么”而不是“怎么干”K8s的理念里有一個(gè)非常關(guān)鍵的轉(zhuǎn)變傳統(tǒng)的運(yùn)維工具告訴你的是“做什么操作”比如啟動(dòng)服務(wù)、停止服務(wù)、增加節(jié)點(diǎn)K8s告訴你的是“期望狀態(tài)”比如“請(qǐng)保持這個(gè)應(yīng)用始終有3個(gè)副本在運(yùn)行”。這種“聲明式”的設(shè)計(jì)有什么好處最大的好處是可審計(jì)、可回放、可防止漂移。你的部署配置是一份YAML文件存在代碼倉(cāng)庫(kù)里任何對(duì)系統(tǒng)的變更都必須通過(guò)修改這份文件來(lái)完成。因?yàn)槲募邪姹練v史你能知道誰(shuí)在什么時(shí)間改了什么東西出問(wèn)題了還能快速回退。這比某個(gè)人半夜登錄服務(wù)器手動(dòng)跑了一條命令靠譜得多。聲明式API背后是K8s的控制器模型Controller。以Deployment為例它的控制器會(huì)持續(xù)做一件看起來(lái)枯燥的事對(duì)比“當(dāng)前副本數(shù)”和“期望副本數(shù)”如果發(fā)現(xiàn)不一致就創(chuàng)建或刪除Pod來(lái)對(duì)齊。這個(gè)過(guò)程叫“調(diào)和循環(huán)”聽(tīng)起來(lái)很簡(jiǎn)單但它是整個(gè)系統(tǒng)穩(wěn)定性的基石。我在這里提醒一句如果你上了K8s之后還是習(xí)慣直接ssh進(jìn)容器里改配置那等于把K8s用成了虛擬機(jī)完全沒(méi)發(fā)揮出它該有的價(jià)值。正確的做法是什么都走聲明式文件讓Git成為唯一的事實(shí)來(lái)源這就是這兩年大家常說(shuō)的GitOps。2.2 調(diào)度與資源利用率把服務(wù)器的每一分錢花明白傳統(tǒng)部署里有個(gè)非常常見(jiàn)的浪費(fèi)場(chǎng)景為了保障核心業(yè)務(wù)的穩(wěn)定性一臺(tái)物理機(jī)或虛擬機(jī)只跑一個(gè)應(yīng)用。結(jié)果是什么呢?cái)?shù)據(jù)庫(kù)機(jī)器CPU常年5%Redis機(jī)器內(nèi)存用了30%應(yīng)用服務(wù)器峰值也只有40%。整個(gè)機(jī)房的平均資源利用率能到15%就已經(jīng)謝天謝地了。K8s的調(diào)度器解決的是“裝箱”問(wèn)題——把很多個(gè)容器合理地塞進(jìn)有限的節(jié)點(diǎn)里讓資源得到充分利用。調(diào)度器會(huì)綜合考量每個(gè)Node的CPU、內(nèi)存剩余量、已經(jīng)運(yùn)行的Pod情況、親和性規(guī)則幫每個(gè)新Pod找到最合適的位置。你只需要在部署配置里寫(xiě)上每個(gè)容器請(qǐng)求多少資源requests、最多能用多少資源limits剩下的交給調(diào)度器。從成本角度看這是一個(gè)很直接的賬假設(shè)你有10臺(tái)物理機(jī)每臺(tái)用了15%的資源。理論上有3臺(tái)機(jī)器就可以承載同樣的業(yè)務(wù)另外7臺(tái)可以下線、可以給別的團(tuán)隊(duì)用、可以節(jié)約電力和機(jī)房空間。雖然實(shí)際調(diào)度沒(méi)有這么完美還要考慮冗余、分片、數(shù)據(jù)局部性但資源利用率提升一倍以上是完全做得到的。2.3 服務(wù)發(fā)現(xiàn)與流量治理長(zhǎng)得像微服務(wù)的功能現(xiàn)在原生就有在傳統(tǒng)架構(gòu)里服務(wù)要互相調(diào)用運(yùn)維要維護(hù)一份IP清單或者接入一個(gè)注冊(cè)中心。每當(dāng)有服務(wù)擴(kuò)容或遷移IP變了要么人工改配置要么靠各種注冊(cè)中心搞定。K8s內(nèi)置了Service、DNS、負(fù)載均衡機(jī)制服務(wù)之間只需要通過(guò)固定的內(nèi)部域名互訪集群自動(dòng)把請(qǐng)求轉(zhuǎn)發(fā)到存活的Pod上。流量治理相關(guān)的功能也下沉到了平臺(tái)層滾動(dòng)更新時(shí)新的Pod一個(gè)一個(gè)起來(lái)老的Pod一個(gè)一個(gè)下線流量的切換平滑得用戶幾乎無(wú)感知一旦新版本發(fā)布后負(fù)載異常一條命令回滾到上一個(gè)版本幾十秒鐘完成。這些能力如果全要自研別說(shuō)小團(tuán)隊(duì)很多中大型團(tuán)隊(duì)都得投入好幾個(gè)人力專門維護(hù)。3. 企業(yè)為什么紛紛轉(zhuǎn)向K8s從成本、速度與標(biāo)準(zhǔn)化算賬3.1 基礎(chǔ)設(shè)施成本賬利用率、多云與避免鎖定企業(yè)上K8s的感受最直觀的是成本結(jié)構(gòu)的變化。前面提到的資源裝箱能力能直接減少服務(wù)器的采購(gòu)量。上云的企業(yè)感受更明顯業(yè)務(wù)流量有明顯的波峰波谷——工作日的白天高夜間低促銷節(jié)點(diǎn)高日常低。沒(méi)有彈性伸縮機(jī)制時(shí)云服務(wù)器的賬單是按峰值需求計(jì)費(fèi)的意味著你為了撐住一個(gè)月里那幾天的流量為整個(gè)月付了額外的費(fèi)用。K8s的動(dòng)態(tài)擴(kuò)縮容配合云的按量付費(fèi)理論上可以做到“用多少付多少”。比如一個(gè)應(yīng)用平時(shí)5個(gè)副本促銷來(lái)了自動(dòng)擴(kuò)到20個(gè)促銷結(jié)束后自動(dòng)縮回5個(gè)。這個(gè)場(chǎng)景下的賬單對(duì)比一年省下來(lái)的錢足夠覆蓋團(tuán)隊(duì)學(xué)習(xí)和維護(hù)K8s的投入了。還有多云和避免廠商鎖定的考量。K8s的API是標(biāo)準(zhǔn)化的雖然每家云廠商的托管K8s服務(wù)在一些細(xì)節(jié)上有差異但基本的Deployment、Service、Ingress、ConfigMap這些對(duì)象是跨平臺(tái)一致的。這意味著你的架構(gòu)可以在不同云之間遷移也可以做到混合云部署。對(duì)于已經(jīng)把“不用把身家性命押在一朵云上”當(dāng)成原則的企業(yè)來(lái)說(shuō)這是很強(qiáng)的吸引力。3.2 研發(fā)效率賬從“等運(yùn)維排期”到“自助發(fā)布”傳統(tǒng)模式下研發(fā)要發(fā)一個(gè)版本流程通常是提工單、等運(yùn)維審批、運(yùn)維執(zhí)行發(fā)布、出問(wèn)題再回滾。這個(gè)流程短則半天長(zhǎng)則一天甚至更久。如果每天要發(fā)布多個(gè)版本運(yùn)維團(tuán)隊(duì)的人力馬上就成為瓶頸。K8s配合CI/CD流水線之后發(fā)布這件事變成了“開(kāi)發(fā)者自己按一下按鈕”或者“代碼合并后自動(dòng)觸發(fā)”。鏡像構(gòu)建、推送到鏡像倉(cāng)庫(kù)、更新K8s工作負(fù)載這一整條鏈路是自動(dòng)化的。低風(fēng)險(xiǎn)的發(fā)布可以做到一天好幾次而且因?yàn)闈L動(dòng)更新和快速回滾機(jī)制發(fā)布失敗的代價(jià)也大大降低。對(duì)于追求快速迭代的互聯(lián)網(wǎng)業(yè)務(wù)來(lái)說(shuō)這種“發(fā)布自由”帶來(lái)的價(jià)值很難用金錢去衡量。3.3 環(huán)境標(biāo)準(zhǔn)化開(kāi)發(fā)、測(cè)試、預(yù)發(fā)、生產(chǎn)“長(zhǎng)得一模一樣”很多企業(yè)的環(huán)境多到數(shù)不清有人有本地開(kāi)發(fā)環(huán)境還有開(kāi)發(fā)環(huán)境、聯(lián)調(diào)環(huán)境、測(cè)試環(huán)境、預(yù)發(fā)布環(huán)境、生產(chǎn)環(huán)境。傳統(tǒng)方式下這些環(huán)境的配置靠人工維護(hù)環(huán)境之間配置漂移是常態(tài)——生產(chǎn)環(huán)境有個(gè)特殊配置預(yù)發(fā)環(huán)境沒(méi)有結(jié)果每次預(yù)發(fā)測(cè)完都好好的一上生產(chǎn)就出問(wèn)題。K8s的價(jià)值在于一套部署文件可以在多個(gè)環(huán)境間復(fù)用只需要切換不同的配置項(xiàng)比如環(huán)境的域名、數(shù)據(jù)庫(kù)地址、密鑰。環(huán)境的差異被顯式地管理在配置中心或ConfigMap/Secret里而不是散落在某臺(tái)服務(wù)器的某個(gè)角落。開(kāi)發(fā)如果要在本地起一套和新環(huán)境一致的K8s集群借助工具比如minikube這類也能很接近地模擬出來(lái)。環(huán)境一致性帶來(lái)的“測(cè)完就能上”的確定性是很多團(tuán)隊(duì)從K8s獲得的最大改善。4. 別盲目跟風(fēng)什么時(shí)候該上K8s什么時(shí)候該說(shuō)“不”4.1 適合上K8s的典型場(chǎng)景結(jié)合我自己見(jiàn)過(guò)的大量案例有以下特征的業(yè)務(wù)場(chǎng)景是比較適合上K8s的微服務(wù)化程度高服務(wù)數(shù)量上來(lái)了光靠手工維護(hù)各個(gè)服務(wù)的部署和通信已經(jīng)力不從心。流量有明顯的峰谷波動(dòng)或者存在大促、活動(dòng)日這類流量突增場(chǎng)景需要快速擴(kuò)縮容。發(fā)布頻率高每周甚至每天都要發(fā)多個(gè)版本需要對(duì)發(fā)布效率和回滾速度有強(qiáng)要求。團(tuán)隊(duì)里有專人或者有決心培養(yǎng)專人負(fù)責(zé)基礎(chǔ)設(shè)施愿意接受長(zhǎng)期維護(hù)集群的成本。業(yè)務(wù)邏輯需要多環(huán)境一致地運(yùn)行客戶現(xiàn)場(chǎng)部署或多云部署的需求比較強(qiáng)烈。如果你所在的團(tuán)隊(duì)同時(shí)命中上述多條那K8s大概率是值得投入的方向。4.2 不適合或暫時(shí)不需要上K8s的場(chǎng)景有些場(chǎng)景強(qiáng)行上K8s反而是災(zāi)難。我把這些典型情況列出來(lái)你對(duì)照一下只有一個(gè)單體應(yīng)用幾臺(tái)服務(wù)器就能搞定沒(méi)有明顯的擴(kuò)容壓力——上了K8s只是徒增復(fù)雜度。團(tuán)隊(duì)沒(méi)有容器化基礎(chǔ)Docker都不熟悉就想一步到位——基礎(chǔ)設(shè)施的新概念一股腦砸過(guò)來(lái)開(kāi)發(fā)運(yùn)維都會(huì)很痛苦。沒(méi)有專門的運(yùn)維或基礎(chǔ)設(shè)施角色全靠研發(fā)兼職——K8s的維護(hù)成本絕對(duì)被低估了尤其是控制平面的升級(jí)、etcd備份、網(wǎng)絡(luò)方案調(diào)優(yōu)這些事。業(yè)務(wù)規(guī)模小到一臺(tái)高性能服務(wù)器就能扛住全部負(fù)載——這時(shí)候談資源利用率沒(méi)有意義因?yàn)樵俑咭簿褪∫慌_(tái)機(jī)器的錢。應(yīng)用是無(wú)狀態(tài)還好如果大量有狀態(tài)應(yīng)用數(shù)據(jù)庫(kù)、中間件在K8s上運(yùn)行它們需要額外付出很多學(xué)習(xí)成本。我親眼見(jiàn)過(guò)一個(gè)團(tuán)隊(duì)業(yè)務(wù)只有幾個(gè)內(nèi)部使用的管理系統(tǒng)總共幾百個(gè)用戶強(qiáng)行追趕時(shí)髦上了一套K8s。結(jié)果幾個(gè)月過(guò)去版本沒(méi)升級(jí)過(guò)證書(shū)過(guò)期了沒(méi)人管節(jié)點(diǎn)被一次日志占滿導(dǎo)致集群故障最后項(xiàng)目無(wú)疾而終。這個(gè)例子我每次講都覺(jué)得很可惜——不僅是資源浪費(fèi)更重要的是讓團(tuán)隊(duì)成員對(duì)K8s留下了“這玩意兒很麻煩”的負(fù)面印象。4.3 一個(gè)可量化的判斷方式你不妨算一筆賬把你過(guò)去一年因?yàn)椤笆止げ渴稹薄碍h(huán)境問(wèn)題”“擴(kuò)容不及時(shí)”“發(fā)布故障”帶來(lái)的直接工時(shí)損失和環(huán)境成本加起來(lái)再預(yù)估一個(gè)K8s落地需要投入的成本人力學(xué)習(xí)、遷移、維護(hù)如果前者明顯大于后者上K8s就是劃算的。這個(gè)公式很粗糙但比“大家都在用”靠譜一百倍。5. 落地K8s的五個(gè)真實(shí)坑來(lái)自一線的避坑清單5.1 網(wǎng)絡(luò)方案選型必須先想清楚K8s集群的網(wǎng)絡(luò)方案是整個(gè)平臺(tái)最容易出問(wèn)題、也最影響使用體驗(yàn)的一環(huán)。常見(jiàn)的方案有Flannel、Calico等。它們的區(qū)別主要是數(shù)據(jù)平面的性能、是否支持網(wǎng)絡(luò)策略以及功能的豐富程度。Flannel部署簡(jiǎn)單適合剛學(xué)習(xí)的時(shí)候用。但如果你在跑生產(chǎn)集群我建議認(rèn)真考慮Calico這類支持網(wǎng)絡(luò)策略的方案。生產(chǎn)環(huán)境里的安全隔離很重要比如不同團(tuán)隊(duì)之間默認(rèn)不允許互相訪問(wèn)或者某個(gè)應(yīng)用只允許被特定調(diào)用方訪問(wèn)這些要在網(wǎng)絡(luò)層做不能在業(yè)務(wù)代碼里做。我踩過(guò)的坑是最開(kāi)始圖省事選了最簡(jiǎn)單的網(wǎng)絡(luò)方案后續(xù)業(yè)務(wù)要求網(wǎng)絡(luò)策略時(shí)發(fā)現(xiàn)底層方案不支持只好推倒重來(lái)遷移集群。這種遷移對(duì)運(yùn)行中的業(yè)務(wù)是有損的代價(jià)遠(yuǎn)比當(dāng)初多花一天選型高得多。所以網(wǎng)絡(luò)方案建議在一開(kāi)始就按生產(chǎn)標(biāo)準(zhǔn)來(lái)規(guī)劃。5.2 有狀態(tài)應(yīng)用別照搬無(wú)狀態(tài)的經(jīng)驗(yàn)數(shù)據(jù)庫(kù)要不要跑在K8s里是社區(qū)里爭(zhēng)論了幾年的話題。我的觀點(diǎn)是沒(méi)有足夠的K8s經(jīng)驗(yàn)之前先不要?jiǎng)雍诵臄?shù)據(jù)庫(kù)。K8s對(duì)有狀態(tài)應(yīng)用的支持雖然在逐年完善但它的復(fù)雜度和運(yùn)維難度依然明顯高于無(wú)狀態(tài)應(yīng)用。如果你一定要在有狀態(tài)應(yīng)用上使用K8s請(qǐng)接受一個(gè)前提你必須嚴(yán)格遵守K8s的存儲(chǔ)抽象PersistentVolume/PersistentVolumeClaim來(lái)做數(shù)據(jù)持久化并且做好備份。親手把數(shù)據(jù)搞丟過(guò)一次之后你就能體會(huì)什么叫“敬畏心”。5.3 版本升級(jí)是有節(jié)奏的不是想升就升K8s的版本升級(jí)有一個(gè)原則跨版本升級(jí)需謹(jǐn)慎。每個(gè)大版本之間可能有API對(duì)象的增刪、字段的變更、行為的變化跨多個(gè)大版本直接升級(jí)容易踩到兼容性的坑。我見(jiàn)過(guò)有人從1.20直接升到1.28結(jié)果一堆資源對(duì)象的API版本變了折騰了好幾個(gè)通宵。更合理的節(jié)奏是跟蹤整個(gè)社區(qū)的版本發(fā)布節(jié)奏至少一個(gè)季度維護(hù)一次保持集群在一個(gè)相對(duì)穩(wěn)定的版本區(qū)間內(nèi)。避免用太老的版本因?yàn)橛行┌踩┒春凸δ苋毕葜辉谛掳姹拘迯?fù)也別用太新的版本因?yàn)樾掳姹緞偘l(fā)布時(shí)可能會(huì)有一些潛在問(wèn)題。還有一條容易被忽略的etcd的備份比什么都重要。集群出事時(shí)etcd經(jīng)常是唯一的救命稻草——請(qǐng)定時(shí)做自動(dòng)化備份否則到時(shí)就晚了。5.4 資源配額和LimitRange不設(shè)限制的系統(tǒng)遲早會(huì)出事很多團(tuán)隊(duì)剛上K8s時(shí)開(kāi)發(fā)人員圖省事部署文件里不寫(xiě)requests和limits??雌饋?lái)順利運(yùn)行了其實(shí)是把風(fēng)險(xiǎn)留給了整個(gè)集群——某個(gè)應(yīng)用內(nèi)存暴漲時(shí)會(huì)拖垮同一節(jié)點(diǎn)上的所有其他應(yīng)用。正確做法是在集群側(cè)建立資源配額機(jī)制ResourceQuota和LimitRange讓namespace下的每個(gè)工作負(fù)載都必須聲明資源請(qǐng)求和限制。從規(guī)范上約定下來(lái)從制度上避免濫用的可能性。在配置方面我建議先為Container設(shè)置合理的requests和limits再以Paas或模板的方式固化下來(lái)防止新成員不按規(guī)則來(lái)。5.5 不要忘了監(jiān)控、日志和告警最后這一個(gè)坑我?guī)缀趺看慰吹叫聢F(tuán)隊(duì)踩都會(huì)心疼一下應(yīng)用業(yè)務(wù)是遷移上了K8s但監(jiān)控體系和日志系統(tǒng)沒(méi)有跟著升級(jí)。當(dāng)Pod漂移、新節(jié)點(diǎn)加入、舊節(jié)點(diǎn)下線時(shí)傳統(tǒng)基于虛擬機(jī)的監(jiān)控體系已經(jīng)失效了而團(tuán)隊(duì)還渾然不覺(jué)直到線上出了故障才發(fā)現(xiàn)什么數(shù)據(jù)都看不到排查無(wú)從下手。K8s上比較好的實(shí)踐是進(jìn)程級(jí)監(jiān)控和資源監(jiān)控用Prometheus生態(tài)體系日志采集用Filebeat或Fluentd這類工具把容器日志統(tǒng)一收集到集中存儲(chǔ)調(diào)用鏈追蹤根據(jù)公司的技術(shù)棧選擇合適的工具。監(jiān)控預(yù)警體系建議在遷移過(guò)程中就要同步建設(shè)不要等出了事故再補(bǔ)救。6. 寫(xiě)在最后我個(gè)人的一點(diǎn)實(shí)際體會(huì)和K8s打交道的這幾年我最大的感受是K8s的本質(zhì)不是簡(jiǎn)化了某個(gè)具體的部署操作而是把運(yùn)維工作從“操作一個(gè)系統(tǒng)”提升到了“聲明一種期望狀態(tài)”的層級(jí)。很多剛上手時(shí)的繁瑣學(xué)習(xí)YAML、理解控制器、研究網(wǎng)絡(luò)插件其實(shí)是把前幾年手工運(yùn)維欠下的技術(shù)債一次性補(bǔ)齊。如果你正在評(píng)估是否要上K8s別急著問(wèn)“怎么部署”先想想“我現(xiàn)在的痛點(diǎn)是什么”。如果痛點(diǎn)是環(huán)境不一致、擴(kuò)容慢、發(fā)布難回滾、機(jī)器利用率低那K8s確實(shí)是你需要的答案如果痛點(diǎn)不明顯那就先把容器化做好把Docker用好也完全沒(méi)問(wèn)題。另外分享一個(gè)實(shí)用技巧即使決定上K8s也不要一下子把全部業(yè)務(wù)塞進(jìn)去。挑一個(gè)非核心的、適合做實(shí)驗(yàn)的服務(wù)先跑起來(lái)讓團(tuán)隊(duì)把整個(gè)鏈路跑通、把坑踩一遍再逐步擴(kuò)大范圍。這種漸進(jìn)式的遷移在成功率和團(tuán)隊(duì)接受度上遠(yuǎn)遠(yuǎn)好于一次性全量遷移。記住K8s是給業(yè)務(wù)提效的工具不是拿來(lái)向同行炫耀的裝飾品。