Manjusaka

Manjusaka

云原生時代的幾個爆論

從去年調轉到現在,做了一段時間的雲原生,我突發奇想,想發表幾個爆論來論述下我眼中的雲原生來作為今年最後一篇技術博客。本文純屬個人向吐槽,與本人公司立場無關

概述#

雲原生大概在 2014-2015 年開始左右,開始正式的提出了這個概念。2015 年 Google 主導成立了雲原生計算基金會(Cloud Native Computing Foundation aka CNCF)。在 2018 年,CNCF 在 CNCF Cloud Native Definition v1.01 首次對雲原生的概念有了一个認定

Cloud native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.
These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.

其中文翻譯如下:

雲原生技術有利於各組織在公有雲、私有雲和混合雲等新型動態環境中,構建和運行可彈性擴展的應用。雲原生的代表技術包括容器、服務網格、微服務、不可變基礎設施和聲明式 API。
這些技術能夠構建容錯性好、易於管理和便於觀察的鬆耦合系統。結合可靠的自動化手段,雲原生技術使工程師能夠輕鬆地對系統作出頻繁和可預測的重大變更。

從官方的定義來看,我更願意將其稱為一個願景 (vision/landscape) 而不是一個定義 (definition),因為在上述的表達中,並沒有清晰明確的表述出雲原生這一新生概念的具體的範圍與邊界,也沒有闡述清楚 Cloud NativeNon-Cloud Native 之間的差異。

如果以個人的視角來看,一個雲原生應用具備以下特質

  1. 容器化
  2. 服務化

而一個踐行雲原生的組織,那麼應該具備以下特質

  1. 重度 Kubernetes 或其餘容器調度平台(如 Shopee 自研的 eru22

  2. 具備完整的監控體系

  3. 具備完整的 CI/CD 體系

在這個基礎上,最近看到很多人都在討論雲原生這一新生概念,所以我想在這裡聊聊個人向的四個爆論(爆論中的數據是個人主觀判斷,輕噴)

  1. 百分之 95 以上的公司,沒有完成 CI/CD 體系的建立。也沒有完成線上服務進程的收斂
  2. 百分之 90 以上的公司,沒有能微服務化的技術儲備
  3. 百分之 90 以上的公司,沒有能撐起容器化的技術儲備

開始爆論#

1. 百分之 95 以上的公司,沒有完成 CI/CD 體系的建立。也沒有完成線上服務進程的收斂#

CI 指持續集成(Continuous Integration aka CI),而 CD 指持續交付(Continuous Delivery aka CD),通常來講 CI 與 CD 的定義如下(此處引用 Brent Laster 在 What is CI/CD?3 中給出的定義

Continuous integration (CI) is the process of automatically detecting, pulling, building, and (in most cases) doing unit testing as source code is changed for a product. CI is the activity that starts the pipeline (although certain pre-validations—often called "pre-flight checks"—are sometimes incorporated ahead of CI).
The goal of CI is to quickly make sure a new change from a developer is "good" and suitable for further use in the code base.
Continuous deployment (CD) refers to the idea of being able to automatically take a release of code that has come out of the CD pipeline and make it available for end users. Depending on the way the code is "installed" by users, that may mean automatically deploying something in a cloud, making an update available (such as for an app on a phone), updating a website, or simply updating the list of available releases.

通常在我們的實踐中,CI 和 CD 的邊界並不明顯。以常見的基於 Jenkins 的實踐為例,我們通常的一套路徑是

  1. 創建一個 Jenkins 的項目,設定一個 Pipeline(其中包含代碼拉取,構建,單元測試等 task),設置觸發條件

  2. 當指定代碼倉庫存在主分支代碼合入等操作時,執行 Pipeline ,然後生成產物

在生成產物後的,常見有兩種做法

  1. 在生成產物的下一個階段觸發自動的 deploy 流程,按照 deploy script 直接將生成的產物 / 鏡像直接部署到目標伺服器上

  2. 將生成的產物上傳到中間平台,由人通過部署平台手動觸發部署任務

在上面描述的過程中,如果有著完備的流程的公司還會有著其餘的輔助流程(如 PR/MR 時的 CI 流程,CR 流程等)

而在面對目標平台的部署時,我自己的另外一個觀點是大部分的公司沒有完成線上服務進程的收斂。講個笑話:

Q: 你們怎麼部署線上服務呀?A;nohup,tmux,screen

對於當下而言,一個規範化的 CI/CD 流程,收口的線上的服務進程的管理,至少在當下,有著可以遇見的幾個好處

  1. 儘可能的降低人為手動變更帶來的風險

  2. 能夠較好的完成基礎運行依賴配置的收口

  3. 依托目前主流的開源的 systemd, supervisor, pm2 等進程管理工具,能對進程提供基礎的 HA 的保證(包括進程探活,進程重拉等)

  4. 為後續的服務化,容器化等步驟打下基礎

2. 百分之 90 以上的公司,沒有能微服務化的技術儲備#

如果說,對於爆論 1 提到的 CI/CD 等手段,我更多的覺得這是一個制度障礙大於技術障礙的現實。那么接下來的幾個爆論,我更願意用沒有技術儲備來形容

先來說說爆論 2: 百分之 90 以上的公司,沒有能微服務化的技術儲備

首先來聊聊微服務的概念吧,微服務實際上在計算機歷史上有著不同的論述,在 2014 年 Martin Fowler 和 James Lewis 正式在 Microservices a definition of this new architectural term4 一文中正式的提出了微服務(Microservice)這一概念。
此處引用維基百科的一段概述

微服務是由以單一應用程序構成的小服務,自己擁有自己的行程與輕量化處理,服務依業務功能設計,以全自動的方式部署,與其他服務使用 HTTP API 通信。同時服務會使用最小的規模的集中管理 (例如 Docker) 能力,服務可以用不同的編程語言與數據庫等組件實現

那麼我們來用研發的話來嘗試描述下關於微服務和與之對應的傳統單體服務(Monolith) 之間顯著性的差異

  1. 微服務的 scope 更小,其更多的專注在某一個功能,或者某一類的功能上

  2. 由於其 scope 更小的特性,其變更,crash 所帶來的影響相較於傳統的單體來說更小

  3. 對於多語言多技術棧團隊來說更為友好

  4. ” 符合 “現在互聯網所需求的小步快跑,快速迭代的大目標

那麼我們這裡需要思考一下,微服務這一套體系,如果我們想要去進行落地和實踐,那麼我們需要怎樣的技術儲備?我覺得主要是兩個方面,架構和治理

首先來聊聊架構吧,我覺得對於微服務來說,最麻煩的一個問題在於從傳統單體應用上進行拆分(當然要是最開始創始之初就開始搞微服務的當我沒說,雖然這樣也有其餘的問題)

如前面所說,微服務相較於傳統的單體應用來說,其 scope 更小,更專注在某一個功能或者某一類的功能上。那么這裡所引申出來我覺得做微服務最大的問題在於合理的劃分功能邊界並進行拆分

如果拆分不合理那麼將導致服務之間相互耦合,比如我將用戶鑑權放置在商城服務中,導致我論壇服務需要依賴其不需要的商城服務。如果拆分的過細,那麼將導致出現一個很有趣的現象,一個規模不大的業務拆了 100 多個服務 repo 出來(我們把這種情況稱為: 微服務難民 2333)

我們踐行落地微服務這一套理念,是因為我們在業務和團隊規模擴大後,面對多樣化的需求與團隊成員技術棧時,傳統單體應用在其持續維護上的成本將會是一個不小的開支。我們希望引入微服務來儘可能減少維護成本,降低風險。但是不合理的拆分,將會重新讓我們的維護成本遠超繼續踐行單體化的方案

而我覺得阻礙微服務繼續踐行的另外一個問題是治理問題。我們來看一下在微服務化後我們所面臨的幾個問題

  1. 可觀測性的问题。如前面所說,微服務化後的單個服務 scope 更小,更多的專注在某一個功能或者某一類功能上。那么這可能導致的問題是,我們在完成一個業務請求所需要經歷的請求鏈路更長。那么按照通用的觀點來看,鏈路更長,其風險更大。那么在在當服務存在異常時(比如業務 RT 的突然增高)我們怎麼樣去定位具體服務的問題?

  2. 配置框架的收口。在微服務化的場景中,我們可能會選擇將一些基礎的功能下沉至具體的內部框架中(如服務註冊,發現,路由等),那麼意味著我們需要維護自己的框架,同時完成配置的收斂

  3. 老生常談的服務治理(註冊、發現、熔斷)等

  4. 由於微服務化後,對於一個完備 CI/CD 機制的需求將變得更為迫切。那么如果存在爆論 1 的情況,將會成為踐行微服務這一理念的障礙

誠然,目前無論開源社區(如 Spring Cloud,Go—Micro 等)還是四大雲廠商(AWS,Azure,阿里雲,GCP)都在嘗試提供一種開箱即用的微服務方案,但是除了沒法很好地解決如上面所說的諸如架構這樣的問題外,其也存在自己的問題

  1. 無論是依賴開源社區的方案,還是雲廠商的方案,都需要使用者具備一定的技術素養,來定位特定情況下框架中的問題

  2. Vendor Lock-in,目前開箱即用的微服務方案並沒有一個通用的開源事實標準。那么依賴某一個開源社區或者雲廠商的方案將存在 vendor lock-in 的問題

  3. 無論是開源社區的方案還是雲廠商的方案,都存在多語言不友好的問題(大家貌似現在都喜歡 Java 一點(Python 沒人權.jpg

所以爆論 2 想表明的最核心的觀點就是:微服務化並不是一個無代價的行為,與之相反的是一個需要不低技術儲備與人力投入的的行為。所以請不要認為微服務是萬能良藥。請按需使用

3. 百分之 90 以上的公司,沒有能撐起容器化的技術儲備#

目前很主流的一個觀點,是能上容器儘可能上容器,說實話這個想法實際上是有一定的合理性的,去 review 這個想法,我們需要去看一下容器這個東西,給我們帶來了什麼樣的改變

容器首先毫無疑問,會給我們帶來非常多的好處:

  1. 真正意義上讓開發與生產環境保持一致是一種非常方便的事,換句話說,開發說的 “這個服務在我本地沒啥問題” 是一句有用的話了
  2. 讓部署一些服務變得更為方便,無論是分發,還是部署,
  3. 能做到一定程度上的資源隔離與分配

那麼,看起來我們是不是可以無腦用容器?不,不是,我們需要再來 Review 一下,容器化後我們可能所要面臨的一些弊端:

  1. 容器安全性問題,目前最主流的容器實現(此處點名 Docker)本質上而言還是基於 CGroups + NS 來進行資源與進程隔離。那么其安全性將會是一個非常值得考量的問題。畢竟 Docker 越權與逃逸漏洞年年有,年年新。那么這意味著我們是需要去有一個系統的機制去規範我們容器的使用,來保證相關的越權點能被把控在一個可控的範圍內。而另一個方向是鏡像安全問題,大家都是面向百度 / CSDN/Google/Stackoverflow 編 (fu) 程 (zhi) 選手,那麼勢必會出現一個情況,當我們遇到一個問題,搜索一番,直接複製點 Dockerfile 下來,這個時候,將會存在很大的風險點,畢竟誰也不知道 base image 裡加了啥料不是?
  2. 容器的網絡問題。當我們啟動若干個鏡像後,那麼容器之間的網絡互通怎麼處理?而大家生產環境,肯定不止一台機器那麼少,那麼跨主機的情況下,怎麼樣去進行容器間的通信,同時保證網絡的穩定性?
  3. 容器的調度與運維的問題,當我一個機器高負載的時候,怎麼樣去將該機器上的一些容器調度到其餘的機器上?而怎麼樣去探知一個容器是否存活?如果一個容器 crash 了,怎麼樣重新拉起?
  4. 容器具體的細節問題,比如鏡像怎麼樣構建與打包?怎麼樣上傳?(又回到了爆論 1)乃至說怎麼樣去排查一些 corner case 的問題?
  5. 對於一些特定的 large size 的鏡像(如機器學習同學常用的 CUDA 官方鏡像,打包了字典模型等大量數據的鏡像等)怎麼樣去快速下載,快速發布?

可能這裡又會有一種觀點,沒事,我們上 Kubernetes 就好啦,上面這些很多問題就能解決啦!好吧,我們再來聊聊這個問題

首先我已經忽略掉自建 Kubernetes 集群的場景了,因為那不是一般人能 Hold 住的。那么我們來看一下,依托公有雲使用的情況吧,以阿里雲為例,點開頁面,然後我們見到這樣張圖

1

2

好了,提問:

  1. VPC 是什麼?
  2. Kubernetes 1.16.9 和 1.14.8 有什麼區別
  3. Docker 19.03.5 和阿里雲安全沙箱 1.1.0 是什麼,有什麼區別
  4. 專有網絡是什麼?
  5. 虛擬交換機是什麼?
  6. 網絡插件是什麼?Flannel 和 Terway 又是什麼?有什麼區別?當你翻了翻文檔,然後文檔告訴你,Terway 是阿里雲基於 Calico 魔改的 CNI 插件。那么 CNI 插件是什麼?Calico 是什麼?
  7. Pod CIDR 是什麼怎麼設?
  8. Service CIDR 是什麼怎麼設?
  9. SNAT 是什麼怎麼設?
  10. 安全組怎麼配置?
  11. Kube-Proxy 是什麼?iptables 和 IPVS 有什麼區別?怎麼選?

大家能看到上面問題涵蓋了這幾方面

  1. Kubernetes 本身的深入了解(CNI,runtime,kube-proxy 等)

  2. 一個合理網絡規劃

  3. 對於雲廠商特定功能的熟悉

在我看來,這三方面任何一方面對於一個技術團隊的技術儲備以及對於業務的理解(廣義的技術儲備)都需要有一個不淺的需求。

當然這裡在碎碎念一下,實際上搞 Kubernetes 這一套開銷實際上很大的(有點偏題,但是還是繼續說吧)

  1. 你得有個鏡像倉庫吧,不貴,中國區基礎版 780 一個月
  2. 你集群內的服務需要暴露出去用吧?行叭,買個最低規格的 SLB,簡約型,每個月 200
  3. 好了,你每個月日誌得花錢吧?假設你每個月 20G 日誌,不多吧?行,39.1
  4. 你集群監控要不要?好,買,每天 50w 條日誌上報吧?行,不貴,975 一個月

算一下,一個集群吧,(780+200+39.1+975)*12=23292.2 一年,不算集群基礎的 ENI,ECS 等費用,美滋滋

而且 Kubernetes 會有很多的玄學的問題,也需要技術團隊有足夠的技術儲備來進行排查(我想想啊,我遇到過 CNI 一号進程 crash 了沒重拉,特定版本上的內核 cgroup 泄漏,ingress OOM 等問題),大家可以去 Kubernetes 的 Issue 區看一下盛況(說多了都是淚)

總結#

我知道這篇文章寫出來會存在很多的爭議。但是我始終想表述的一個觀點是對於雲原生時代這一套東西(實際上也更多是之前傳統技術的延伸),他們的引入並不是無代價,並不是無成本的。對於有著足夠規模與痛點的公司來說,這樣的成本對於他們的業務增長來說是一個正向的促進,而對於更多中小企業來說,可能這一套對於業務的提升將會是非常小乃至說是負作用。

我希望我們技術人員在做技術決策的時候,一定是在評估自己的團隊的技術儲備乃至對於業務的收益後再引入某一種技術與理念,而不是引入一個技術只是因為它看起來夠先進,夠屌,能夠為我的簡歷背書

最後用之前我分享過的一句話來作為本文的結尾吧

一個企業奔著技術先進性去搞技術,就是死

Reference#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。