京東雲的雲原生理念及 Serverless 最佳實踐

在雲原生技術全面爆發以前,咱們開發的應用能夠被稱爲非雲原生應用,非雲原生應用並無考慮到應用的彈性和規模性,甚至不少都不具有擴展性,當業務規模擴大時,特別依賴硬件的升級,進而帶來了不少問題。雲原生的出現帶來了新的開發方式,然而這一技術處於快速的發展過程當中,致使很難定義清楚各種概念和理解各類技術名詞。前端

爲此,Infoq專門採訪了京東雲中間件團隊負責人李道兵,瞭解京東雲在雲原生領域的理念和相關探索,以期對開發者有所幫助。如下爲本次採訪的整編內容。編程

現在,企業很難在聊雲原生這個話題時避開容器,可是往回倒四年,容器在國內的應用並不廣泛,大多集中在技術實力較強的互聯網大廠,但也並不是後來大火的 Docker,當時的很多文章還將這羣早期實踐者稱做「勇於吃螃蟹的人」。顯然,在雲原生領域,容器的發展是推進其落地的重要條件,但最大的需求並非爲了使用容器,這個邏輯自己就很奇怪,爲了出現而出現的技術每每不會有好的結局,容器所解決的問題纔是組織或開發者最大的需求。那麼,組織現階段對雲原生實踐最大的需求是什麼呢?後端

過去幾個月,InfoQ 前後就雲原生這一話題採訪了阿里巴巴、騰訊、青雲、竟然之家、華爲等衆多廠商,對值得關注的開源技術及相關落地實踐進行了初步探索。本文,InfoQ 對京東雲中間件產品研發部高級總監李道兵進行了獨家專訪,瞭解京東雲在雲原生領域的理念和相關探索。api

雲原生理念

關於雲原生,其實每篇相關文章都會特地留出一部分講解企業的理念,也屢次提到了 Pivotal 公司的 Matt Stine 寫的一本叫作遷移到雲原生應用架構的小冊子以及 CNCF 在今年 KubeCon 上海站提出的定義(V1.0): 雲原生技術有利於各組織在公有云、私有云和混合雲等新型動態環境中,構建和運行可彈性擴展的應用。雲原生的表明技術包括容器、服務網格、微服務、不可變基礎設施和聲明式 API。安全

可是,正如李道兵在接受採訪時所言:「與其說雲原生涉及了衆多理念,不如說如今社區尚未找到最佳實踐應該是什麼樣子。」正因如此,每篇文章都會花費一些篇幅介紹本文所討論的雲原生理念的範圍。服務器

相比於「雲原生」這個名字的誕生,李道兵認爲這一律唸的出現能夠追溯到更早以前。架構

2008 年,經過將 cgroups 的資源管理能力和 Linux Namespace 的視圖隔離能力組合在一塊兒,LXC(Linux Container)這樣的完整的容器技術出如今了 Linux 內核當中。固然,在這以前的虛擬機的概念此處就不贅述了,李道兵介紹道,LXC 比虛擬機輕量不少,但能夠達到大部分虛擬機的效果,隔離性和安全性卻不夠好。併發

在這以後,Docker 項目的正式發佈是對雲原生領域產生深遠影響的重要事件。李道兵補充道,Docker 真正的成功在於 Docker Hub,也就是官方維護的公共倉庫,其內存儲了大量鏡像。其次就是構建鏡像的方法,Docker 構造鏡像的方法比其餘的簡單不少,也能更輕鬆地利用其餘人的已有成果。總之,Docker 的出現大幅下降了微服務的運維負擔,讓微服務能真正成爲一個能夠大面積推廣的技術。在服務拆分以後,組織就會出現服務治理的需求,包括服務發現、服務伸縮、日誌收集、問題定位等,隨即就出現了不少相似 Mesos、Kubernetes 的技術,作服務的方式由原來的用 Java 寫完後跑在 Tomcat 上演變成將服務部署在容器之上,再利用 Kubernetes 進行管理,開發者已經不須要操心服務器的事情,這一系列由此產生的新理念能夠稱之爲「Cloud Native(雲原生)」。框架

不難看出,容器是雲原生得以落地的重要條件,但這背後的真正訴求則是開發者對服務治理和去運維化的需求,能夠認爲在雲原生時代,系統運維這個角色可能徹底消失掉,由於不須要操心服務器,天然就無運維,容器鏡像能夠直接將一個應用運行所需的完整環境,即:整個操做系統的文件系統所有打包進去,這纔是容器得以大面積普及的緣由。換句話說,這樣的服務交付方式纔是開發者的真正訴求。less


雲原生最佳實踐

正如開篇所言,如今談到雲原生實踐很難避開容器這個話題,一樣也很難避開Kubernetes(k8s),這就好像曾經的 Hadoop 是大數據領域的事實標準同樣,但 Kuberntes 的複雜性也是有目共睹的,李道兵表示:「我認可 Kubernetes 底層體系的重要性,但它的接口真的不夠簡單。相比較而言,早些年穀歌推出的 Google App Engine 反而是對將來很好的示範,但很惋惜,因爲種種緣由(當時雲的概念尚未起來、在 AppEngine 寫一個有狀態服務很是困難、對 AppEngine 的性能分析和優化困難等),Google App Engine 並無得到很好的反響。但就這個層面來說,將來,咱們應該能夠獲得比 Kubernetes 友好得多的界面。」

既然如此,爲何 Kubernetes 頂着「複雜性」的帽子還能夠發展得如此迅速呢?李道兵認爲,首先,底層的複雜性是不可避免的,開發者只能在上層經過合適的抽象來簡化使用界面;其次,過去幾年採用 K8s 大都是技術好的團隊,他們能駕馭這種複雜性,同時還能從底層的靈活性中獲益。但最近幾年隨着 K8s 的更普遍採用,這個問題就愈發嚴重了,也有不少項目在嘗試解決這個問題。

那麼,K8s 是否會被新的框架取代呢?李道兵認爲這個問題能夠類比爲編程語言來看待,好比「Java 就足夠好到把全部編程語言都比下去嗎?」這也未必,當年,Java 確實好到足以淘汰 COBOL(如今依舊有一些企業在使用),但一旦 Java 被大面積採用,你淘汰 Java 就須要比 Java 好一個數量級的語言出現。因此,儘管出現了一些針對 Java 做出改進的語言,好比 Groovy、Scala 等,但仍然沒法撬動 Java 在企業市場的佔有率,畢竟對於整個 IT 業界,作出決定更換編程語言是要耗費不少成本的。同理,Kubernetes 仍是有很是多優勢的,而且已被普遍採納,因此要被取代其實很難。

現在,在 Kubernetes 上進行探索的大部分企業以技術見長的互聯網大廠爲主,這些企業有動力也有能力選擇 Kubernetes,由於搞得定。可是,爲了面向更加普遍的用戶,Kubernetes 社區一直沒有中止在這個領域的持續探索,並已經取得一些關鍵性突破。所以,雲原生領域的核心技術實際上是處在不斷的發展和變化之中,如今很難對最佳實踐給出定論。


京東雲的雲原生實踐

京東雲雖然是一個雲服務的提供者,但其內部也須要進行雲原生改造,好比京東雲提供的對象存儲服務,其下的數十個組件一樣有服務治理的需求。所以,京東雲在這個過程當中有不少 Service Mesh 相關實踐,主要是經過 Service Mesh 的 sidecar 將本來須要寫在代碼中的邏輯替換掉,而微服務改造和容器化能夠認爲在此以前已經陸續完成(若是對這部分感興趣,能夠閱讀《專訪京東雲:願雲原生再也不只有 Kubernetes》,本文不做爲重點介紹)。

在 Service Mesh 方面,目前比較有表明性的開源工具就是 Istio。

如上圖,Istio 的核心組件主要包括 Proxy 代理、Mixer 混合器、Pilot 引導、Citadel 堡壘和 Galley。其中,Proxy 代理的代理組件主要是 Envoy,用來攔截全部想攔截的流量;Mixer 混合器混合了各類策略以及後端數據採集或遙測系統的適配器,實現了前端 Proxy 與後端系統的隔離與匯合;Pilot 引導提供了一系列 rules api,容許運維人員指定一系列高級的流量管理規則;Citadel 堡壘管理着集羣的密鑰和證書,是集羣的安所有門;Galley 主要是用來驗證用戶編寫的 Istio api 配置。

目前來看,Istio 並無太大的問題,但李道兵表示,Envoy 可能成爲 Istio 發展的阻礙,Envoy 自己是用 C++ 編寫的,主要由核心團隊維護,社區參與度通常。Envoy 支持了多種調用機制,但仍然不能知足部分工業界的需求(好比 Backup Request),而 Envoy 的複雜性又限制了使用者自行擴展,不排除將來 Envoy 會被更靈活的 Sidecar 組件替代掉。

除此以外,過去一段時間,京東雲在 Serverless 層面進行了大量實踐,這也是京東雲總體改造中很是重要的一個環節。


Serverless 實踐

2019 年,Serverless 被 Gartner 稱爲最有潛力的雲計算技術發展方向,並被賦予是必然性的發展趨勢。Serverless 從底層開始變革計算資源的形態,爲軟件架構設計與應用服務部署帶來了新的設計思路。在行業內,對 Serverless 的解讀並無公認的準肯定義,京東雲認爲 Serverless 技術目前有三種實現:

  • 真正的無服務器,就是所謂的函數計算 FaaS;
  • 相似京東雲的原生容器,容器直接呈現給用戶,而且背後不須要有虛擬機來支持;
  • 應用比較普遍的無服務器,背後虛擬機由雲廠商來提供,可是對用戶不可見,仍然是以虛擬機的方式來提供容器。

目前,京東雲在 Serverless 還在開發中,完整的 Serverless 實踐須要包括以下幾個模塊:

  • 負責提供計算能力的 FaaS
  • 負責提供通訊能力的 Queue Service 和 Notification Service
  • 負責提供持久化能力的 Serverless KV 和 Object Storage
  • 負責提供入口的 API Gateway
  • 負責提供編排能力的 Step Function

京東雲已經提供了 FaaS, Queue Service, Object Storage 和 API Gateway, 其餘模塊也會在近期陸續發佈。

FaaS

在 FaaS 層面,京東雲和 AWS 的 Lambda 以及 Azure 的 Function 相似,都是須要用戶提供一段代碼,這段代碼以 HTTP 的入口形式能夠訪問。代碼能夠用 Java 等多種語言寫出,處理完用戶請求後給出必定反饋,總體代碼的生存週期就是請求的處理過程。代碼是由函數計算來提供包括 CPU、內存、語言平臺等運行環境,用戶徹底不用關心代碼運行在什麼地方。

當併發請求很是多時,平臺就會運行這段代碼容器的多個副本,這樣就能作到:用戶無需預留計算資源,僅根據調用的時長、次數來付費。這種狀況是目前爲止計算資源能作到的最小化分配粒度。粒度越小時,越有可能填滿服務器的計算能力,粒度越大,後期就可能有越多的計算能力被閒置。

李道兵表示,FaaS 的優點和劣勢都很明顯,主要優點包括:完全的無運維、近乎無限的伸縮能力和零啓動成本。劣勢則包括:冷啓動比較慢,相對常規服務延時較高、壓力穩定時沒有成本優點。不過這些劣勢並非 FaaS 的本質形成的,而是能夠解決掉的問題,在解決掉這些問題以後,FaaS 就能得到更大的適用範圍和更遠大的前景。

現階段,FaaS 比較適合的應用場景主要有兩類:一是事件驅動型應用,好比 IoT、網頁遊戲等類型;二是實驗性項目,這類項目租用虛擬機的成本比較高,而 FaaS 幾乎是零成本,不調用的狀況下不會產生開銷。目前還有一個趨勢是逐步用 FaaS 取代 AppEngine。京東雲目前將 FaaS 應用在多媒體內容分析處理和 Serverless 後端服務兩個場景:

  • 經過對象存儲上傳事件能夠觸發多個函數,完成實時圖片或文件篩選、轉存、建立縮略圖、轉換視頻編碼等處理分析。經過事件觸發機制,您可以快速部署複雜的應用與服務,構建一個彈性、可靠的後端系統。
  • 經過函數服務和 API 網關構建後端,以驗證和處理 API 請求。採用函數服務構建可靈活拓展架構,輕鬆創造豐富、個性化的應用程序體驗。

如上,京東雲目前的 FaaS 主要支持 Python 2&3 和 Nodejs 6&8,這二者是目前 FaaS 適用場景中使用較多的語言,而接下來也會陸續支持 Java 和 PHP 等編程語言,畢竟幾行代碼就能夠處理的事件一般開發者更願意用 Python 而不是 Java。籠統地說,能夠經過 K8s 和 Docker 來實現的服務,也能夠選擇用 FaaS 實現,但要認清楚 FaaS 的優劣。李道兵表示,FaaS 的冷啓動是業界目前在共同努力解決的問題,這個概念很好理解,就是指函數第一次調用時平臺部署函數實例的過程。

在本地調用函數時,響應基本是實時的,而云上的 FaaS 須要部署計算環境,這個過程的時間從數百毫秒到數秒不等,難於應對時延敏感型應用;此外,FaaS 的優點是極度彈性伸縮,這讓其在調用量降低時會進行資源回收清理,下次調用時則又須要冷啓動,這個過程一直反覆存在於服務的整個生命週期中。

李道兵表示,京東雲在這方面進行了很多嘗試,主要能夠分爲兩部分:一是加快原生容器(下文將介紹這一律念)和雲硬盤的啓動速度,甚至說在雲硬盤加載以前先按需加載數據;二是預留部分實例,須要的時候再啓動,不過這未必適合全部場景,當 FaaS 運行在客戶的 VPC 中時,使用的是 VPC 中的資源,第二種方案暫時並不適用。

目前,業界也有一些方案,好比 Kata、Firecracker 對 qemu,虛擬機鏡像作裁剪來加速虛擬機的建立和啓動,可是效果並無那麼好。李道兵表示,虛擬機啓動慢的問題並非第一天出現,所以沒有那麼好解決,而容器的問題則是安全性不夠高,若是容器足夠安全,也不須要造虛擬機了,直接物理機上運行能夠節省很多時間,而原生容器算是平衡各類利弊後的一個不錯的嘗試。

隊列服務

根據瞭解,京東雲的隊列服務(Queue Service)是一項基於 Serverless 架構的全託管消息隊列服務,它能夠提供高可靠而且幾乎無限擴展的託管消息隊列。

如上圖是隊列服務的架構圖,主要分爲底層分佈式存儲、功能及解決方案、安全管理及用戶接入四層,其特色是毫秒級自動伸縮和無規格限制。在消息類型上,標準隊列理論上無限制的 TPS 上限,最大努力的消息排序以及至少一次消息傳達;FIFO 隊列保證消息的傳達順序與消息發送順序一致以及精確的一次性處理。主要的應用場景是以下兩種:

  • 異步解耦,削峯填谷。上下游系統處理能力存在差距的時候,利用隊列做爲數據的緩衝器,增長系統架構的可用性和可靠性,平滑處理峯值流量,解耦系統架構,避免對業務主流程的影響。
  • 性能擴展,容錯處理。因爲隊列服務會解耦分離用戶應用的處理進程,所以對於有擴展需求的應用,能夠輕鬆提升從隊列服務發送或接收速率來增長用戶應用的處理能力,對於部分故障的模塊能夠從整個系統中摘除。

原生容器

原生容器與普通意義的容器仍是有一些差異,一般容器會被認爲是在 PaaS 層,由 PaaS 團隊負責,而原生容器在京東雲內部屬於 IaaS 團隊,這也能夠看出原生容器與底層的關聯比較密切。簡單來講,能夠將原生容器理解爲普通容器和削薄後的虛擬機的結合體。

如上文所言,容器的安全性和隔離性是很大的問題,一旦容器被入侵,入侵者很容易經過穿透容器到達下面的物理機,從而影響整個雲平臺上的用戶,雖然這也是老生常談的問題,但要想既保證性能和啓動時間不受影響,又達到更高的安全級別,這自己就是一件棘手的事情,常規的安全手法成本又過高,最好的方式是將虛擬機隔離起來,經過這個彌補容器安全性上的不足,當容器被入侵時,入侵者不至於影響整個雲平臺的用戶。同時,原生容器對虛擬機作了大幅簡化,資源損耗和啓動時間均有所下降,這就是所謂的原生容器的概念。坦白地說,用戶申請的每個原生容器裏面跑的就是一個 Docker 或者 Pod。

在原生容器方面,京東的產品推出時,Kubernetes 還沒這麼流行。因此爲了實現節點容量的無限大,是經過一個叫 virtual kubelet 的插件讓 Kubernetes 集羣擁有一個虛擬節點。而現在,原生容器徹底看用戶需求。若是是一次性的任務處理批量計算工做,這種方式很是有效,由於虛擬節點可能會在某些方面不能實現 Kubernetes 全部的接口,某些特殊應用可能須要必定的適配工做,例如 daemonset。京東雲正在考慮把原生容器運行的節點暴露出來,並提供和如今 Kubernetes 全部接口兼容的一個應用。而在 Docker 方面,京東雲但願能向輕量化發展,能夠隨時建立、隨時銷燬,而且能夠隨時隨地建立更多的副本。

此外,京東雲也但願能將原生容器和 Kubernetes 經過比較緊密的方式結合在一塊兒。好比在 Kubernetes 裏的 Kata Container,其在 Kubernetes 裏使用了更安全的容器;還有 Rancher Labs 基於 K8s 推出的輕量級的 Kubernetes 發行版 K3s,能夠知足在邊緣計算環境中運行在內存和處理能力受限的小型、易於管理的 Kubernetes 集羣日益增加的需求。

歡迎點擊「連接」瞭解京東雲更多精彩內容


結束語

面向將來,京東雲的總體目標仍是但願在雲原生領域有更多投入。李道兵表示,具體來講,在 Service Mesh 方面達到更好的透視遙感能力,若是是較大調用量的分析須要很好地分析服務之間的關係以及出現瓶頸和延遲的緣由,甚至在開發者不須要增長代碼的狀況下就能夠享受這些功能。

在 Serverless 層面,須要進一步優化 FaaS 的冷啓動能力,大幅縮短啓動時間至毫秒級別,並儘量下降延遲,由於如今須要過的層和轉換的協議還比較多,這部分消耗的時間須要儘可能減小,並增長更多語言支持,將界面簡化到接近當年 Google App Engine 的樣子。

相關文章
相關標籤/搜索