導讀
随着雲計算技術的發展,雲資源傳遞變的越來越簡單,按需使用已經成為可能。在按需使用資源的模式下,使用者更多的聚焦于業務自身,而減少了對基礎設施的關注,Serverless 理念也是以應運而生。我們知道 Kubernetes 已成為當今雲原生業界标準,具備良好的生态以及跨雲廠商能力。Kubernetes 很好的抽象了 IaaS 資源傳遞的标準, 但如果想要在 Kubernetes 之上以 Severless 的方式管理應用還是要做很多事情的。Knative 在 K8s 之上又做了進一步的簡化,大大降低了應用生命周期管控複雜度,同時提供了自動彈性和灰階釋出等能力,同時基于阿裡雲 Severless Kubernetes (ASK)提供的極緻容器化 Serverless,給您帶來雲原生 Serverless 應用完全體。本文會從如下 4 部分内容展開介紹:
- 為什麼需要 Knative
- Knative 簡介
- Knative 和 ASK 融合
- 示範示例
為什麼需要Knative
我們知道目前K8s 已經成為了雲原生事實上的作業系統,Kubernetes 對上通過資料抽象暴露基礎設施能力,比如 Service、Ingress、Pod、Deployment,這些都是通過 Kubernetes 原生 API 給使用者暴露出來的能力。而對下,Kubernetes 提供了基礎設施能力接入的标準接口,比如說 CNI、CRD,讓雲資源以一個标準化的方式接入到 Kubernetes 的體系中。今天我們來看 Kubernetes 所處的位置,實際上是承上啟下。雲原生的使用者使用 Kubernetes 的目的,都是為了傳遞和管理應用,當然也包括灰階釋出、擴容縮容等,并且兼顧資源成本。

但我們實際在使用Kubernetes過程中, 逐漸會發現如下問題:
- 通過 k8s API 實作服務全生命周期管理比較複雜
- 雲 IaaS 資源規格繁雜,每一種規格适用場景都所有不同,使用者很難自己組合所有規格
- 節省資源使用成本,彈性越來越重要
那麼如何才能簡單的使用容器(K8s)技術?如何随心所欲的實作按需使用,降低成本?答案就是:Knative


Knative 是在 2018 的 Google Cloud Next 大會上釋出的一款基于Kubernetes 的 Serverless編排引擎。Knative 一個很重要的目标就是制定雲原生、跨平台的Serverless 編排标準。Knative 是通過整合容器建構(或者函數)、工作負載管理(彈性)以及事件模型這三者來實作的這一Serverless 标準。Knative 社群的目前主要貢獻者有Google、Pivotal、IBM、Red Hat。另外像 CloudFoundry、OpenShift 這些 PAAS 提供商都在積極的參與Knative 的建設。
Knative 核心子產品

Knative 核心子產品主要包括事件驅動架構 Eventing 和部署工作負載的Serving。
Serverless 服務引擎 - Serving
Knative Serving 核心能力就是其簡潔、高效的應用托管服務,這也是其支撐Serverless 能力的基礎。當然作為SeverlesssFramework 就離不開按需配置設定資源的能力,Knative 可以根據您應用的請求量在高峰時期自動擴容執行個體數,當請求量減少以後自動縮容執行個體數,可以非常自動化的幫助您節省成本。Serving 還提供了的流量管理能力和靈活的灰階釋出能力。流量管理能力可以根據百分比切分流量,灰階釋出能力可以根據流量百分比進行灰階。
一個簡單的場景:基于流量灰階釋出
我們以一個簡單的流量灰階釋出為例,先看一下在k8s中如何實作。
我們建立一個提供外部通路的服務,在 K8s 中需要建立如下資源:
- Deployment: 部署應用的工作負載
- Service: 提供服務通路以及負載均衡的能力
- Ingress: 對外提供域名通路的功能
- HPA:我們實作按照負載(cpu、memory)自動彈性,需要建立HPA。
初始的時候,通過V1提供服務,這時候如果要灰階新的版本,那麼需要建立對應資源的V2版本,然後通過Ingress實作V1和V2版本直接的流量灰階。如圖:

我們可以看到在k8s中基于流量對灰階過程,我們需要對這些資源進行細粒度的控制,包括新版本對應資源的建立以及灰階完成之後舊版本資源的清理,對于使用者來說還是比較複雜的。那麼在 Knative 中,如何進行灰階釋出的呢?
- 建立 Knative 服務
- 更新 Knative 服務
- 調整版本流量比例
這裡我們隻需要操作Knative Service服務資源,對于新變更隻需要更新一下Knative Service資訊(如鏡像),就會自動建立一個新版本,灰階的規程隻需要在Knative Service中調整對應版本的流量比例即可。如下圖:

看了上面的灰階釋出,我們接下來對 Knative 應用模型做進一步介紹。
應用模型
Knative 提供了極簡的應用模型 - Knative Service,同時滿足服務部署、服務通路以及灰階釋出的能力。可以用下面的公式了解:Knative Service = 工作負載(Deployment)+服務通路(service)+灰階流量(Ingress) + 自動彈性。應用模型如圖:

- Service: 對 Serverless 應用模型的抽象,通過Service 管理應用的生命周期
- configuration: 用于配置應用期望的資訊。每次更新Service 就會更新Configuration
- revision: configuration的每次更新都會建立一個快照,用來做版本管理
- route: 将請求路由到Revision,并可以向不同的Revision 轉發不同比例的流量
豐富的彈性政策
作為 Serverless 架構,其核心能力就是自動彈性,Knative中提供了豐富的彈性政策:
- 基于流量請求的自動擴縮容-KPA
- 基于CPU、Memory的自動擴縮容-HPA
- 支援定時 + HPA的自動擴縮容政策
- 提供事件網關滿足事件精準分發政策
Knative 和 ASK 融合
這裡我們先來了解一下ASK。通常的我們使用K8s,需要提前準備 IaaS 資源才能部署應用,這無疑違背了serverless的 初衷。那麼我們能否擺脫IaaS的束縛, 不必提前進行IaaS資源規劃呢?答案就是:ASK
ASK是阿裡雲推出的無伺服器Kubernetes。使用者無需購買節點即可直接部署容器應用,無需對叢集進行節點維護和容量規劃。ASK叢集提供完善的Kubernetes相容能力,同時極大降低了Kubernetes使用門檻,讓使用者更專注于應用程式,而不是管理底層基礎設施。

- 免運維:開箱即用,無需節點管理、運維及安全維護。
- 極緻彈性擴容:無需容量規劃,秒級擴容,30s 擴容 500 POD執行個體。
- 低成本:按需建立POD,支援 spot(搶占式執行個體)、預留執行個體券
- 相容k8s:支援deployment/statefulset/job/service/ingress/crd等
- Knative: 基于流量的應用自動彈性、縮容到保留執行個體
- 存儲挂載:支援雲盤、NAS、OSS存儲卷
- Elastic Workload: 支援 eci 按量和 spot 混合排程
- 內建ARMS/SLS等雲産品
Knative 運維複雜度
了解了ASK,我們接下來看一下目前Knative 自身面臨的一些問題:
- Gateway 網關。Knative 社群提供Istio網關能力,但Istio元件較多,使用者在管控這些元件時需要付出資源及運維成本。(雖然目前社群已經解耦了Istio, 使用者可以自行選擇更多輕量級的網關,但是資源及運維成本依然需要投入)
- Knative 管控元件。目前需要運維 7 個管控元件,需要使用者額外投入資源及運維成本
- 冷啟動問題。Serverless 繞不開應用冷啟動的問題,0到1的時候需要考慮如何保證服務的快速響應。

對于上述問題,我們在ASK Knative 中提供了如下的能力。
Gateway 和 SLB 融合
通過阿裡雲 SLB 提供網關能力:
- 降成本:減少了十幾個元件,大大降低運維成本和 IaaS 成本
- 保穩定:SLB 雲産品服務更穩定、可靠性更高,易用性也更好
k8s 原生Serverless 實踐:ASK 與 Knative

管控元件下沉
将 Knative 管控元件進行托管:
- 開箱即用:使用者直接使用 Serverless Framework,不需要自己安裝
- 免運維、低成本:Knative 元件和 K8s 叢集進行融合,使用者沒有運維負擔,也無需承擔額外的資源成本
- 高管控:所有元件都在管控端部署,更新和疊代更容易

保留執行個體
解決從 0 到 1冷啟動的問題:
- 免冷啟動:通過保留執行個體消除了從 0 到 1 的 30 秒冷啟動時間
- 成本可控:突發性能執行個體成本比标準規格執行個體降低 40% 的成本,如果和 Spot 執行個體結合還能再進一步降低成本
- 在 ASK 叢集中安裝 Knative
- 部署 helloworld 應用并通路
目前支援在建立 ASK 叢集時選擇安裝 Knative, 也可以在ASK叢集部署完成之後在應用 > Knative 中通過元件管理頁簽單擊一鍵部署Knative。在已有的ASK叢集部署 Knative 操作如下:
- 登入 容器服務管理控制台 。
- 在控制台左側導航欄中,單擊叢集。
- 在叢集清單頁面中,單擊目标叢集名稱或者目标叢集右側操作列下的詳情。
- 在叢集管理頁左側導航欄中,選擇應用 > Knative。
- 在Knative的元件管理頁簽單擊一鍵部署Knative。
- 選擇需要安裝的Knative元件後,單擊部署。
Knative 部署完成之後,結果如圖:


- 單擊建立。建立完成後,您可以在服務管理頁簽的清單中,看到新建立的服務。點選服務名稱,進入服務詳情頁,内容如下:

- 服務通路。
我們将域名綁定Host通路,也可以直接通過curl指令通路如下:
$ curl -H "host: helloworld-go.default.example.com" http://39.106.199.35
Hello World!
在沒有請求通路等時候(持續時間90s沒有通路),會預設縮容到保留執行個體:
$ kubectl get po |grep hello
helloworld-go-v6z2l-deployment-754dc6c64d-89jlj 2/2 Terminating 0 6m28s
helloworld-go-v6z2l-deployment-reserve-6bf95f6746-mq2wq 2/2 Running 0 116s
待保留執行個體 Ready 之後,會将正常執行個體下線掉。
總結
本文介紹了為什麼需要Knative, Knative 核心子產品 Serving , 同時通過在ASK的融合,降低Knative 運維及資源成本,最後我們通過一個示例示範了在 ASK 部署并通路 Knative 服務、縮容到保留執行個體。歡迎有興趣同學關注 Knative 釘釘交流群。
