Heroku 的“得”与“失”
作者 | 孫健波(天元)? 阿里巴巴技術專家
2011 年,Heroku 的聯合創始人 ?Adam Wiggins 根據針對上百萬應用托管和運維的經驗,發布了著名的 “十二要素應用宣言(The Twelve-Factor App)”。不知那時候他們有沒有想到,這份宣言會在今后數年時間里,成為 SaaS 應用開發的啟蒙書。同時也奠定了 Heroku 在 PaaS 領域的地位,成為了云上應用開發規范化的基石。
Heroku 無疑是一家偉大的公司,它關注應用與開發者,“以應用為中心”的理念讓我們至今受益。然而在過去這一兩年里,我們看到許多 Heroku 的用戶開始尋找別的選擇。這不禁讓我們好奇,站在“云原生”如火如荼的今天回望過去,Heroku 的“得”與“失”究竟在哪里?
“以應用為中心”的先進理念
Heroku 創辦于 2007 年,是最早成熟的 PaaS 產品之一。Heroku 也是最早喊出“以應用為中心”,大規模幫助應用上云的產品。正是圍繞“以應用為中心”這樣先進的理念,使得 Heroku 從一開始便擁有了至今看來都非常誘人的功能:
-
用戶可以直接從開發語言出發,選擇對應的技術棧,通過 heroku create 這樣簡單的命令,將應用托管到云上。主流的開發語言,均能在 Heroku 中找到對應的選擇。從代碼的變動自動觸發軟件的部署交付,清晰的工作流、多樣的發布策略,直到后來的很多年都是 DevOps 們夢寐以求的功能;
-
**用戶無需關心應用背后的基礎設施是什么,Heroku 負責維護背后的一切。**這句看似簡單的話背后隱藏了巨大的復雜性,試想下某個軟件或系統爆出安全漏洞后給你帶來的窘境,又或者你想使用一個數據庫服務時卻不得不維護一個數據庫實例。而在 Heroku, 這一切麻煩你都無需關心;
-
**高可用與彈性作為附加能力。**Heroku ?平臺托管的服務具備高可用等附加能力,更讓人驚喜的是,滿足 12-factor 的應用還天然具備了擴縮容的能力,可以很輕松的抗住突發流量,這在當時無異于黑科技般的存在。
**正是這樣強大的能力,使得 Heroku 成為了 PaaS 領域事實上的標準,**無論是后續的 Cloud Foundry 還是 OpenShift,似乎都沒有對 Heroku 有實質性的超越。
Heroku 不再物超所值
眾所周知,相對于只是提供純粹計算能力的 IaaS 而言,以服務能力著稱、提供眾多開箱即用附加功能的 PaaS,價格上素來都是普遍偏貴的。畢竟 PaaS 可以使你專注于業務本身,貴一點自然也無可厚非。更何況 PaaS 通常根據開通附加能力的數量收費,剛開始甚至更便宜,Heroku 亦是如此。
一開始,用戶可能感覺只是比自己在 IaaS 上搭建服務貴一點點。當你發現應用可以便捷綁定 Heroku 提供的高可用 PostgresSQL 數據庫時,甚至會覺得它貴的物超所值。不過,隨著業務邏輯逐漸復雜、部署規模越來越大,需求自然而然就變了。比如為了讓用戶的數據更安全,你可能需要一個只能私有網絡訪問的 PostgresSQL 實例,而 Heroku 默認不具備這樣的功能,你必須要配置一個 VPC 才能做到,你自然要為這個 VPC 額外付費。這類需求逐漸覆蓋了你每一個實例,增加的費用直接變成了增長的單價,成本快速上升。與此同時,IaaS 廠商的能力也正在爆炸式的增長。今天,幾乎所有的云服務商都開始提供數據庫服務,并且這些數據庫實例的 VPC 通常是免費的。
另一方面,**Heroku 從 13 年前誕生至今,一直是閉源的商業平臺,關于 Heroku 的一切你都只能在其本身的平臺上玩。**這無疑給新人學習、上手造成了很高的門檻,甚至許多人因此不愿意體驗該產品。這也導致周邊生態的配套工具相當匱乏,只要官方不提供的能力,用戶就得自己開發。然而無論是招聘 Heroku 熟練工,還是從零開始培養,這無疑都帶來了不小的人力成本。
反觀如今的云原生社區,任何人都可以通過幾條簡單的命令在自己的開發環境中運行 Kubernetes,開發者可以很輕易的體驗和學習,積累經驗。基礎設施主動對接 Kubernetes 生態。周邊的各類工具也在不斷的繁榮演進。
黑盒化的運行時體驗
提到 Heroku,另一個代表性的技術無疑就是 Buildpack。在 Docker 鏡像機制出現之前,使用 Buildpack 管理用戶應用的運行時構建,使得 PaaS 的運行時最終與語言無關,這無疑是非常聰明的做法。然而十多年過去,Buildpack 的模式早已暴露出許多問題。
-
一方面是官方支持的 Buildpack 數量少,限制多,比如運行系統僅支持 Linux 的 Ubuntu 發行版;某些 Ubuntu 安裝包在 Buildpack 中沒有安裝你便無法使用;相對小眾的開發語言(如 Elixir)均不支持;又或者是你的應用包含多種語言,使用起來就變得復雜;
-
另一方面,你也許能自定義或者找到第三方的 Buildpack 滿足需求,但是沒有人來保證它的穩定。一旦出了問題,你很難在本地運行 Buildpack 排查問題,而 Heroku 平臺的錯誤信息透出方式并不直接,日志排查更是不便。
2017 年 9 月份,Heroku 最終還是支持了基于 Docker 鏡像的運行時部署,然而至今為止依舊有不少限制,其中最大的限制是存儲,只能使用 Heroku 的臨時存儲,這幾乎就決定了你不可能自己編寫像 etcd、TiDB 這類復雜的有狀態應用。
一切的本質,都在于 Heroku 給用戶提供的體驗是黑盒化的,為用戶屏蔽基礎設施的同時,也使得用戶失去了改造的自由。這也是為什么即便像 Cloudfoundry 這樣理念極其類似的 PaaS 平臺,即便是開源的,依舊存在同樣的弊病。
**事實上用戶喜歡的是“白盒”,他們希望能夠自定義基礎設施,可以平行的替換或改造平臺的已有功能,而非只能局限在平臺提供的能力之上構建。**就像我們買了一輛車,在雨雪的極端天氣下,我們希望可以換雪地胎,而不是只能加裝防滑鏈。
Kubernetes 的出現
而 Kubernetes 正是這樣一個白盒化體驗,它從未嘗試去屏蔽基礎設施,而是作為一個標準化接入層,把基礎設施層的能力通過聲明式 API 暴露出來,將選擇權留給了用戶。正是在這樣一個開放世界里,復雜有狀態應用的管理也終于得以在云上落地了。另一方面, Kubernetes 并不是 PaaS。相比于 Heroku 官方提供了將近兩百個 add-ons(插件)) 用于增強包括數據庫、監控、日志、緩存、搜索、分析、權限等能力,而 Kubernetes 則強調強可擴展能力,希望用戶自己可以通過編寫 CRD Operator 新增任意能力。
那么,這兩種做法的區別是什么呢?
封閉、限制 vs 開放、自由
眾所周知,Heroku 一直是一個“主觀”的 PaaS 平臺,12-factor 代表了應用必須云原生化的強硬觀點,這一點毋庸置疑是正確的,而且非常了不起。但如果觀念不能與時俱進,那么“主觀”就會變得危險。就比如容器和虛擬機都已經相當普及的今天,Heroku 依舊堅持應用只能運行在 Heroku Dynos 上面。雖然這種統一很大程度上為管理提供了便利,但是這也使得用戶丟掉了很多靈活性,更重要的是,運行時的巨大差異,開始讓很多用戶覺得自己與更廣泛的社區“格格不入”。
不過,Heroku 有屬于自己的封閉生態,除了上文提到官方維護的 Add-ons 以外,還有方便用戶一鍵部署到 Heroku 平臺的 4700 多個 Buttons 應用 ?和 用于自定義運行時和構建流程的 6300 多個 Buildpacks,這兩大功能都允許用戶自定義并可以申請注冊到官方的應用市場中,數量著實驚人。這樣繁榮的社區怎會被人詬病?出于好奇,筆者整體分析了一下這些項目。
下面兩張圖分別是 Heroku Buildpack 和 Buttons 的項目統計:
我們可以看到,Buildpack 只能在 Heroku 平臺使用,所以 star 數量代表了大家對項目的關心,而下載量則代表了用戶的使用頻度。圖中,6000 多個 Buildpack 的 star 數和下載安裝量均在 50 以內,而超過 500 個 star 和 500 次下載部署的項目均只有 30 個左右。再來看 Buttons 中的項目,由于這些項目本身還可以部署到 Heroku 以外的其他平臺,所以就只看在 Heroku 的部署下載量反映大家的使用頻度,而圖中超過 500 次部署的 Buttons 項目只有 6 個。原來這一切竟只是表面繁榮。
面對這樣一個統計數據,我們很難說 Heroku 的封閉生態是成功的。
Buildpack 本質上是對進程的構建和打包,同樣的工作業界幾乎都已經統一通過 Dockerfile 構建鏡像解決。與 Buildpack 只能在 Heroku 平臺上使用的封閉生態不同,Docker 鏡像以及 OCI 容器和鏡像規范的出現,大大推動了基于容器鏡像的應用打包方式走向了全面繁榮。而用于存儲鏡像的 Docker Registry 也是人人都可以搭建的鏡像倉庫。從數字上看,僅官方鏡像倉庫上的鏡像數量就超過了 300 萬,更有數千鏡像下載量超過了 100 萬,這才是成功生態應該有的力量。
而在 Kubernetes 生態中幫助應用打包并可以一鍵部署 CRD Operator 的 Helm Chats 也與 Heroku 的 Buttons 類似。同樣, Helm Charts 的托管平臺是可以自由搭建的,而 Chart 本身則在任何一個開源或者商業版本的 Kubernetes 上均能運行。雖然沒有明確的統計數據,但是像 Helm Hub、Kubeapps Hub、CloudNative App Hub 等 Charts 托管網站里的內容看起來也已經取得了不小的成功。
Heroku 們的未來?
從上述觀察來看,Heroku 過去最重要的教訓,在于不夠開放而錯失了原本屬于自己的云原生應用生態。而在 Kubernetes 項目成為基礎設施主流之后,Heroku 以及它的開源繼任者 Cloud Foundry 還是很難走出“被故意忽視”的困境。這個困境的關鍵并不在于它們是不是基于 K8s 構建的,而是它們能不能帶來像 K8s 一樣的開放與自由。
可是,另一方面,Kubernetes 本身從始至終都不是一個面向最終用戶的體驗,也不是最終用戶想要的東西。Kubernetes 自身“白盒化”的體驗正在為越來越多的業務研發和運維帶來“太復雜”的困擾。而這個社區里大量的 CRD Operator 則像一個個煙囪,彼此孤立,不能聯動,而且有大量的冗余(比如:Kubernetes 中永無止盡的 Ingress 實現 )。這一切都說明,純粹使用 Kubernetes 并非托管云原生應用的“標準答案”。而那些試圖“給 K8s 寫個界面”的 PaaS 構建者們,似乎又陷入了 Heroku 的困境。這種變化,也讓 PaaS 與 Kubernetes 之間的關系越來越復雜和不清晰。
從 Kubernetes 到“以應用為中心”的美好未來之間,全世界的 PaaS 工程師其實都在期待一項全新的技術能夠彌補這之間的鴻溝。阿里云原生應用平臺團隊的做法是,通過為應用“建模”的方式來解決這個問題,這也正是 Open Application Model (OAM)?開源項目得以創建的重要目的。
最后
OAM(Open Application Model)開放應用模型是阿里聯合微軟針對云原生應用的模型,第一次對“以應用為中心”的基礎設施和構建規范進行了完整的闡述。應用管理者只要遵守這個規范,就可以編寫出一個自包含、自描述的“應用定義文件”。
OAM 相關內容在 github 上完全開源,同時我們也為 Go 生態編寫了 oam-go-sdk 方便快速實現 OAM。
目前,阿里巴巴團隊正在上游貢獻和維護這套技術,如果大家有什么問題或者反饋,也非常歡迎與我們在上游或者釘釘聯系。
參與方式:
- 釘釘掃碼進入 OAM 項目中文討論群
(釘釘掃碼加入交流群)
- 通過 Gitter 直接參與討論
- OAM 開源實現地址
- 點擊 star 一下
“阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的技術圈。”
總結
以上是生活随笔為你收集整理的Heroku 的“得”与“失”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Serverless 解惑——函数计算如
- 下一篇: 开发函数计算的正确姿势——使用 brot