Knative 简介
本文作者來自螞蟻金服系統部之芥
什么是 Knative?
knative?是谷歌開源的 serverless 架構方案,旨在提供一套簡單易用的 serverless 方案,把 serverless 標準化。目前參與的公司主要是 Google、Pivotal、IBM、Red Hat,2018年7月24日才剛剛對外發布,當前還處于快速發展的階段。
?
這是 Google Cloud Platform 宣布 knative 時給出的介紹:
?
Developed in close partnership with Pivotal, IBM, Red Hat, and SAP, Knative pushes Kubernetes-based computing forward by providing the building blocks you need to build and deploy modern, container-based serverless applications.?
可以看出,knative 是為了解決容器為核心的 serverless 應用的構建、部署和運行的問題。
?
serverless 的概念已經出現蠻久了,為了理解 serverless 可以從應用開發者的角度來看,使用 serverless 框架之后,應用開發者的整個操作流程就變成了:
?
~ # 編寫 code 和 configuration 文件~ # faascli build ~ # faascli deploy ~ # curl http://myapp.com/hello hello, world from Awesome FaaS App!?
可以看到用戶只需要編寫代碼(或者函數),以及配置文件(如何 build、運行以及訪問等聲明式信息),然后運行 build 和 deploy 就能把應用自動部署到集群(可以是公有云,也可以是私有的集群)。
?
其他事情都是 serverless 平臺(比如這里的 knative)自動處理的,這些事情包括:
?
- 自動完成代碼到容器的構建
- 把應用(或者函數)和特定的事件進行綁定:當事件發生時,自動觸發應用(或者函數)
- 網絡的路由和流量控制
- 應用的自動伸縮
?
和標準化的 FaaS 不同,knative 期望能夠運行所有的 workload : traditional application、function、container。
?
knative 是建立在 kubernetes 和 istio 平臺之上的,使用 kubernetes 提供的容器管理能力(deployment、replicaset、和 pods等),以及 istio 提供的網絡管理功能(ingress、LB、dynamic route等)。
?
knative 核心概念和原理
?
為了實現 serverless 應用的管理,knative 把整個系統分成了三個部分:
?
- Build:構建系統,把用戶定義的函數和應用 build 成容器鏡像
- Serving:服務系統,用來配置應用的路由、升級策略、自動擴縮容等功能
- Eventing:事件系統,用來自動完成事件的綁定和觸發
?
Build 構建系統
build 的功能是把用戶的代碼自動化構建成容器鏡像,初次聽起來很奇怪,有了 docker 之后有一個 Dockerfile 不就能構建容器了嗎?為什么還需要一個新的 Build 系統?
?
Knative 的特別之處在于兩點:一是它的構建完成是在 kubernetes 中進行的,和整個 kubernetes 生態結合更緊密;另外,它旨在提供一個通用的標準化的構建組件,可以作為其他更大系統中的一部分。
?
正如官方文檔中的說的那樣,更多是為了定義標準化、可移植、可重用、性能高效的構建方法:
?
The goal of a Knative build is to provide a standard, portable, reusable, and performance optimized method for defining and running on-cluster container image builds.?
Knative 提供了?Build?CRD 對象,讓用戶可以通過 yaml 文件定義構建過程。一個典型的?Build?配置文件如下:
?
apiVersion: build.knative.dev/v1alpha1 kind: Build metadata:name: example-build spec:serviceAccountName: build-auth-examplesource:git:url: https://github.com/example/build-example.gitrevision: mastersteps:- name: ubuntu-exampleimage: ubuntuargs: ["ubuntu-build-example", "SECRETS-example.md"]steps:- image: gcr.io/example-builders/build-exampleargs: ['echo', 'hello-example', 'build']?
其中,serviceAccountName?是構建過程中需要用到的密碼和認證信息(比如連接到 git repo 的 SSH keys、push 鏡像到 registry 的用戶名和密碼等);source?是代碼信息,比如這里的 git 地址和分支;steps?是真正運行過程中的各個步驟,這個示例中的步驟只是作為 demo,真正的構建過程一般是 pull 代碼、 build 鏡像和 push鏡像到 registry 等邏輯。
?
因為大部分的構建過程都是一致的,因此 knative 還提供了?Build template?的概念,Build template 封裝了預先定義好的構建過程(就是封裝了上面的?steps?過程),并提供了非常簡單的配置參數來使用。
?
使用 build template 構建容器鏡像就更簡單了,只需要提供代碼的地址和鏡像名字即可,比如下面是使用 Google kaniko 模板構建 github 源碼的 yaml 文件(需要在代碼根目錄存在 Dockerfile 文件):
?
apiVersion: build.knative.dev/v1alpha1 kind: Build metadata:name: kaniko-build spec:serviceAccountName: build-botsource:git:url: https://github.com/my-user/my-reporevision: mastertemplate:name: kanikoarguments:- name: IMAGEvalue: us.gcr.io/my-project/my-app?
Serving:服務系統
?
serving 的核心功能是讓應用運行起來提供服務。雖然聽起來很簡單,但這里包括了很多的事情:
?
- 自動化啟動和銷毀容器
- 根據名字生成網絡訪問相關的 service、ingress 等對象
- 監控應用的請求,并自動擴縮容
- 支持藍綠發布、回滾功能,方便應用方法流程
?
knative serving 功能是基于 kubernetes 和 istio 開發的,它使用 kubernetes 來管理容器(deployment、pod),istio 來管理網絡路由(VirtualService、DestinationRule)。
?
因為 kubernetes 和 istio 本身的概念非常多,理解和管理起來比較困難,knative 在此之上提供了更高一層的抽象(這些對應是基于 kubernetes 的 CRD 實現的)。這些抽象出來的概念對應的關系如下圖:
?
?
?
?
- Configuration:應用的最新配置,也就是應用目前期望的狀態,對應了 kubernetes 的容器管理(deployment)。每次應用升級都會更新 configuration,而 knative 也會保留歷史版本的記錄(圖中的 revision),結合流量管理,knative 可以讓多個不同的版本共同提供服務,方便藍綠發布和滾動升級
- Route:應用的路由規則,也就是進來的流量如何訪問應用,對應了 istio 的流量管理(VirtualService)
- Service:注意這里不是 kubernetes 中提供服務發現的那個 service,而是 knative 自定義的 CRD,它的全稱目前是?services.serving.knative.dev?。單獨控制 route 和 configuration 就能實現 serving 的所有功能,但knative 更推薦使用 Service 來管理,因為它會自動幫你管理 route 和 configuration
?
一個 hello world 的 serving 配置如下所示:
?
apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata:name: helloworld-gonamespace: default spec:runLatest:configuration:revisionTemplate:spec:container:image: docker.io/{username}/helloworld-goenv:- name: TARGETvalue: "Go Sample v1"?
看起來和 kubernetes 的 pod 定義非常類似,但是它會幫你管理 deployment、ingress、service discovery、auto scaling……從這個角度來看,可以認為 knative 提供了更高的抽象,自動幫你封裝掉了 kubernetes 和 istio 的實現細節。
?
下面這張圖介紹了 knative serving 各組件之間的關系:
?
?
?
?
- 可以看到,每個 revision 對應了一組 deployment 管理的 pod
- pod 會自動匯報 metrics 數據到 autoscaler,autoscaler 會根據請求量和資源使用情況修改 deployment 的 replicas 數量,從而實現自動擴縮容。serverless 一個重要的特定是它會 scale to 0 的,也就是當應用沒有流量訪問時,它會自動銷毀所有的 pod
- activator 比較有趣,它是為了處理 scale to 0 而出現的。當某個 revision 后面的 pod 縮容到 0 時,route 的流量會指向 activator,activator 接收到請求之后會自動拉起 pod,然后把流量轉發過去
- route 對象對應了 istio 的 DestinationRoute 和 VirtualService,決定了訪問應用的流量如何路由
?
Eventing:事件系統
serving 系統實現的功能是讓應用/函數能夠運行起來,并且自動伸縮,那什么時候才會調用應用呢?除了我們熟悉的正常應用調用之外,serverless 最重要的是基于事件的觸發機制,也就是說當某件事發生時,就觸發某個特定的函數。
?
事件概念的出現,讓函數和具體的調用方能夠解耦。函數部署出來不用關心誰會調用它,而事件源觸發也不用關心誰會處理它。
?
Note:目前 serverless 的產品和平臺很多,每個地方支持的事件來源以及對事件的定義都是不同的(比如 AWS Lambda 支持很多自己產品的事件源)。Knative 自然也會定義自己的事件類型,除此之外,knative 還聯合 CNCF 在做事件標準化的工作,目前的產出是 CloudEvents 這個項目。
?
為了讓整個事件系統更有擴展性和通用性,knative 定義了很多事件相關的概念。我們先來介紹一下:
?
- EventSource:事件源,能夠產生事件的外部系統
- Feed:把某種類型的 EventType 和 EventSource 和對應的 Channel 綁定到一起
- Channel:對消息實現的一層抽象,后端可以使用 kafka、RabbitMQ、Google PubSub 作為具體的實現。channel name 類似于消息集群中的 topic,可以用來解耦事件源和函數。事件發生后 sink 到某個 channel 中,然后 channel 中的數據會被后端的函數消費
- Subscription:把 channel 和后端的函數綁定的一起,一個 channel 可以綁定到多個knative service
?
它們之間的關系流程圖如下:
?
?
?
?
Bus 是 knative 內部的事件存儲層,用戶可以選擇自己感興趣的實現,目前支持的方式有:Stub(在內存中實現的簡單消息系統)、Kafka、Google PubSub。如果想要事件能夠正常運行,必須在 knative 集群中安裝其中一個 bus 實現方式。
?
有了 bus 之后,我們就可以監聽外部的事件了。目前支持的事件源有三個:github(比如 merge 事件,push 事件等),kubernetes(events),Google PubSub(消息系統),后面還會不斷接入更多的事件源。
?
如果要想監聽對應的事件源,需要在 knative 中部署一個 source adaptor 的 pod,它負責從外部的系統中讀取事件。
?
讀取后的事件,會根據用戶配置的 Feed 對象(里面包括了事件源和 channel 的對應關系),找到對應的 channel,然后把消息發送到這個 channel 中(channel 的消息最終是存儲在后端的 bus 系統里的)。
?
然后,knative 會根據 subscription 的配置,不斷從 channel 中讀取事件,然后把事件作為參數調用對應的函數,從而完成了整個事件的流程。
?
Knative 目前的狀態
?
knative 是 2018 年 7月才剛剛對外開放,雖然內部已經開發一段時間,但是目前還處于非常早前的階段(從支持的事件源和 bus就能看出來)。目前代碼還不穩定,很多實現都是 hard-coded。
?
knative 也是脫產于 google 和 CNCF,因此整個社區運行方式和目標與之前的 kubernetes 以及 istio 非常相似。社區根據組件分成多個 Working Group,每個 Group 獨立負責自己的功能,所有的開源活動(文檔、視頻、代碼)都是開放的。另外,CloudEvents 作為 knative 依賴的標準,目標也是成為 CRI、CNI、CSI 這種類似的標準。
?
knative 社區目前非常活躍,已?github.com/knative/serving?項目為例,一個月已經有 600+ star,目前有 60+ contributor,900+ commits,而且入門的文檔和教程都已經非常全面。
?
?
?
?
?
Knative 應用場景和思考
?
knative 基于 kubernetes 和 istio 的 serverless 開源實現,目標是為了提供更高層次的抽象,讓開發者無需關注基礎設施(虛擬機或者容器,網絡配置,容量規劃),而專注于業務代碼即可。
?
目前 serverless 以及 knative 的幾個問題:
?
1. 性能問題
?
性能問題一直是 serverless 被人詬病的一點,也是目前它不能廣泛用于應用服務上的決定性原因。互聯網的應用大多數有高并發、高性能的要求,serverless 整個網絡鏈路很長,容器啟停需要額外的時間,還無法滿足互聯網應用的要求。
?
針對這一點,很多 serverless 框架也在不斷地做改進,比如不斷精簡容器的啟動時間、容器啟動之后會做緩存等,比如 nuclio 就宣稱自己的平臺比 AWS Lambda 要快 10 倍以上。
?
相信隨著 serverless 的不斷演進,性能問題會不斷優化,至于能不能達到互聯網應用的要求,還要時間給我們答案。
?
2. 是否需要 istio 這一層?
基于 kubernetes 的 serverless 組件非常多,比如 kubeless。但是基于同時又基于 istio,目前 knative 還是第一個這么做的。
?
有些人的疑問在于,knative 真的有必要基于 istio 來做嗎?對于這個問題,我個人的看法是必要的。
?
雖然 istio 才剛剛release 1.0 版本,但是它作為集群基礎設施通用網絡層的地位已經開始顯露,相信在未來的發展中接受度會越來越大,并逐漸鞏固自己的地位。雖然現階段來說,很多人并不非常熟悉 istio 的情況,但是從長遠角度來看,這一點將是 knative 的一個優勢所在。
?
另外,基于 istio 構建自己的 serverless 服務,也符合目前軟件行業不要重復造輪子的工作。istio 在集群的網絡管理方面非常優秀(智能路由、負載均衡、藍綠發布等),基于 istio 來做可以讓 knative 不用重復工作就能直接使用 istio 提供的網絡通用功能。
?
3. 系統復雜度
這一點和上面類似,knative 下面已經有兩個非常復雜的平臺:kubernetes 和 istio。這兩個平臺的理解、構建、運維本身就很復雜,如今又加上 knative 整個平臺,需要了解的概念都要幾十個,更不要提落地過程中會遇到的各種問題。
?
對于公有云來說,kubernetes 和 istio 這些底層平臺可以交給云供應商來維護(比如 google Function),但是對于內部構建來說,這無疑提高了整個技術門檻,對系統管理人來的要求更高。
?
如何安裝部署整個集群?如何對集群做升級?出現問題怎么調試和追蹤?怎么更好地和內部的系統對接?這些系統的最佳實踐是什么?怎么做性能優化?所有這些問題都需要集群管理人員思考并落實。
?
4. 函數的可運維性?
相對于編寫微服務來說,單個函數的復雜度已經非常低,但是當非常多的函數需要共同工作的時候,如何管理這些函數就成了一個必須解決的問題。
?
- 如何快速找到某個函數?
- 如何知道一個函數的功能是什么?接受的參數是什么?
- 怎么保證函數的升級不會破壞原有的功能?升級之后如何回滾?怎么記錄函數的歷史版本一方面追溯?
- 當有多個函數需要同時工作的時候,怎么定義它們之間的關系?
- 函數出現問題的時候如何調試?
?
對于函數的運維,一般的 serverless 平臺(包括 knative)都提供了 logging、metrics、tracing 三個方面的功能。默認情況下,knative 使用 EFK(Elasticsearch、Fluent、Kibana)來收集、查找和分析日志;使用 prometheus + grafana 來收集和索引、展示 metrics 數據;使用 jaeger 來進行調用關系的 tracing。
?
針對 serverless 衍生出來的運維工具和平臺還不夠多,如何調試線上問題還沒有看到非常好的解決方案。
?
5. knative 成熟度
最后一點是關于 knative 成熟度的,前面已經提到,knative 目前剛出現不久。雖然整個框架和設計都已經搭好了,但是很多實現都比較初級。這里提幾點來說:
?
- 為了實現 autoscaling,knative 在每個 pod 中添加一個叫做 queue proxy 的代理,它會自動把請求的 metrics 發送給 autoscaler 組件作為參考。這樣一來,整個網絡鏈路上又多了一層,對整個性能勢必會有影響,未來的打算是直接使用 envoy sidecar 來替換掉 queue proxy
- 支持的事件源和消息系統還還優先,外部事件只支持 github、kubernetes 和 Google PubSub。 這個問題可以慢慢擴展,knative 本身會實現很常用的事件類型,自定義的事件源用戶可以自己實現
- 目前還沒有函數的 pipeline 管理(類似 AWS Lambda Step Functions),多個函數如何協作并沒有自己處理。雖然沒有在官方文檔中看到這方面的 roadmap,但是以后一定會有這方面的功能(不管是 knative 本身來做,還是社區作為工具補充來實現)
?
這方面的問題都不是大事情,隨著 knative 版本的迭代,在很快的時間都能夠解決。
參考資料
?
- Google Cloud Platform 宣布 Knative 發布的博客文章:?Google Cloud Platform Blog: Bringing the best of serverless to you
- the Newstack 上非常好的科普文章:?Knative Enables Portable Serverless Platforms on Kubernetes, for Any Cloud - The New Stack
- Serving 的設計理念:https://docs.google.com/presentation/d/1CbwVC7W2JaSxRyltU8CS1bIsrIXu1RrZqvnlMlDaaJE/edit#slide=id.g32c674a9d1_0_5
- knative 官方文檔:GitHub - knative/docs: Documentation for users of Knative components
- Google Cloud Next 2018 大會上宣布 knative 的視頻 presentation:?Kubernetes, Serverless, and You (Cloud Next ’18) - YouTube
- Google Cloud Knative 產品頁面,目前只有最簡單的介紹和文檔鏈接:https://cloud.google.com/knative
歡迎關注技術公眾號:架構師成長營
?
總結
以上是生活随笔為你收集整理的Knative 简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习3 :用户及文件权限管理
- 下一篇: 李开复给中国大学生的第三封信:成功、自信