在Kubernetes上執行區塊鏈服務(BaaS)
本文是在2018年11月15日由Linux基金會CNCF主辦的KubeCon & CloudNativeCon China 2018大會的“Running Blockchain as a Service (BaaS) on Kubernetes”演講內容基礎上整理而成,從技術上介紹了阿里雲如何將基於區塊鏈Hyperledger Fabric的BaaS和容器叢集技術Kubernetes進行結合的設計理念和實踐經驗分享。
大家好!我是來自於阿里雲區塊鏈團隊的餘珊,今天給大家分享的是《在Kubernetes上執行區塊鏈服務(BaaS)》這個主題。
以上是今天分享的內容大綱,其中重點在第三部分,我們將對BaaS結合Kubernetes的一些典型問題進行深入探討。
首先我們分享一下在我們眼中的區塊鏈和BaaS的定義是什麼。
從狹義上來說,區塊鏈是一種分散式共享賬本技術,基於智慧合約,在各參與方之間達成對交易的共識,並實現賬本交易歷史的不可篡改。這個定義是大家所熟知的,並且是從技術和功能上進行的概括。
而從廣義上來說,我們認為,區塊鏈也是一種在機構、個人、機器之間,構建分散式信任網路、連線可信資料、實現價值流動的新的架構和協作模式。這也是跳出技術和功能維度,從更高維度去進行的理解和總結。
對於另一個概念"BaaS",即"Blockchain as a Service", 我們認為,是雲平臺之上的區塊鏈平臺服務,提供了區塊鏈系統的部署、運維、治理能力,以及提供了區塊鏈應用執行和管理的能力。
區塊鏈從其型別上可分為私有鏈、公有鏈、聯盟鏈三種類型,而從系統拓撲上我們可以將其對應為下述三種模式。對於傳統的中心化系統或私有鏈來說,它基本屬於一種星型中心化系統。對於公有鏈來說,是一種將所有參與企業和個人都對等連線在一起的完全去中心化系統。而對於聯盟鏈來說,是一種帶分層結構的多中心化系統。而阿里雲今天主要關注的是面向企業場景的聯盟鏈技術型別。
下面我們來探討一下為什麼將區塊鏈與容器技術以及Kubernetes進行結合。
首先,我們來分析一下區塊鏈的特點。我們將其分為區塊鏈系統和區塊鏈業務應用兩類。
-
區塊鏈系統是以資料為核心、高度分散式、Full-Mesh網路拓撲、Long-Running、複雜系統型別。
- 資料為核心:其中最重要的是賬本上的資料。
- 高度分散式:因為區塊鏈節點可能部署於不同機房、不同region、不同國家等等。
- Full-Mesh: 區塊鏈節點之間要依賴全連通的網路以實現共識、賬本同步等過程。
- Long-Running:區塊鏈服務和節點是長時間執行,而不是像Web應用或批處理任務那樣短生命週期的。
- 複雜系統型別:區塊鏈系統不是一兩個模組構成的簡單應用,而是往往一整天解決方案或系統的形式。
- 區塊鏈業務應用:沒有統一的標準,可能包含各種應用型別,包括無狀態應用、有狀態應用、Web應用、資料型應用等等型別。
接下來,我們分析一下區塊鏈結合容器技術會帶來哪些優勢:
- 容器技術為區塊鏈系統和業務應用提供了標準化的軟體打包、分發的能力。
- 容器技術實現了區塊鏈執行環境的一致性,以及與底層基礎架構的解耦,使得區塊鏈系統和業務應用可以很方便地移植和執行在各種平臺之上。
進一步的,我們發現,區塊鏈使用Kubernetes叢集技術可獲得以下幾方面的優勢:
- Kubernetes提供了靈活的區塊鏈所需要的底層資源的排程能力,如計算、儲存、網路等。
- Kubernetes強大的運維管理能力,使得我們的區塊鏈服務的產品上線速度以及運維的效率大大提升。
- Kubernetes支援各種應用型別以及微服務架構,因此對於上面區塊鏈系統和區塊鏈業務應用各自的需求都能很好地滿足。
- 使用Kubernetes,可以更好地跟雲平臺進行整合,因為今天在業界它已經成為了各大雲廠商雲原生應用的標準底座了。
- Kubernetes還提供了豐富的安全和隔離功能,這對我們區塊鏈的安全防護體系是很大的增強。
- 另外,圍繞Kubernetes有著非常活躍的社群和豐富的技術和業務生態,因此為結合區塊鏈的研發提供了強大的技術支援和資源。
這裡解答圖中的一個疑問,微服務架構是否適合區塊鏈,這要結合上面的區塊鏈特點分析來看待:
- 對區塊鏈系統來說,內部元件之間是強耦合、強依賴的關係,比較難解耦,內部各元件本身不是通用化的服務定位,也不是REST化服務介面,更多是例如gRPC呼叫,因此不是太適合微服務架構。
- 但是對區塊鏈業務應用來說,則很適合考慮與微服務架構進行結合。
上面這幅圖展示了阿里雲區塊鏈產品形態的演進歷史,同時也可以看出我們在區塊鏈結合容器以及Kubernetes方面所在的工作。
在2017年10月,我們開始提供基於容器服務的區塊鏈解決方案,支援Hyperledger Fabric,為企業提供一鍵式的區塊鏈自動部署能力,當時是基於Docker Swarm叢集技術。緊接著在2017年12月,我們推出了支援Kubernetes的容器服務區塊鏈解決方案,並且在業界也是較早開始使用Helm Chart部署區塊鏈的。在今年7月底,我們正式推出了阿里雲區塊鏈服務BaaS,支援Hyperledger Fabric,同樣也是基於Kubernetes。而在今年9月杭州雲棲大會上,阿里雲BaaS也正式支援了螞蟻區塊鏈,在這背後螞蟻區塊鏈也通過適配改造工作實現了在Kubernetes上的部署執行。
這一頁展示的是阿里雲BaaS的產品架構大圖。其中最核心的是BaaS,目前已經支援Hyperledger Fabric和螞蟻區塊鏈。它們的執行例項底座都是基於阿里雲容器服務Kubernetes叢集。今天的演講內容主要是圍繞Hyperledger Fabric跟Kubernetes結合這方面展開討論的。
上面這一頁展示了阿里雲容器服務Kubernetes版的產品架構圖。
這裡我們展示了一套跨region的Hyperledger Fabric聯盟鏈的部署架構圖。在聯盟管理方的Kubernetes叢集上部署了Orderer organization和Peer Organization, 而在其他業務參與方所在region的Kubernetes上部署了各自的Peer Organization. 這裡的CA、Peer、Orderer、Kafka、ZooKeeper的每個例項都是用了Kubernetes的Service和Deployment型別物件來定義。
此外區塊鏈的業務應用可以部署在Kubernetes上或者其他環境上,通過SLB對映到叢集worker節點的NodePort上,來訪問區塊鏈的各個service。
接下來我們進入重點的第三部分,對於實現BaaS執行在Kubernetes的過程,我們曾經遇到的一些有代表性的問題,以及我們的解決思路和實踐經驗。
首先是關於區塊鏈BaaS的打包、釋出、服務編排等方面的問題。
對於以Hyperledger Fabric為代表的區塊鏈系統來說,這方面面臨的主要問題是:區塊鏈系統本身較為複雜,在一套典型部署裡可能涉及到三十多個容器、近二十個服務、十來個容器映象;而且這些服務相互之間有較強的依賴。
對於這個問題,我們的解決思路是:
- 在打包部署方面,從一開始我們便選用了容器映象以及Kuberentes的Helm Chart作為標準的格式和工具。這裡尤其提一下,為了保證聯盟鏈各組織建立的獨立性和靈活性,我們採用的是一類組織(例如Orderer Org或Peer Org)使用一套chart的方式。
- 在儲存庫管理方面,目前使用的是阿里雲OSS作為Chart Repo(當然可以使用功能更豐富的如ChartMuseum等工具),使用阿里雲容器映象服務作為映象倉庫。這裡我們還採用了region化的映象倉庫配置,加快大體積映象的下載速度,同時採用imagePullSecret保護映象的安全。
- 在配置方式方面,我們採用了Kubernetes的ConfigMap和Secrets來儲存主要的配置和安全資訊,以及使用Chart Values來讓管控可以根據客戶的輸入去定製BaaS聯盟鏈例項。
- 在服務編排方面,為了滿足服務的依賴性需求,我們結合了Chart Template,Chart的Hook(鉤子)機制,以及Kubernetes的Init Container加上Shell指令碼方式,實現各種服務尤其在啟動過程中的依賴和順序保證。
對於企業來說,業務系統的高可用性是非常重要的,尤其是對生產環境的系統執行和應用訪問。這裡我們分享一下在BaaS的每一個層面上的高可用設計思路,以及Kubernetes在其中起到怎樣的幫助。
首先在雲基礎架構和雲資源服務層,我們通過雲資料中心的多可用區、所依賴的雲服務本身的高可用性和高可靠性來提供保障。
在BaaS管控層,通過管控元件的多例項化部署避免單點故障。
在容器服務的Kubernetes叢集,採用3個master節點和多個worker節點的方式提供應用底座的高可用。
在Hyperledger Fabric這一層,它的Orderer、Peer、Kafka、ZooKeeper、CA等型別節點均有叢集或高可用互備的設計,比如任一節點掛掉的話,其他節點依然能正常提供服務。但這裡有一個關鍵的點,就是在Kubernetes叢集上部署的時候,為了避免這些本應高可用互備的Fabric節點的pod被排程到同一個worker node上,我們採用了Kubernetes Pod Anti-Affinity的功能區將高可用叢集的pod排程到不同的worker上,這樣保證了真正高可用的部署,提高了對故障的容忍度。
在區塊鏈業務應用層,則需要各個企業客戶對應用進行周全的高可用設計和實現。在執行時,應用訪問Fabric各個服務的這一環節,我們BaaS內建了雲平臺的SLB負載均衡能力(包含對服務埠的健康檢查),以及Fabric的Service Discovery,來保證即使後端部分節點或服務不可用時,應用的呼叫鏈路都會被排程到可用的節點或服務上。
下面我們談談BaaS資料持久化儲存的問題。雖然上面已經介紹了BaaS的高可用性設計,但我們仍需考慮如何將鏈上賬本資料、區塊鏈關鍵配置等重要內容持久化儲存到可靠的外部儲存而不是容器內部,這樣便可以在伺服器節點全部發生故障,或者系統重啟、備份恢復等場合依然可以實現對系統和資料的恢復。
首先,作為背景,我們分析瞭如果使用本地盤方式可能存在的問題:
- Kubernetes本身對pod的排程預設並沒有限定worker節點,因此如果使用本地盤,就會因為在重啟或恢復過程中排程導致的pod漂移而無法讀取原來worker節點上的本地盤。
- 對於第一個問題,Kubernetes提供了NodeSelector的機制可以讓pod可以繫結worker節點進行部署,不會排程到其他worker節點上,這樣就可以保證能始終訪問到一個本地盤。但這又帶來另一個問題,即在容災的場景,如果這個節點包括其本地盤受到損壞無法恢復時,會導致整個pod也無法恢復。
因此,我們在設計BaaS中的選擇是阿里雲的NAS檔案系統儲存、以及阿里雲的雲盤。在資料可靠性方面,NAS和雲盤可以分別提供99.999999999%和99.9999999%的資料可靠性。此外,我們都選用了SSD型別以保證I/O效能。
在Kubernetes部署的時候,Fabric的節點通過Persistent Volume和Persistent Volume Claim掛載上相應的儲存,並且這些儲存是為每一個Fabric的業務organization獨立分配的,保證了業務資料的隔離性。
在和參加KubeCon大會的一些區塊鏈使用者交流的時候,有朋友提到隨著賬本資料的持續增長,可以怎樣解決儲存問題。在我們的實踐中,我們發現阿里雲的NAS有一些很適合區塊鏈賬本儲存的一些特點:
- 首先,阿里雲NAS可提供儲存容量動態無縫擴容,在這過程中Fabric節點或區塊鏈業務應用均無需重啟或停機,對儲存擴容過程完全無感知。
- 其次,有使用者擔心隨著儲存資料量的增大,儲存的效能是否會明顯下降。恰恰相反的是,在阿里雲NAS隨著所使用的資料量變得越大,NAS所提供的吞吐效能會變得更高,這樣可以打消企業使用者在長期生產執行方面的顧慮。
在上圖的右邊是Fabric不同型別的區塊鏈節點使用不同型別儲存的一個示意圖。
接下來我們探討一下在設計搭建BaaS聯盟鏈跨企業的網路方面遇到的挑戰。
對於大多數區塊鏈技術而言,包括Hyerpedger Fabric, 在網路上要求區塊鏈節點之間形成Full Mesh全連通網路,以實現節點間的賬本資料同步、區塊廣播、節點發現、交易背書等過程,同時企業也要求保障跨企業鏈路的安全性。對於這些需求,我們梳理了業界目前常見的幾類解決方案如下,並進一步分析它們存在的一些不足之處。
方案一是採用單一VPC的聯盟鏈網路方案,在這種模式下,聯盟鏈的所有區塊鏈節點均被部署到一套Kubernetes叢集網路或VPC內。這種方案實質上是一種私有鏈的模式,失去了聯盟鏈的各方自治的價值。
方案二是基於公網的聯盟鏈網路方案,區塊鏈節點分散式部署在不同區域,通過公網IP對外提供服務以及實現互相通訊。這種方案可以較靈活、較低成本低滿足大多數基本需求,但對於高階需求如企業級安全網路則不能很好地滿足。
方案三是基於專線互聯的聯盟鏈網路方案,它採用運營商專線方式將不同網路或資料中心進行兩兩互聯,在業界一些企業中得到了採用。但這裡面主要存在兩方面的問題,首先是如果聯盟鏈參與企業採用了不同電信運營商的專線方案的話,專案實施的複雜性和成本都會很高;其次,如果幾家企業已經建好了這樣一個聯盟網路,對於新來的參與企業,它的接入複雜度和成本也是一個不小的問題。
針對上述各種問題,我們在阿里雲BaaS基礎之上,結合了CEN雲企業網,提供了一種安全的聯盟鏈網路方案,主要面向高階需求的企業使用者。
方案的核心,是採用CEN雲企業網打通不同企業的VPC網路,就像一張跨企業的環網,這樣不同企業不同的VPC內的網路就可以在CEN內實現全連通。
在實現網路連通之後,因為阿里雲BaaS聯盟鏈中的Peer,Orderer,CA等服務是通過域名來訪問的,目的是提升應用訪問的靈活性,而在CEN的這套方案中,我們可以結合雲解析PrivateZone,來實現企業環網內各企業VPC之間的統一域名解析。而且上述的網路連通性和域名解析僅限於聯盟內部,不會暴露到外網。
除了在公共雲環境之外,對於那些將區塊鏈節點部署於本地IDC的企業來說,他們也可以通過VPN或者專線方式,接入到雲上已和CEN打通的任一VPC中,便可實現和聯盟任意節點的通訊。
作為一個小提醒,在方案實施環節,需要注意提前規劃好不同VPC內的內網地址分配,避免在環網中發生衝突。
這樣我們便形成了一套真正跨企業、跨賬戶,打通各個VPC的安全聯盟鏈網路方案。
下面我們將探討一個非常有挑戰性的問題。眾所周知,智慧合約是區塊鏈的一個核心。Hyperledger Fabric中的智慧合約即chaincode是運行於容器當中。在上面這幅圖裡我們總結了Hyperledger Fabric的chaincode容器生成過程的示意圖:
- Peer通過Docker Client發起對Docker Daemon的呼叫,以fabric-ccenv為基礎映象創建出一個chaincode構建容器(chaincode builder container)
- Peer將chaincode原始碼傳入chaincode構建容器,在裡面完成智慧合約編譯
- Peer再呼叫Docker Daemon建立以fabric-baseos為基礎映象的chaincode映象,並將在第2步編譯好的chaincode二進位制檔案內建在chaincode映象中。
- 啟動執行chaincode容器。
從上述過程我們分析一下這裡面存在的一些問題:
- 由於該過程是獨立於Kubernetes體系之外執行的,難以對chaincode容器進行生命週期管理。
- 無法基於Kubernetes的namaspace隔離、NetworkPolicy等機制實現對chaincode容器的安全管理。
針對上面分析發現的問題,我們研究了幾種問題解決的思路。
第一種思路,是將chaincode容器納入到Kubernete的體系(如pod)進行管理。
這在我們的角度看來,其實是最理想的方案。因為它不僅可以實現chaincode容器全生命週期與Fabric其他型別節點一致的管理方式,並且可以結合Kubernetes的NetowrkPolicy控制chaincode容器的網路訪問策略。
其實此前Hyperledger Fabric社群已經建立了一個相關的需求即JIRA(FAB-7406),但目前仍未實現。
假設未來在此功能實現之後,我們進一步展望一下,還可以將智慧合約的容器排程運行於Serverless Kubernetes之上,提供kernal級別的隔離,保證應用容器之間的安全隔離。
第二種思路,如社群和網上的一些觀點所提到的,將chaincode容器放入Docker-in-Docker(DIND)環境執行。
這個思路背後的出發點,主要是為了降低對宿主機Docker Daemon的依賴以及動態生成chaincode映象和容器的不可管理性。
對於這個思路,我們也基於Hyperledger Fabric和Kubernetes進行了試驗,在右邊的這部分Kubernetes部署模板yaml程式碼裡,綠色框的部分是用於配置DIND的容器作為peer pod的一個sidecar,同時將DIND容器內的Docker Daemon通過本地埠2375以環境變數的形式配置到peer的引數中,使得peer可以將chaincode建立相關請求傳送到DIND內。
通過對結果的觀察和分析,我們發現了以下這幾點。
DIND的思路有如下一些優點:
- 無需依賴宿主節點的/var/run/docker.sock。
- 無需專門清理每個Kubernetes worker節點的chaincode映象。
但DIND有著一些更為明顯的不足:
- 每次建立部署或恢復peer節點會變得很慢,因為DIND內需要去拉取fabric-ccenv映象,其大小約1.4GB;而如果用傳統部署方式的話,只需在worker節點拉取一次映象即可。
- Chaincode的例項化(instantiate)過程稍微變慢,推測這和DIND容器本身執行所需的開銷有一定關係。
- 當peer節點或者整個組織(organization)刪掉重建之後(複用原有的資料目錄),啟動速度比起傳統方式會慢很多,這背後的原因和第1點相同。
- 在業界實踐中,DIND方法主要用於CI/CD的場景,但對於生產環境使用的話,則在穩定性等方面仍有較多的挑戰。
- DIND的思路仍然不能解決chaincode容器的安全訪問控制和隔離的問題。
第三種思路,是我們目前在BaaS中採用的方法,即綜合各種配置的手段先解決最主要的問題。這包括以下幾個方面的工作:
- 首先,通過Fabric peer的合理配置(如圖中右上角的示例配置)保證chaincode和peer的通訊。
- 其次,使用docker rm和docker rmi命令清理chaincode容器和映象(它們均包含“dev-”字首)。這裡面有不同的可選位置。
2.1 適合事後清理的可選位置是採用DaemonSet結合lifecycle.preStop.exec.command的位置來執行這些清理命令。
2.2 適合事前清理的可選位置是在initContainer中執行上述清理命令。
- 採用iptables規則,對chaincode容器進行網路隔離。主要是通過在Helm Chart安裝階段配置Kubernetes worker節點的iptables規則,實現限制chaincode容器對Kubernetes網路和對外部網路的訪問(同時也可以限制進入chaincode容器的網路訪問)。
通過上述一系列手段,我們得到了對chaincode容器實現生命週期管理、安全隔離和網路訪問限制的一個實用的方案。未來我們也會繼續朝著思路一這種最理想方式進行更多的探索。
今天阿里巴巴集團的區塊鏈已經在多個行業、多種場景實現了結合以及業務落地,包含了如商品溯源、數字內容版權、供應鏈金融、資料資產共享、公益慈善、醫療處方等等。我們的客戶在生產環境已經達到了百萬級的交易規模以及百GB的賬本資料,這也為我們提供了很豐富的區塊鏈應用實踐經驗。
基於這些實踐,我們想跟大家分享的是,其實區塊鏈應用設計開發並不複雜,這一頁總結了構建於Kubernete之上的區塊鏈系統和應用的基本模式。可以看到,Kubernetes幫我們解決了底層基礎架構和資源的複雜性,提供了應用的標準底座;而區塊鏈服務BaaS則幫我們解決了區塊鏈系統配置部署和運維的複雜性,提供了統一的介面,那麼對企業來說,便可以聚焦在業務流程和業務邏輯的實現,及業務應用的開發上,以及與業務資料的互動和管理上來,實現核心價值的最大化。
下面,我們將進行阿里雲BaaS Hyperledger Fabric的一個demo,主要展示一下幾方面的過程:
- 首先,快速建立跨企業(跨賬號)、跨region的聯盟鏈。
- 接著,動態新增新組織、新通道,完成企業間協同,包括邀請企業,以及企業各自的審批流程。
- 在一些關鍵操作點上,BaaS內建了風控保障,強制邀請簡訊驗證才允許完成操作,這看似麻煩的環節實際上是企業對生產安全保障以及審計都非常看重和需要的。
- 最後,我們在BaaS上部署了經典的Marbles虛擬數字資產交易的應用,包含chaincode的部署和client SDK應用的部署。
最後,歡迎有興趣的朋友進一步瞭解和使用阿里雲的區塊鏈服務BaaS,通過掃描圖中的兩個二維碼可快速訪問相關產品主頁,申請開通免費公測試用,以及訪問產品文件獲得更多使用和開發指南。
以上就是我今天跟大家分享的全部內容,謝謝大家!
原文連結
本文為雲棲社群原創內容,未經允許不得轉載。