為什么說 k8s 是云時代的操作系統(tǒng)?
這兩年,Kubernetes 擊敗了 Swarm 和 Mesos,幾乎成為容器編排的事實標(biāo)準(zhǔn),BAT、滴滴、京東、頭條等大廠,都爭相把容器和 K8S 項目作為技術(shù)重心。
為什么在眾多容器平臺中,Kubernetes能夠脫穎而出,是因為Kubernetes的接口和概念設(shè)計是完全站在應(yīng)用角度而非運維角度的。
如果站在傳統(tǒng)運維人員的角度看 Kubernetes,會覺得他是個奇葩所在,容器還沒創(chuàng)建出來,概念先來一大堆,文檔先讀一大把,編排文件也復(fù)雜,組件也多,讓很多人望而卻步。
但是如果開發(fā)人員的角度,尤其是從微服務(wù)應(yīng)用的架構(gòu)的角度來看Kubernetes,則會發(fā)現(xiàn),他對于微服務(wù)的運行生命周期和相應(yīng)的資源管控,做了非常好的抽象。
如圖中所示,和虛擬機(jī)運行傳統(tǒng)應(yīng)用,只需要創(chuàng)建出資源來,并且保證網(wǎng)絡(luò)暢通即可的方式不同,微服務(wù)的運行,需要完成左面的一系列工具鏈。
為什么要使用這些工具鏈,以及如何使用這些工具鏈,請參考我的另外兩篇文章以業(yè)務(wù)為核心的云原生體系建設(shè)和從1到2000個微服務(wù),史上最落地的實踐云原生25個步驟。
你會發(fā)現(xiàn),Kubernetes都有相應(yīng)的工具鏈可以匹配。
微服務(wù)設(shè)計重要的一點就是區(qū)分無狀態(tài)和有狀態(tài),在 K8S 中,無狀態(tài)對應(yīng) deployment,有狀態(tài)對應(yīng) StatefulSet。
deployment 主要通過副本數(shù),解決橫向擴(kuò)展的問題。
而 StatefulSet 通過一致的網(wǎng)絡(luò) ID,一致的存儲,順序的升級,擴(kuò)展,回滾等機(jī)制,保證有狀態(tài)應(yīng)用,很好地利用自己的高可用機(jī)制。因為大多數(shù)集群的高可用機(jī)制,都是可以容忍一個節(jié)點暫時掛掉的,但是不能容忍大多數(shù)節(jié)點同時掛掉。而且高可用機(jī)制雖然可以保證一個節(jié)點掛掉后回來,有一定的修復(fù)機(jī)制,但是需要知道剛才掛掉的到底是哪個節(jié)點,StatefulSet 的機(jī)制可以讓容器里面的腳本有足夠的信息,處理這些情況,實現(xiàn)哪怕是有狀態(tài),也能盡快修復(fù)。
微服務(wù)少不了服務(wù)發(fā)現(xiàn),除了應(yīng)用層可以使用 SpringCloud 或者 Dubbo 進(jìn)行服務(wù)發(fā)現(xiàn),在容器平臺層當(dāng)然是用 Service了,可以實現(xiàn)負(fù)載均衡,自修復(fù),自動關(guān)聯(lián)。
服務(wù)編排,本來 K8S 就是編排的標(biāo)準(zhǔn),可以將 yml 文件放到代碼倉庫中進(jìn)行管理,而通過 deployment 的副本數(shù),可以實現(xiàn)彈性伸縮。
對于配置中心,K8S 提供了 configMap,可以在容器啟動的時候,將配置注入到環(huán)境變量或者 Volume 里面。但是唯一的缺點是,注入到環(huán)境變量中的配置不能動態(tài)改變了,好在 Volume 里面的可以,只要容器中的進(jìn)程有 reload 機(jī)制,就可以實現(xiàn)配置的動態(tài)下發(fā)了。
統(tǒng)一日志中心,監(jiān)控中心,APM往往需要在 Node 上部署 Agent,來對日志和指標(biāo)進(jìn)行收集,當(dāng)然每個 Node 上都有,daemonset 的設(shè)計,使得更容易實現(xiàn)。
Kubernetes本身能力比較弱的就是服務(wù)的治理能力,這一點 Service Mesh,可以實現(xiàn)更加精細(xì)化的服務(wù)治理,進(jìn)行熔斷,路由,降級等策略。Service Mesh 的實現(xiàn)往往通過 sidecar 的方式,攔截服務(wù)的流量,進(jìn)行治理。這也得力于 Pod 的理念,一個 Pod 可以有多個容器,如果當(dāng)初的設(shè)計沒有 Pod,直接啟動的就是容器,會非常的不方便。
所以,掌握容器技術(shù)成為很多公司招聘時的重要選項。
這兩年,跟朋友探討 K8S落地時,也有一些問題被反復(fù)提及,比如:
- 為什么容器里只能跑“一個進(jìn)程”?
- 之前一直用的某個 JVM 參數(shù),在容器里怎么不好使了?
- 為什么 Kubernetes 不能固定 IP 地址?容器網(wǎng)絡(luò)連不通,該如何 Debug?
- K8S 中 StatefulSet 和 Operator 到底什么區(qū)別?PV 和 PVC 又該怎么用?
這些問題的答案和原理并不復(fù)雜,但很難一兩句話解釋清楚。因為容器技術(shù)涉及操作系統(tǒng)、網(wǎng)絡(luò)、存儲、調(diào)度、分布式原理等方方面面的知識,是個名副其實的全棧技術(shù)。
而其技術(shù)體系里那些“牽一發(fā)而動全身”的主線,比如 Linux 進(jìn)程模型對容器本身的重要意義,“控制器”模式對整個 K8S 項目提綱挈領(lǐng)的作用等等,不會詳細(xì)展現(xiàn)在 Docker 或 Kubernetes 官方文檔中,但偏偏就是它們,才是掌握容器技術(shù)體系的精髓所在。