云原生基礎及調研
本文僅用于簡單普及,達到的目的是給沒接觸過或者很少接觸過這方面的人一點感覺,閱讀起來會比較輕松,作者深知短篇幅文章是不可能真正教會什么的,所以也不會出現 RTFM 的內容。
概念
提到云原生(Cloud Native)可能部分人會陌生,但是如果說 Serverless 相信很多人就知道了,實際上兩者并不等價。Serverless 是一種理念或者服務交付形態,目標是屏蔽硬件和運維細節,而云原生則是實現此類目標的一種規范以及基礎設施。
再進一步,介于 Docker 天然的隔離性和高效等特點,以及 Kubernetes 成為事實意義上的 Docker 編排標準,凡是見到云原生或者 Serverless 的地方,幾乎都可以認為是基于 Docker + Kubernetes 的一種實踐。
演進之路
單個點展開講太枯燥,索性我們從歷史的角度看看為什么會有云原生。
Docker
先申明下,Docker 是一種容器技術(具體可深入 namespaces 和 cgroups),而不是虛擬化技術,真正的虛擬化比較常見的是 Xen 和 KVM,可能有同學要舉手了:老師,那我們經常用的 VirtualBox 和 VMware 算虛擬化么?當然算!不過大多數情況下,它們用在桌面虛擬化領域。不要急著撕,我說的是大多數,而且虛擬化方案也還有很多。
可能大家之前經常遇到這樣的場景:為什么在我這可以運行在你那就不行了?為什么剛剛可以運行現在就不行了?最終解決下來,大多是環境不一致導致的問題。這里的環境除了開發環境還包括操作系統。
所以一般給別人代碼的時候還需要告訴別人此代碼可運行的操作系統版本,所依賴的各種軟件的版本,甚至目錄、磁盤、內存、CPU 都有要求!
當然這個問題還有更直接的辦法,就是把代碼跑在虛擬機里,然后打包虛擬機!(不要笑,實際上還真有人這么干)為什么此刻你笑了,因為虛擬機太重了,無論從打包的體積還是運行時占用的資源都太重了。
那有沒有輕點的「虛擬機」呢?嗯,如標題,不過我們叫做容器化,特點:
- 進程級別的隔離性;
- 除里面運行的應用本身外幾乎不占用宿主資源;
- 結構化的配置文件(Dockerfile);
- 無狀態無副作用(主流方式);
- 分層的聯合文件系統;
- …
Docker 讓運行環境變得可編程!
拿一個最近部署 Sourcegraph 的經歷舉個栗子,官方有個開發者 清單,一堆依賴和環境設置,照著這個部署會爆炸的,好在官方還提供了可快速部署的鏡像,就是這么簡單:
Kubernetes
太長,以下簡稱 K8S,類似的簡稱形式還有 很多。
Docker 雖然很厲害,但是在成人看來也只是小孩的玩具,稍微大點的公司內部可能服務就多的嚇人,特別是 微服務架構 盛行后。
Docker 只解決了單個服務的交付問題,一個具備完整形態的應用必然會涉及各種服務依賴,人為組織這些依賴也是會死人的。Docker 把我們從各種跟環境糾纏里解放出來,卻讓我們陷入了更高維度的服務依賴之間的糾纏。
是個 Docker 用戶應該都會想到去解決這個問題,如你所愿,出現了三國爭霸的局面:Docker Swarm、Apache Mesos 和 Google Kubernetes,一定程度上 K8S 成為了現在主流的 Docker 編排標準。有意思的是 K8S 有舵手之意,而 Docker 有集裝箱之意,所以結合下是不是更合理了?
更有意思的是,K8S 管理 Docker 的過程也是一層層抽象。為了解決一組密切相關容器集合的調度,K8S 的最小的調度單位是 Pod 而不是容器,同一個 Pod 里的容器的資源可以互相訪問。為了管理發布、回滾、擴縮容,又在這之上抽象了一個 Deployment,實際上這是我們最直接使用的單元。為了管理負載均衡和調度,又抽象了一個叫 Service。
以上概念是 K8S 基本概念,不過我想強調的是這個:解決復雜問題很多都是在一層層抽象,這點展開還可以說很多東西。
K8S 做的比較極致的點就是以上所有資源的管理都是通過聲明式的配置進行,K8S 把容器運維變得可編程!
Cloud Native
到這里,如果要直接在生產環境使用 K8S 基本也可以了,我們聊點別的吧。
都知道 Java 后端廣泛采用的 Web 框架是 Spring MVC,那可是 02 年的老古董了!即使現在有了 Spring Boot,也可以算是一種升級,跟近幾年百花齊放的前端三大框架比少了太多的口水仗。
百花齊放的原因很大一部分就是前端一開始就沒有形成強有力的最佳實踐!從工程化角度看,太多的重復輪子很容易導致工程的可維護性變差。Web 后端穩定性的特點不太能容忍這樣的事情發生,推導到云上也一樣。
云原生就是云的(或狹義指 K8S 的)最佳實踐,生而為云,所謂云原生!
為了達到此目的,還有了 CNCF(云原生計算基金會),有了組織就靠譜多了。這個組織有一個收集(或孵化)了各種最佳實踐的 云原生全景圖譜。比如,一個比較有意思的叫 helm,作為 K8S 應用包管理器,它把一個 K8S 應用抽象成一個包,一鍵就可以部署一個應用,跟很多包管理器一樣,它也有源 KubeApps Hub(甚至有阿里云提供的 國內源)。
Serverless
有了云原生,基本各種業務場景都可以找到適合的最佳實踐,Serverless 就是其中一種。個人很不理解為什么這個詞被翻譯成:無服務器架構,Serverless 屏蔽的是運維,所以叫無運維架構更合適。迫于無法接受其中文翻譯,文中還是用 Serverless。
你可能好奇,為啥這里要把 Serverless 單獨拉出來說下,因為這是 CNCF 的寵兒啊!CNCF 范疇內太多項目了,但是大多還是偏硬,普通業務很難用上并落地,所以抓了個可以落地的當典型,還為其起草了個 白皮書,建議有興趣的可以細品。
在說屏蔽運維之前,我們先回顧下運維一般包括哪些:
- 服務器、網絡、存儲等物理資源(IaaS)申請;
- 測試、發布、擴縮容;
- 監控、日志;
- …
要達到屏蔽運維大體就是無需關心以上點,目前業界主流形式有 BaaS 和 FaaS:
- BaaS(Backend as a Service):此服務做法就是把常見的后端服務抽象出來,比如數據存儲、文件存儲、消息等,客戶端使用這些服務時感覺就像在使用普通的 SDK/API。
圖片來自 Cloudflare
- FaaS(Function as a Service):BaaS 只在大多數場景好使,某些特殊場景可能就比較麻煩,有些能力可能并沒有提供,但是又必須要在后端寫。完整關心整個后端代碼框架并沒必要,所以就可以抽象簡單一個個 function 讓用戶去完成。目前 Google 采用的是 Knative,這里還有個其它方案的對比 文章。
具體采用何種方式取決于業務形態,大體上就是用靈活性換方便度,給各種云服務一個靈活度排序:IaaS(各種云主機) > CaaS(Docker 等容器服務) > PaaS(BAE、SAE、GAE 等 APP Engine) > FaaS > BaaS > SaaS(各種 Web APP,如 Google Doc)
。
歪歪的云計算九層架構,深色的表示留給用戶定制的,靈感來源
Serverless 為開發者提供了一種屏蔽運維又具備一定靈活度的云服務。
業界現狀
本文只關心云原生相關產品,即 Docker/K8S 之上的產品,以下是部分主流產品:
- K8S && CaaS
- FaaS
- BaaS
- BaaS + FaaS
有條件都可以體驗下,我舉兩個切身的例子:
- 除了大家見到很多公共云服務,還有很多服務是不適合放到公共云的,需要私有化部署。記得之前給某單位做項目,交付的時候過去裝系統、裝軟件,還要各種現場聯調,來來回回折騰很久。現在用 Docker + K8S 交付就非常輕松了,只需要有一套 K8S 集群,其它都 Docker 鏡像打包帶過去,一個配置文件輕松搞定編排!
- 回想下你們做的系統,是不是很多幾乎都沒人用了,但是還是不能下線?是不是有的系統可能只有幾個接口也要從申請機器到申請各種中間件走一遍流程?我們姑且稱這些為長尾應用,這些應用是團隊歷史包袱變重的重要因素。如果采用 FaaS 或 BaaS 的方式做,你會發現新的人生,而與此相關的配套設施,業界主流的是 CLI 和 WebIDE,無論哪種,都會讓你爽。
以上兩個例子雖然只反應了業界一部分現狀,可見一斑。
總結
本文簡單介紹了云原生的一些基本概念,從演進角度解釋了為什么會有云原生,本質就是抽象抽象再抽象,最后調研了國內外的主流現狀,讀到這希望你有點感覺了,進一步了解需要讀者自行實踐。
參考資料
正文里均以外鏈形式列出。