最近閒下來,打算把Knative的核心組件Serving給學習下,會繼續採用k8s源碼學習的方式,管中窺豹以小擊大,學習serving的主要目標: 可觀測性基礎設施、自動伸縮、流量管理等核心組件的設計與實現,今天先簡單臆測下,感興趣的同窗, 一塊兒來學習吧web
1. 基於雲原生的單體應用構建
大多數公司的服務可能都已經通過單體、SOA演進到了當下流行的微服務架構,微服務給咱們帶來了獨立演進、擴容、協做、數據自治等便利的背景下,也帶來了諸如穩定性保障、維護、服務治理等實際的問題,咱們今天來一塊兒來回歸單體,好比咱們要新開一個業務,新上一個小的模塊這個場景,在雲原生的場景下,是如何玩的docker
1.1 雲原生下的單體應用
雲原生有不少大佬有不少的解釋,我就簡單理解成是基於雲構建而來,可使用雲上全部已知的現有的服務,同時享受雲所帶來的彈性、按需付費、高可用等方面的原生能力 後端
一個基礎的單體應用一般會依賴以下幾部分:持久化數據存儲、高性能緩存、全文索引、消息隊列等常見組件, 各家雲廠商大多數會包含這些基礎的服務,咱們只須要引入對應的類庫完成咱們的應用邏輯便可, 而後程序就完成代碼的coding後,下一步就是交付了緩存
1.2 基於k8s的雲原生交付
基於k8s的雲原生已經成爲一個事實上的標準,將代碼和應用的數據打包成docker鏡像,基於Pod的交付模式,讓咱們並不須要關注咱們是使用IDC裏面的實體機,仍是公有云的雲服務,咱們只須要打包成docker鏡像,而後設置好檔期環境的配置數據,咱們的單體應用就能夠運行了, 可是一般咱們會有一些非業務需求, 好比監控、日誌等, 下一節咱們來解決這些問題微信
1.3 sidecar模式
在應用開發的初期,咱們可能並無考慮監控、日誌這種可觀測性的需求,一般是在上線的時候纔會考慮這些,而基於k8s的雲原生的環境下,一般會使用一個sidecar來實現這種基礎功能的加強,經過嵌入一個sidecar容器完成這種基礎組件的複用,能夠基於sidecar模式實現日誌、監控、分佈式跟蹤、Https支持等基礎功能,而讓上層應用只關注業務邏輯的實現 架構
1.4 服務即基礎設施
在公司中一般一個業務每每都會進行一些公司內部系統的接入,好比用戶、支付、運營等服務,若是公司的服務也能夠與基礎設施同等對待,而且這些服務也能夠經過k8s的形式進行交付,則咱們就能夠只關注單體應用自身的擴展(小前臺) 併發
經過上面的設想咱們構建出了一個基礎的單體應用,應用程序只須要關注應用邏輯的編寫,所有的業務邏輯都耦合在一個應用內,其他的基礎設施、非業務需求全都由其餘組件實現,接下來就該部署了,一般咱們就須要分配個XHXG配置的Pod,而後爲了高可用可能還須要N個replicaset,而後再來個HPA體驗下自動伸縮,跑了一段時間可能會發現,可能一天就兩個巴掌的訪問量,但是依舊佔用着N*XHXG的資源,以這個角度咱們來進入咱們今天的主題Knative框架
2.Knative
Knative還在不斷變化中,一些設計文檔也並無對外開放,讀起來就相對k8s難一些,但總體代碼量相比較也少了一些,在後續的文章裏面咱們仍是先管中窺豹,逐個組件進行代碼閱讀,但由於沒有相關的Proposal, 主要是參考冬島大神的相關文章來進行代碼的閱讀,只是我的理解,若有不對,歡迎指教,接下來咱們看看knative是如何完成上面提到的功能與實現按需分配關鍵組件, 咱們從流量入口開始依次介紹各個組件分佈式
2.1 基於Istio實現南北向流量的管控
在k8s中南北向流量一般由Ingress來進行管控,而在kantive流量管控的實現,主要是依賴於istio, Istio是一個ServiceMesh框架,Knative中與其集成主要是使用了istio的南北向流量管控的功能,其實就是利用istio對應的ingress的功能, 主要功能分爲下面兩個部分ide
2.1.1 版本部署管理
Knative裏面支持藍綠、金絲雀等發佈策略,其核心就是經過本身的revision版本管理和istio中的ingress的路由配置功能,即咱們能夠根據本身的須要設定對應的流量策略,從而進行版本的發佈配置管理
2.1.2 自動伸縮(至零)
Knative自動伸縮有兩個特色:按需自動分配、縮容至零,按需分配時指的knative能夠根據應用的併發能力,來自動計算實現自動擴容,並且整個基本上是秒級,不一樣於HPA, 其次是就是縮容至零,便可以將對應的業務容器Pod,所有幹掉,可是新進入請求以後會當即進行分配,並不影響正常訪問(可能初期延遲會相對高一些)
2.2 Queue sidecar
在上面到過可觀測性需求,在應用服務中一般能夠分爲三個部分:日誌、監控、分佈式跟蹤,爲了實現這些功能Knative實現了Queue組件,其職責目前理解主要是分爲兩個部分:完成觀測性數據收集、代理業務容器的訪問, Queue組件經過代理的方式實現上面提到指標的統計, 並將對應的數據彙報給後端的日誌/監控/分佈式跟蹤服務, 同時還須要向autoscaler同步當前的併發監控, 以便實現自動伸縮功能, Queue主要是代理應用容器, 而Kantive支持縮容至零的特性, 在縮容至零的時候, Knative就會使用一個Activator Pod來替代Queue和應用容器,從而實現縮容至零
2.3 Activator
Activator容器是縮容至零的關鍵,當業務容器沒有訪問的時候,Knative就會將對應的ingress流量指向Activator組件,當縮容至零的時候,若是此時又業務請求,Activator會當即通知autoscaler馬上拉起業務容器,並將流量轉發真正的業務容器,這樣既能夠完成流量的無損轉發,又能夠實現按需付費,不再用爲沒有訪問量的業務,一直啓動着Pod了, Activator並不負責實際的伸縮決策,伸縮組件主要是經過Autoscaler來實現
2.4 Autoscaler
Autoscaler是Knative中實現自動擴容的關鍵,其經過Activator和Queue兩個組件傳遞過來的監控數據並根據配置來計算,實時動態的調整業務容器的副本數量,從而實現自動伸縮
2.5 Controller
Controller是Knative對應資源的控制器,其自己的功能跟k8s中其餘的組件的實現相似,根據資源的當前狀態和指望狀態來進行一致性調整,從而實現最終一致性
2.6 webhook
Knative是基於k8s的CRD實現的,其webhook主要包含對應資源數據的驗證和修改等admission相關
3. 總結
結合上面的組件功能猜測,大概猜測了核心的數據流的實現,如圖所示,咱們能夠分爲五層來考慮:觀測層(Queue和Activator)、決策層(Autoscaler)、控制層(Controller)、准入層(Webhook)、路由層(Istio INgress), 經過觀測層實時獲取用戶請求數據,發給決策層進行決策,並將決策結果寫入到Apiserver, 控制層感知,負責進行對應資源的更新,最終由路由層感知,進行流量分配,這樣就實現了總體流量的感知、決策、路由等核心功能,暫時就理解這些,後續但願隨着代碼的深刻,有更深的體會,祝我好運,good luck!
原文 https://www.yuque.com/baxiaoshi/tyado3/up5efq
微信號:baxiaoshi2020
關注公告號閱讀更多源碼分析文章
更多文章關注 www.sreguide.com