天天看點

基于 Knative 打造生産級 Serverless 平台 | KubeCon NA2019一. 分享概要二. 解決性能問題:使用 Pod 預熱池三. 降低成本:共享控制面元件四. 解決容量問題:每個層級都做好對分片的支援五. 結束語

本文推薦知道的背景知識:

  1. Kubernetes 的基本原理和各大元件的職責;
  2. Serverless 計算的基本概念和它的優勢;
  3. Plus: 對社群 Knative 項目的基本了解;

本文根據董一韬和王轲在 KubeCon NA 2019 大會分享整理。

董一韬 螞蟻金服,産品經理,緻力于驅動雲計算相關産品,包括雲原生 PaaS 平台、容器與 Serverless 産品等,與最終顧客緊密合作,幫助客戶在規模化的金融場景下采用與落地雲原生相關解決方案。

王轲 螞蟻金服,軟體工程師,建設基于 Kubernetes/Knative 的企業級 Serverless 産品,Knative 的早期使用者,Kubernetes 社群成員、控制面流控早期維護者,長期緻力于用創新的方式優化、落地雲原生技術。

一. 分享概要

Knative 是 Google 主導的基于 Kubernetes 的 Serverless 平台,在社群上有較高的知名度。然而,身為社群項目的 Knative 主要關心的是标準、架構。雖有先進的理念,卻離可在生産上使用有不少的差距。

本次 KubeCon 的演講中,來自螞蟻金服 SOFAStack-PaaS 平台産品技術團隊的隐秀和仲樂與大家分享螞蟻金服金融科技 Knative 的實踐和改造:基于 Knative 建構一個優秀的 Serverless 計算平台,詳細分析如何用獨特的技術,解決性能、容量、成本三大問題。

從 Serverless 計算的應用場景開始,提煉客戶真正的 Use Case,分公有雲、私有雲、行業雲等,講述 Serverless 計算的多種用途。之後我們将介紹在 Kubernetes 上運作 Knative 平台的方案,詳細介紹要使其生産可用,不得不克服的問題。演講最後,将剛剛的這些問題一一攻破,做出一個比社群版本優秀的 Knative 平台。

基于 Knative 打造生産級 Serverless 平台 | KubeCon NA2019一. 分享概要二. 解決性能問題:使用 Pod 預熱池三. 降低成本:共享控制面元件四. 解決容量問題:每個層級都做好對分片的支援五. 結束語

二. 解決性能問題:使用 Pod 預熱池

熟悉 Kubernetes 的同學可能知道,Kubernetes 的首要目标并不是性能。

在一個大規模的 Kubernetes 叢集下,要建立一個新的 Pod 并讓它跑起來,是很慢的。這是因為這整個鍊路很長:先要向 APIServer 發一個 POST 請求,再要等 Scheduler 收到新 Pod 資源被建立的事件,再等 Scheduler 在所有的 Node 上運作一遍篩選、優選算法并把排程結果傳回給 API Server,再到被選中 Node 的 Kubelet 收到事件,再到Docker 鏡像拉取、容器運作,再到通過安全檢查并把新的容器注冊到 Service Mesh 上…

任何一個步驟都有可能出現延時、丢事件,或失敗(如排程時資源不足是很常見的)。就算一切都正常工作,在一個大規模的 Kubernetes 叢集裡,整個鍊路延時達到20s,也是很常見的。

這便導緻在 Kubernetes 上做 Serverless 的窘境:Serverless 的一大特點是自動擴縮容,尤其是自動從0到1,不使用時不占任何資源。但如果一個使用者用 Serverless 跑自己的網站/後端,但使用者的首個請求花費20s才成功,這是無法接受的。

為了解決冷啟性能問題,我們團隊提出了一個創造性的解決方案:使用 Pod 預熱池(Pod Pool)。

基于 Knative 打造生産級 Serverless 平台 | KubeCon NA2019一. 分享概要二. 解決性能問題:使用 Pod 預熱池三. 降低成本:共享控制面元件四. 解決容量問題:每個層級都做好對分片的支援五. 結束語

我們的産品會預先建立許多個 Pod 并讓它們運作起來,當 Kubernetes 的控制器希望建立一個新的 Pod 的時候,我們不再是從零開始建立一個 Pod,而是找到一個處于待命狀态的符合條件的 Pod,并把代碼注入這個 Pod,直接使用。

在演講中,我們分享了一定技術實作的細節,例如如何建立 CRD 并 fork Kubernetes 的 ControllerManager,來以較小的成本實作新 Workload;如何自動根據曆史的使用資料來自動伸縮 Pod 池的水位;如何做代碼注入等。我們提了3種方式,分别是給容器發指令讓容器中的程序下載下傳并執行代碼包、使用 Ephemeral Container、魔改 Kubelet允許替換 Container。

實際的實作比這個還要複雜,要考慮的問題更多,例如如何響應 Pod 中不同的資源 request、limit。我們實際上也實作了一個排程器。當某個預熱好的 Pod 不能滿足,會看那個 Pod 所在 Node 上的資源餘量,如果餘量夠則動态改 Kubernetes 控制面資料和 cgroups,實作“垂直擴容”。

實際操作證明,這個冷啟優化的效果非常好,當 Pod 大小固定、代碼包緩存存在時,啟動一個最簡單的 HTTP 伺服器類型應用的耗時從近20秒優化到了2秒,而且由于不需要當場排程 Pod,從0到1的穩定性也提升了很多。

這個優化主要是跳過了若幹次 API Server 的互動、Pod Schedule 的過程和 Service Mesh 注冊的過程,使用者程式從零到一的體驗得到極大的提升,又不會招緻過多的額外成本。一般來講多預留10-20個 Pod 就可以應付絕大多數情況,對于少見的短時間大量應用流量激增,最壞情況也隻是 fallback 到原先的新建立 Pod 的鍊路。

Pod 預熱池不光可以用來做冷啟優化,還有很多其他的應用場景。演講中我呼籲将這種技術标準化,來解決 Kubernetes 資料面性能的問題。會後有觀衆提出 cncf/wg-serverless 可能有興趣做這件事情。

三. 降低成本:共享控制面元件

在成本方面,我們和大家分享了多租戶改造和其他的降低成本的方式。

如果以單租戶的方式運作社群版的 Knative,成本是昂貴的:需要部署 Kubernetes 控制面和 Service Mesh 控制面,因為這些都是 Knative 的依賴,Knative 本身的控制面也很占資源。十幾C幾十G 的機器就這樣被使用了,不産生任何業務價值。是以,共享這些控制面的元件是非常必要的。

基于 Knative 打造生産級 Serverless 平台 | KubeCon NA2019一. 分享概要二. 解決性能問題:使用 Pod 預熱池三. 降低成本:共享控制面元件四. 解決容量問題:每個層級都做好對分片的支援五. 結束語

通過共享,使用者不必再單獨為基礎設施買單。控制面的成本也隻和每個租戶建立的應用的數量之和有關,而不會再和租戶多少産生關聯。

我們推薦兩種共享的方式,一種是 Namespace 隔離+ RBAC 權限控制,這種控制面共享的方法是最簡單、Kubernetes 原生支援,也廣為使用的一種方法。另一種方法是螞蟻金服金融科技自研 Kubernetes 實作的多租戶方案,通過在 etcd 中多加一級目錄并把每個使用者的資料存在他們自己的目錄中,實作真正全方位多租戶的

Kubernetes。

演講中還提到了其他的一些降低成本的方法,如通過 Virtual Kubelet 對接阿裡雲的 ECI(按需的容器服務)、通過 Cluster AutoScaler 來自動釋放使用率低的 Kubernetes 節點或從阿裡雲購置 ECS 來增加新的節點以水準擴容等。還簡單提了一下多個租戶的容器共享同一個主控端可能面臨的安全問題,如 Docker 逃逸。一種可能的解決方法是使用 Kata Container(虛拟機)以避免共享 Linux 核心。

四. 解決容量問題:每個層級都做好對分片的支援

容量方面的挑戰在于當 Workload 數量增多後,無論是 Knative 各控制器/資料面元件還是 Kubernetes 控制面本身還是 Service Mesh,都會面臨更大的壓力。要解決這個問題并不難,隻要在從上到下每個層級都做好對分片的支援。

上遊系統給每個 APP 建立一個分片 ID,下遊就可以部署多組控制面元件,讓每一組元件處理一個分片 ID。

基于 Knative 打造生産級 Serverless 平台 | KubeCon NA2019一. 分享概要二. 解決性能問題:使用 Pod 預熱池三. 降低成本:共享控制面元件四. 解決容量問題:每個層級都做好對分片的支援五. 結束語

要完整支援分片,我們需要改造控制面各控制器、資料面的 Knative Activator,和 Service Mesh。

控制器的改造非常容易,隻需要在 Informer 中添加 LabelSelector,其值為分片 ID,控制器就隻能看到那個分片 ID下的所有資源,自動無視其他資源了。每組控制器都設定不重疊的 LabelSelector,我們就可以同時運作多組互不幹擾的控制器。因為控制器調和是無狀态且幂等的,對于每一個分片 ID,我們仍然可以以主主的方式部署多個副本以實作高可用。

接下來是資料面 Activator 的改造,其主要挑戰是如何找到每個應用對應的 AutoScaler(因為 AutoScaler 也被分片,部署了多份)。這裡可以通過域名的方式來做尋址,把分片 ID 作為域名的一部分,然後搭配 DNS 記錄或 Service Mesh,将 Activator 的封包路由到某個分片的 AutoScaler 裡。

最後是 Service Mesh 的改造,預設情況下每個 Service Mesh 中的 Sidecar 都包含别的 Pod 的資訊,是以一個含有 n 個 Pod 的 Mesh 的資料量是 O(n2)。通過 ServiceGroup,我們可以将一個 Service Mesh 分割成多個子 Service Mesh,并設為僅每個子 Service Mesh 中的 Sidecar 互相可見,來解決資料量在規模增長下激增的問題。自然的,每個子 Service Mesh 需要單獨設定一個 Ingress,但這也有好處:每個 Ingress 的壓力不會過高。如果要跨子 Service Mesh 通路,那可以走公網 IP 等,通路另一個子 Service Mesh 的 Ingress。改造完以上所有東西後,在單個 Kubernetes 叢集裡,就可以無限水準擴容了。

但當 Workload 多到一定程度,Kubernetes 控制面本身也可能成為瓶頸。這個時候,我們可以再部署一個Kubernetes,并把某些分片放到那個新的 Kubernetes 叢集裡,這算是更進階别的分片。巧的是,本屆 KubeCon一大火熱話題也是多 Cluster:把你的全套應用打包帶走,一鍵建立新 Kubernetes 叢集并全量釋出,統一運維和更新…

五. 結束語

基于 Knative 打造生産級 Serverless 平台 | KubeCon NA2019一. 分享概要二. 解決性能問題:使用 Pod 預熱池三. 降低成本:共享控制面元件四. 解決容量問題:每個層級都做好對分片的支援五. 結束語

本次分享不到40分鐘,現場觀衆約150人,關注653人,YouTube 觀看目前近200人。KubeCon 的确是很不錯的技術會議,有很多專業人士。更加棒的是那種包容、自由、分享的氛圍,讓人覺得自己是一個很大 Community 的一份子,一同進步與革新,一同做一些了不起的事情。

本次 KubeCon,我們将螞蟻金服内部的一些技術成果帶了出去和大家分享,也從這個 Community,見識了大家在搞的新技術、新産品,有很多非常棒,很值得借鑒。

在雲原生 Serverless 平台模式下,我們需要處理的場景和待解決的問題還非常多,資料規模也在不斷的增長,歡迎緻力于雲原生領域的小夥伴們加入我們,我們一起探索和創新!

分享演講視訊回顧:

https://www.youtube.com/watch?v=PA1UoLPf4nE

P.S. 團隊長期招人、歡迎轉崗。産品、研發、測試,base支付寶上海S空間!

技術崗 → 淩真([email protected])、仲樂([email protected])

産品崗 → 隐秀([email protected])

繼續閱讀