- 金融級IT架構(gòu)與運維:云原生、分布式與安全
- 魏新宇等
- 14041字
- 2022-01-14 14:22:57
2.1 容器云構(gòu)建金融業(yè)敏態(tài)業(yè)務(wù)的考量
近兩年,很多金融企業(yè)已經(jīng)開始部署或計劃部署容器云。我們先分析一下容器云如何幫助金融客戶構(gòu)建敏態(tài)IT以及適合容器云的應(yīng)用是什么。
2.1.1 國內(nèi)企業(yè)敏態(tài)IT建設(shè)趨勢分析
我們知道,在敏態(tài)IT建設(shè)過程中,DevOps的建設(shè)是其中最重要的一個環(huán)節(jié)。筆者這里通過對云計算開源產(chǎn)業(yè)聯(lián)盟發(fā)布的《中國DevOps現(xiàn)狀調(diào)查報告》[1]進(jìn)行解讀,分析國內(nèi)企業(yè)敏態(tài)IT建設(shè)趨勢。
閱讀報告,可以得出如下21條結(jié)論。
1)國內(nèi)企業(yè)普遍接受了DevOps的觀念,并已經(jīng)開始實踐敏捷開發(fā)。
2)敏捷管理實踐排名采用度依次為:發(fā)布計劃、看板、每日站會、Spring迭代。Sprint迭代是DevOps的基礎(chǔ)。舉例來說,紅帽O(jiān)penShift采用Sprint迭代模式開發(fā),而Ansible采用看板模式開發(fā)。
3)最受歡迎的四個工程實踐:持續(xù)集成、自動構(gòu)建、單元測試、持續(xù)部署。
4)項目管理使用最多的工具是JIRA。
5)多數(shù)企業(yè)將代碼、配置管理、自動化腳本被納入版本控制系統(tǒng)。
6)代碼主干集成比例提升。
7)自動化測試比例大幅提升,但模糊測試、混沌測試、全鏈路測試仍需要提升。
8)測試左移比例提升,但仍不高。
9)大多數(shù)客戶在使用虛擬機和容器。
10)告警平臺的智能化與自動化決策有待提升。
11)運維全生命周期數(shù)據(jù)智能化分析有待提升。
12)變更管理可視化能力有待提升。
13)智能化配置管理和關(guān)聯(lián)分析能力弱。
14)全鏈路容量管理能力有待提升。
15)自動化和智能化高可用管理能力有待提升。
16)企業(yè)應(yīng)用RTO有待提升。
17)Spring Boot和Spring Cloud被大量使用。
18)兩成企業(yè)微服務(wù)拆分簡單粗暴。
19)半數(shù)以上企業(yè)嘗試DevSecOps。
20)選擇混合云的企業(yè)比重增加,選擇公有云的企業(yè)比重下降。
21)超過20%的企業(yè)無法判斷DevOps實踐是否成功。
通過以上21條結(jié)論,我們來分析企業(yè)今后在敏態(tài)IT方面的8個建設(shè)重點。
1)混沌工程平臺的建設(shè)會成為繼容器云、DevOps建設(shè)后,企業(yè)IT建設(shè)這兩年的重點。
2)企業(yè)短時間很難實現(xiàn)所有應(yīng)用上容器,虛擬機+容器模式將會長期存在,因此DevOps建設(shè)應(yīng)該考慮虛擬機+容器的混合環(huán)境。
3)智能告警、運維、變更、自動化等平臺建設(shè)是企業(yè)在DevOps建設(shè)后,提升運維能力的重點建設(shè)方向。
4)企業(yè)應(yīng)用RTO有待提升,企業(yè)會重視基于容器云實現(xiàn)業(yè)務(wù)的雙活建設(shè),保證在單數(shù)據(jù)中心出現(xiàn)故障時,服務(wù)不降級。
5)DevSecOps被普遍接受,將容器云的安全工具納入DevSecOps工具成為企業(yè)IT建設(shè)的主要方向。
6)Spring Boot和Spring Cloud仍然受歡迎,因此Istio大規(guī)模商用的基礎(chǔ)目前尚不存在。
7)20%的企業(yè)單體應(yīng)用拆分簡單粗暴,因此使用專業(yè)的方法論(如DDD)拆分單體應(yīng)用,并進(jìn)行微服務(wù)落地是建設(shè)重點。
8)選擇混合云的企業(yè)比重增加,因此基于混合云實現(xiàn)DevOps、多云管理是企業(yè)建設(shè)的重點。
2.1.2 敏態(tài)IT的構(gòu)建路徑
在物理機中部署應(yīng)用,我們需要先安裝操作系統(tǒng)(如Linux),然后安裝應(yīng)用服務(wù)器(如WebLogic、Tomcat),再部署應(yīng)用包(如war包)。在虛擬化環(huán)境中,可以將部署了應(yīng)用服務(wù)器的虛擬機做成模板,如果需要部署新的應(yīng)用服務(wù)器,可先進(jìn)行模板部署,再將應(yīng)用包部署到應(yīng)用服務(wù)器上。
虛擬化環(huán)境下應(yīng)用部署的便捷性有了很大的提升,但在應(yīng)用彈性擴容方面,效果還是不理想。在業(yè)務(wù)突然繁忙的時候,如銀行的紀(jì)念幣銷售、保險公司的開門紅業(yè)務(wù)造成大量的突發(fā)訪問請求,緊急通過模板部署虛擬機、部署并啟動應(yīng)用,顯然耗時太長。但是,如果提前準(zhǔn)備虛擬化環(huán)境,一來增加工作量,浪費資源,二來臨時準(zhǔn)備的虛擬機,也未必能夠承載突增的業(yè)務(wù)訪問請求。所以,構(gòu)建容器云是金融科技敏態(tài)業(yè)務(wù)的基礎(chǔ)。金融科技敏態(tài)IT的構(gòu)建分為5個步驟,如圖2-1所示。

圖2-1 金融科技敏態(tài)IT構(gòu)建路徑
接下來,我們針對圖2-1中的5個步驟進(jìn)行說明。
- 在容器云中,我們可以通過模板直接部署應(yīng)用服務(wù)器的容器化鏡像,同時在部署的時候,也可以借助類似Java Source to Image的開源技術(shù)[2]實現(xiàn)從源碼構(gòu)建應(yīng)用以及應(yīng)用的容器化。而當(dāng)業(yè)務(wù)請求量高時,可以通過容器云的自動橫向擴容來實現(xiàn)應(yīng)用服務(wù)器的橫向擴展。在容器云中,我們可以通過容器鏡像倉庫統(tǒng)一管理容器鏡像,實現(xiàn)容器鏡像的標(biāo)準(zhǔn)化,然后將應(yīng)用的配置放到配置倉庫,這樣相同的容器鏡像,在不同的環(huán)境部署時只需使用不同的配置文件即可,從而大幅提升應(yīng)用部署速度。
- 借助于容器云,我們可以便捷地實現(xiàn)CI/CD工具鏈的落地,提升應(yīng)用的開發(fā)和發(fā)布速度。
- 傳統(tǒng)的應(yīng)用服務(wù)器通常較重,如WebLogic,在向容器云遷移時存在一定的難度,需要將應(yīng)用遷移到輕量級的應(yīng)用服務(wù)器(如Tomcat)或進(jìn)行微服務(wù)拆分。近兩年,隨著Spring Cloud和Service Mesh的發(fā)展,越來越多的新型應(yīng)用在設(shè)計之初就已經(jīng)符合微服務(wù)的設(shè)計原則。
- 云原生計算基金會(Cloud Native Computing Foundation,CNCF)一直主推的云原生,實際上也是以輕量級應(yīng)用開發(fā)框架為核心,以分布式、容器化的開源中間件堆棧為依托,以容器云為承載平臺實現(xiàn)的。
- 加快微服務(wù)的落地,也是很多企業(yè)選擇構(gòu)建容器云的重要目的。
在介紹了金融科技通過容器云構(gòu)建敏態(tài)IT的路徑后,接下來我們介紹適合于容器云承載的應(yīng)用。
2.1.3 容器云承載的應(yīng)用
容器云在發(fā)展之初,主要是承載無狀態(tài)的、輕量級的應(yīng)用。比較常見的企業(yè)級應(yīng)用有運行在Tomcat中的War包,或者以Spring Boot方式打包并運行在OpenJDK中的Fat Jar。可以看到,這類應(yīng)用都是重要性相對較低的Web應(yīng)用。如果容器云平臺只是Web類、網(wǎng)站前端類的應(yīng)用,顯然容器云平臺的重要性也不會太高。在Kubernetes層面,我們可以通過Statefulset支撐有狀態(tài)應(yīng)用,而大量無狀態(tài)應(yīng)用和少量有狀態(tài)應(yīng)用則在容器云運行,如圖2-2所示。

圖2-2 容器云承載應(yīng)用種類
隨著Operator項目的興起并被CNCF采納,有狀態(tài)應(yīng)用集群也可以很方便地在容器云上部署和管理。目前OperatorHub已經(jīng)有超過3000種有狀態(tài)應(yīng)用,并且仍在迅速增長,如etcd、ElasticSearch、TiDB等。
如果我們想讓容器云承載更為復(fù)雜的業(yè)務(wù),那勢必需要借助一些類似中間件的架構(gòu),才能使容器化應(yīng)用體系化。Spring Cloud作為一種微服務(wù)治理框架,本身具備一定中間件功能。例如在OpenShift上基于Spring Cloud開發(fā)一套電商平臺,其UI界面如圖2-3所示。

圖2-3 電商平臺UI界面示意圖
本質(zhì)上講,Spring Cloud不是一個產(chǎn)品化的方案。Spring Cloud包括大量組件,可以根據(jù)客戶的不同需求定制出一個可落地的完整方案,但這個定制過程涉及較多的架構(gòu)相關(guān)的工作,以及業(yè)務(wù)代碼的實現(xiàn)。
由于Spring Cloud主要靠定制計劃開發(fā),因此對應(yīng)用開發(fā)人員或獨立軟件開發(fā)商(Independent Software Vendor,ISV)要求很高,而且一旦某個微服務(wù)模塊的業(yè)務(wù)邏輯發(fā)生變化,都需要重新定制開發(fā)和編譯。此外,這種代碼實現(xiàn)的業(yè)務(wù)邏輯缺乏IT廠商的支持。因此,不少企業(yè)客戶還是希望使用產(chǎn)品化的中間件。
我們?nèi)匀灰陨衔奶岬降碾娚虡I(yè)務(wù)為例,其技術(shù)架構(gòu)如圖2-4所示。
在圖2-4所示的微服務(wù)架構(gòu)中,Pricing Service是定價服務(wù)。我們可以通過代碼的方式實現(xiàn)定價邏輯,但工作量較大,且變更不方便。在Pricing Service中,如果使用JBoss BRMS產(chǎn)品實現(xiàn)定價業(yè)務(wù)規(guī)則,則會靈活得多。因為開發(fā)者可以只關(guān)注業(yè)務(wù)代碼開發(fā),而無須將過多精力放在架構(gòu)開發(fā)上。

圖2-4 電商業(yè)務(wù)技術(shù)架構(gòu)示意圖
近兩年,中間件廠商針對容器云發(fā)布了更為輕量級的容器化中間件,主要也是這個目的。如IBM推出了WAS Liberty,紅帽推出了很多云原生相關(guān)的開源方案,如Quarkus(云原生開發(fā)框架)、Camel-K(云原分布式集成)、Kogito(云原生業(yè)務(wù)流程自動化)、Debezium(云原生的CDC)、AMQ-Streams(容器化Kafka)、JBoss Data Grid(云原生分布式緩存)。具體技術(shù)細(xì)節(jié),可以參考《云原生應(yīng)用構(gòu)建:基于OpenShift》這本書。
Spring Cloud的本質(zhì)和首要目的,是實現(xiàn)微服務(wù)治理。但我們知道Spring Cloud的治理框架是代碼侵入式的,不是針對Kubernetes原生的微服務(wù)治理框架,所以代碼開發(fā)人員需要站在七層協(xié)議的角度,同時關(guān)注微服務(wù)之間的調(diào)度關(guān)系。2017年由谷歌和IBM主導(dǎo),正式開源了Service Mesh架構(gòu):Istio。Istio的目的是將微服務(wù)的治理框架交由底層Istio和Kubernetes來實現(xiàn)。但I(xiàn)stio并不負(fù)責(zé)具體微服務(wù)的業(yè)務(wù)邏輯,比如上文舉的Pricing Service微服務(wù)的例子,其定價規(guī)則可以由代碼實現(xiàn),也可以由容器化中間件實現(xiàn)。
隨著Kubernetes的發(fā)展,現(xiàn)在有一個新的技術(shù)趨勢:在容器云中以Pod的方式運行虛擬機,這樣容器云平臺就能夠提供普通容器無法實現(xiàn)的功能。例如OpenShift上的OpenShift Virtualization技術(shù),對應(yīng)開源社區(qū)的KubeVirt技術(shù)。OpenShift Virtualization能夠承載的應(yīng)用包括WebSphere Application Server、Oracle DB、MSFT SQL Server(non-clustered)、IBM DB2 LUW、MySQL等。相信通過類似的技術(shù),越來越多的應(yīng)用會向容器云遷移。
2.1.4 應(yīng)用上容器云的準(zhǔn)入條件和最佳實踐
整體而言,應(yīng)用上容器云的準(zhǔn)入條件包含如下幾個方面(包含但不限于)。
- 已建立了清晰的可自動化的編譯及構(gòu)建流程:應(yīng)用使用如Maven、Gradle、Make或Shell等工具實現(xiàn)了構(gòu)建編譯步驟的自動化,以便在容器平臺上實現(xiàn)自動化的編譯及構(gòu)建流程。
- 已實現(xiàn)應(yīng)用配置參數(shù)外部化:應(yīng)用已將配置參數(shù)外部化于配置文件或環(huán)境變量中,以便應(yīng)用容器能適配不同的運行環(huán)境。包含特定環(huán)境的配置的容器鏡像不能在整個環(huán)境(Dev、QA、Prod)中升級。為了實現(xiàn)可靠的發(fā)布過程,應(yīng)將在較低環(huán)境中測試過的相同鏡像部署到生產(chǎn)中。將特定環(huán)境的配置保留在容器鏡像之外,例如,使用ConfigMap和Secret存儲應(yīng)用程序配置。
- 已提供合理可靠的健康檢查接口:容器平臺將通過健康檢查接口判斷容器狀態(tài),對應(yīng)用服務(wù)進(jìn)行狀態(tài)保持。
- 已實現(xiàn)狀態(tài)外部化,以及應(yīng)用實例無狀態(tài)化:應(yīng)用狀態(tài)信息存儲于數(shù)據(jù)庫或緩存等外部系統(tǒng),應(yīng)用實例本身實現(xiàn)無狀態(tài)化。
- 不涉及底層的操作系統(tǒng)依賴及復(fù)雜的網(wǎng)絡(luò)通信機制:應(yīng)用以處理業(yè)務(wù)為主,不強依賴于底層操作系統(tǒng)及組播等網(wǎng)絡(luò)通信機制,提高可移植性。
- 部署交付件及運行平臺的大小在2GB以內(nèi):輕量級的應(yīng)用便于在大規(guī)模集群中快速傳輸分發(fā),更符合容器敏捷的理念。
- 啟動時間在5分鐘以內(nèi):過長的啟動時間將不能發(fā)揮容器敏捷的特性。
如果應(yīng)用明顯不符合上述條件,則其暫時不適合運行在容器上。
在應(yīng)用上容器云時,除了需要遵循以上準(zhǔn)入條件,還需要盡量符合以下最佳實踐。
- 在Pod定義中指定資源請求和資源限制。如果請求資源的配置不正確的話,那么應(yīng)用程序可能會耗盡內(nèi)存或?qū)е翪PU資源不足。指定請求的內(nèi)存和CPU資源可以使集群做出適當(dāng)?shù)恼{(diào)度決策,以確保應(yīng)用程序具有足夠的可用資源。
- 使用Pod中斷預(yù)算保護(hù)應(yīng)用程序。在某些情況下,需要將應(yīng)用程序容器從集群節(jié)點中逐出。例如,在管理員可以執(zhí)行節(jié)點維護(hù)之前或在縮減規(guī)模時集群自動縮放器可以從集群中刪除節(jié)點之前,需要驅(qū)逐Pod。為確保驅(qū)逐Pod時應(yīng)用程序仍然可用,你必須定義各自的PodDistruptionBudget對象。PodDisruptionBudget是一個API對象,用于指定保證應(yīng)用可用的最小副本數(shù)或最小百分比。
- 每個容器運行一個進(jìn)程。避免在單個容器中運行多個進(jìn)程。每個容器中運行一個進(jìn)程可以更好地隔離進(jìn)程,避免信號路由出現(xiàn)問題。
- 應(yīng)用程序監(jiān)視和警報。應(yīng)用程序監(jiān)視和警報對保持應(yīng)用程序在生產(chǎn)中良好運行并滿足業(yè)務(wù)目的至關(guān)重要??梢允褂肞rometheus和Grafana等監(jiān)視工具來監(jiān)視你的應(yīng)用程序。
- 配置應(yīng)用程序以將其日志寫入stdout或stderr。容器云將收集這些日志并將其發(fā)送到集中位置(ELK、Splunk)。在分析生產(chǎn)問題時,應(yīng)用程序日志是寶貴的資源?;趹?yīng)用程序日志內(nèi)容的警報有助于確保應(yīng)用程序按預(yù)期運行。
- 考慮實施彈性措施:斷路器、超時、重試、速率限制。彈性措施可以使你的應(yīng)用程序在出現(xiàn)故障時表現(xiàn)更好。它們可保護(hù)你的應(yīng)用程序免于過載(速率限制、斷路器),并在遇到連接問題(超時、重試)時提高性能??紤]利用OpenShift Service Mesh來實現(xiàn)這些措施,需在應(yīng)用程序中更改代碼。
- 使用受信任的基礎(chǔ)鏡像(base image)。盡可能使用容器廠商提供的企業(yè)級容器鏡像。容器廠商提供的鏡像已通過測試、安全加固并有相應(yīng)的技術(shù)支持。如果使用社區(qū)提供的鏡像,請盡量使用你信任的社區(qū)提供的鏡像。不要使用公共注冊表(例如Docker Hub)中有未知來源的鏡像。
- 使用最新版本的基礎(chǔ)鏡像。通常,僅最新版本的容器鏡像包含所有可用的安全修復(fù)程序。設(shè)置CI管道,以便在構(gòu)建應(yīng)用程序鏡像時始終提取最新版本的基礎(chǔ)鏡像,同時在更新的基礎(chǔ)鏡像可用時重建應(yīng)用程序。
- 使用單獨的構(gòu)建鏡像和運行時鏡像。創(chuàng)建具有最小依賴的、單獨的運行時鏡像可減少攻擊面,并產(chǎn)生較小的運行時鏡像。構(gòu)建鏡像包含構(gòu)建依賴關(guān)系,構(gòu)建依賴關(guān)系對于構(gòu)建應(yīng)用程序是必需的,對于運行應(yīng)用程序則不是必需的。
- 盡可能遵守受限制的安全上下文約束(SCC)。修改你的容器鏡像以允許在受限制的SCC下運行。應(yīng)用程序容易受到攻擊,強制使用OpenShift受限制的SCC可提供最高級別的安全性,以防止在應(yīng)用程序被破壞的情況下?lián)p害集群節(jié)點。
- 使用TLS保護(hù)應(yīng)用程序組件之間的通信。應(yīng)用程序組件可能會傳達(dá)應(yīng)受到保護(hù)的敏感數(shù)據(jù)。除非你認(rèn)為基礎(chǔ)OpenShift網(wǎng)絡(luò)是安全的,否則你可能希望利用TLS保護(hù)應(yīng)用程序組件之間的通信??紤]利用OpenShift Service Mesh從應(yīng)用程序中卸載TLS管理。
2.1.5 應(yīng)用容器化遷移步驟
針對已有傳統(tǒng)應(yīng)用系統(tǒng)的改造遷移,通常需要經(jīng)過如圖2-5所示的流程。

圖2-5 應(yīng)用容器化遷移流程圖
從圖2-5中,我們可以看到應(yīng)用容器化遷移大致需要經(jīng)歷6個步驟。
- 應(yīng)用準(zhǔn)入評估:根據(jù)制定的應(yīng)用準(zhǔn)入評估準(zhǔn)則對要遷移的應(yīng)用或系統(tǒng)進(jìn)行評估,如果滿足運行在容器云上的準(zhǔn)入要求,則進(jìn)行應(yīng)用遷移方案的制定。
- 制定應(yīng)用遷移方案:在應(yīng)用遷移方案制定中,需要綜合考慮應(yīng)用或系統(tǒng)的技術(shù)語言、通信協(xié)議、中間件版本、配置傳入方式、日志輸出方式、應(yīng)用灰度發(fā)布等技術(shù)實現(xiàn)細(xì)節(jié),并結(jié)合Kubernetes/OpenShift的特性以及約束制定遷移方案,其間可能需要進(jìn)行必要的技術(shù)驗證。
- 應(yīng)用改造:待應(yīng)用遷移方案確定并得到認(rèn)可之后,可能需要對應(yīng)用進(jìn)行必要的改造,以最佳的形式在Kubernetes/OpenShift上運行,如日志的輸出形式、配置外部化等。
- 應(yīng)用容器化:將應(yīng)用改造或打包為可以容器形式運行的過程。應(yīng)用容器化通常包括基礎(chǔ)鏡像制作、應(yīng)用容器化構(gòu)建、其他技術(shù)組件容器化這三個方面。
- 遷移驗證和正式遷移:在應(yīng)用容器化完成之后,就可以進(jìn)行遷移驗證了。如果過程中出現(xiàn)問題可能需要隨時調(diào)整,最終達(dá)到符合預(yù)期的效果就可以正式遷移了。
可以看到,在這6個步驟中,最關(guān)鍵的是制定應(yīng)用遷移方案和應(yīng)用容器化。應(yīng)用遷移方案沒有一個通用的形式,它會因應(yīng)用系統(tǒng)的不同而差異很大,所以企業(yè)需要根據(jù)應(yīng)用系統(tǒng)的特點制定。后文將著重介紹應(yīng)用容器化的方法。
2.1.6 容器應(yīng)用基礎(chǔ)鏡像的選擇
應(yīng)用容器化的第一步就是選擇基礎(chǔ)鏡像,具體遵循如下選擇標(biāo)準(zhǔn)。
鏡像應(yīng)從官方途徑獲得,避免使用來自社區(qū)構(gòu)建和維護(hù)的鏡像。應(yīng)用鏡像應(yīng)在PaaS平臺中構(gòu)建,所選擇的基礎(chǔ)鏡像應(yīng)來自可信的鏡像源,包括:
- Docker Hub官方鏡像(https://hub.docker.com);
- 紅帽容器鏡像庫registry.access.redhat.com或registry.redhat.io。
在容器云中,我們更推薦使用第二類鏡像。紅帽提供的鏡像經(jīng)過了嚴(yán)格的安全掃描,其鏡像掃描遵循如下規(guī)則。
- 鏡像中不能出現(xiàn)嚴(yán)重(Critical)和重要(Important)級別的安全問題。
- 鏡像應(yīng)遵循最小安裝原則,在鏡像中不要引入與應(yīng)用系統(tǒng)運行無關(guān)的組件和軟件包。
- 鏡像應(yīng)為非特權(quán)鏡像(Unprivileged Image),不需要提升容器運行權(quán)限。
- 鏡像應(yīng)經(jīng)過數(shù)字簽名檢查,避免鏡像被覆蓋和篡改。
- 安全掃描僅限在鏡像范圍,不會涉及源碼等其他資源。
根據(jù)掃描結(jié)果確定鏡像的健康級別,只有A、B級別可運行在OpenShift平臺上,避免使用C及以下級別的鏡像,如圖2-6所示。

圖2-6 鏡像安全等級
紅帽的很多基礎(chǔ)鏡像,是可以直接從互聯(lián)網(wǎng)拉?。o須額外的認(rèn)證)的,如RHEL7的基礎(chǔ)容器鏡像,如圖2-7所示。

圖2-7 RHEL7的基礎(chǔ)容器鏡像
查看鏡像的健康等級,如圖2-8所示。

圖2-8 查看鏡像的健康等級
使用Docker或者Podman都可以拉取鏡像,如圖2-9所示。

圖2-9 成功拉取容器鏡像
除了RHEL容器鏡像之外,紅帽還提供了通用基礎(chǔ)鏡像(Universal Base Image,UBI),該鏡像可以運行在任何OCI兼容的Linux上。這意味著我們可以在UBI上構(gòu)建容器化的應(yīng)用程序,將其推送到鏡像倉庫,然后分享給別人。UBI的架構(gòu)如圖2-10所示。

圖2-10 UBI的架構(gòu)
什么時候使用UBI?可以參照以下幾種情況。
- 開發(fā)人員想要構(gòu)建一個容器鏡像,以便可以更廣泛地分發(fā)。
- 運營團隊希望獲得具有企業(yè)全生命周期可支持的基礎(chǔ)鏡像。
- 企業(yè)想要為客戶提供Kubernetes Operator。
- 客戶希望在其紅帽環(huán)境中獲得企業(yè)支持。
- 社區(qū)希望更自由地共享容器化的應(yīng)用程序。
UBI 7支持8類容器鏡像,供我們自行選擇,如圖2-11所示。

圖2-11 UBI 7提供的8類容器鏡像
我們可以在任意安裝了Podman或Docker的Linux服務(wù)器上獲取UBI的鏡像,如圖2-12所示。

圖2-12 獲取UBI的鏡像
目前,紅帽UBI已經(jīng)發(fā)布到Docker Hub中,也就是說即使沒有OpenShift的訂閱,也可以使用這個基礎(chǔ)鏡像,如圖2-13所示。

圖2-13 ubi8-minimal鏡像
2.1.7 C語言應(yīng)用上容器云的方法
截至目前,筆者所接觸的容器云上運行的應(yīng)用,大多基于Java語言,少量基于Python、Go語言。由于Java是解釋型語言,使用OpenJDK或Tomcat的基礎(chǔ)容器鏡像實現(xiàn)應(yīng)用容器化即可,這里不再贅述。而C語言是本地編譯的,這可能會和編譯環(huán)境的操作系統(tǒng)產(chǎn)生關(guān)聯(lián)。在本節(jié)中,我們將具體介紹C語言應(yīng)用上容器云的方法。
C語言應(yīng)用上云需要考慮的第一點是基礎(chǔ)鏡像。如果容器云使用的基礎(chǔ)鏡像與容器云宿主機的操作系統(tǒng)不一致,是否會有問題?舉例而言,如果開發(fā)環(huán)境是SUSE Linux,那應(yīng)用上OpenShift的時候,使用紅帽基于RHEL的容器鏡像,是否能夠正常運行?
不能,但這個問題解決起來并不難。在C語言應(yīng)用上容器云時,我們可以使用比紅帽提供的基礎(chǔ)容器鏡像更為底層的鏡像:Alpine Linux。這樣我們就可以將C語言的編譯和運行環(huán)境做到容器鏡像里,從而規(guī)避了跨Linux操作系統(tǒng)的問題。Alpine Linux是一個由社區(qū)開發(fā)的基于MUSL和BusyBox的Linux操作系統(tǒng),它以安全為理念,面向x86路由器、防火墻、虛擬專用網(wǎng)、IP電話盒及服務(wù)器而設(shè)計。
Alpine Linux的基礎(chǔ)層只有6MB。它使用BusyBox提供外殼程序,根據(jù)MUSL C庫而不是glibc構(gòu)建。MUSL是一個符合POSIX的最小C標(biāo)準(zhǔn)庫。Alpine Linux鏡像中可以正常使用諸如cp和wget之類的命令。BusyBox有自己的方式來執(zhí)行系統(tǒng)設(shè)置任務(wù),例如添加用戶和組。
下面我們來查看Alpine Linux的版本和Linux內(nèi)核的版本。我們在寫Dockerfile的時候,需要選對應(yīng)內(nèi)核版本的Alpine Linux,如圖2-14所示。后文的驗證使用Alpine Linux 3.12。

圖2-14 Alpine Linux的版本
需要注意的是,Alpine Linux的核心應(yīng)用程序都與MUSL連接,而不是glibc,并且Alpine Linux默認(rèn)不包含其他C庫。對于在Linux開發(fā)中已經(jīng)習(xí)慣glibc擴展的人來說,使用MUSL會遇到一些問題。這里簡單舉幾個例子。首先,MUSL中沒有與glibc qsort_r()函數(shù)等效的函數(shù),該函數(shù)用于對任意數(shù)據(jù)結(jié)構(gòu)進(jìn)行排序。其次,MUSL在實現(xiàn)某些功能時存在一些無法解釋的問題。例如,用于格式化時間數(shù)據(jù)的strftime()函數(shù)缺少glibc實現(xiàn)所具有的說明符。
如果需要對微服務(wù)的HTTP通信進(jìn)行加密,則需要決定是在OpenShift集群中還是僅在外部通過HTTP訪問OpenShift上的應(yīng)用時進(jìn)行加密。對到集群的所有流量加密其實很簡單,因為我們可以配置OpenShift路由進(jìn)行邊緣終止。如果在OpenShift集群中也要對流量進(jìn)行加密,則需要為微服務(wù)提供自己的傳輸層安全性(TLS)支持。libmicrohttpd庫支持TLS,但是該支持需要使用許多GNU TLS庫的開發(fā)版本來構(gòu)建。當(dāng)然,這些庫也必須在運行時可用于容器。
此外,需要提供服務(wù)器證書,并為客戶的管理員提供一種獲取該證書的方法。你可以在OpenShift Secret或ConfigMap中提供證書,然后將其作為文件掛載到Pod的文件系統(tǒng)中。這種技術(shù)相對普遍,基于C語言或基于其他任何語言編寫在原理上沒有什么不同。
接下來,我們通過一個基于C語言的微服務(wù)測試代碼驗證上容器的方式。在這個展示中,我們使用solunar_ws,它是基于REST的Web服務(wù),可在指定日期提供特定城市的日出和日落時間并設(shè)置信息。solunar_ws是用C語言實現(xiàn)的基于REST的Web服務(wù)的demo,容器的總大小約為10MB,包括操作系統(tǒng)層、應(yīng)用程序二進(jìn)制文件和相關(guān)性,以及(在此特定情況下)完整的世界時區(qū)數(shù)據(jù)庫。solunar_ws組件只有兩個重要的依賴項:libmicrohttpd和tzdata(全局時區(qū)數(shù)據(jù)庫)。libmicrohttpd是GUN下開源的一個小型HTTP庫,能夠方便地嵌入系統(tǒng)中。它支持HTTP 1.1可以同時監(jiān)聽多個端口,具有select、poll、pthread、thread poo等多種模式。tzdata軟件包(全稱為Time Zone and Daylight-Saving Time Data)可供各個Linux系統(tǒng)安裝,以讀取時區(qū)數(shù)據(jù)庫中的數(shù)據(jù)。
查看如下Dockerfile,我們將C語言應(yīng)用編譯和容器化:
FROM alpine:3.12 RUN apk add git build-base tzdata zlib-dev && \ wget https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-latest.tar.gz && \ tar xfvz libmicrohttpd-latest.tar.gz && \ (cd libmi*; ./configure; make install) && \ git clone https://github.com/kevinboone/solunar_ws.git && \ make -C solunar_ws # Binary solunar_ws ends up in / directory FROM alpine:3.12 RUN apk add tzdata COPY --from=0 /solunar_ws/solunar_ws / COPY --from=0 /usr/local/lib/libmicrohttpd.so.12 /usr/local/lib USER 1000 CMD ["/solunar_ws"]
以上Dockerfile的整體構(gòu)建包含兩個階段。
第一階段:基于Alpine Linux 3.12基礎(chǔ)鏡像下載libmicrohttpd的源代碼并進(jìn)行構(gòu)建,然后對solunar_ws進(jìn)行相同操作。這些源代碼來自不同的地方,但是它們都是以相同的方式編譯。在此示例中,請注意,在構(gòu)建Web服務(wù)之前,我們必須先構(gòu)建libmicrohttpd的原因是Web服務(wù)依賴它。
本階段鏡像構(gòu)建完以后,鏡像大小約為210MB。
第二階段:從相同的Alpine Linux 3.12基礎(chǔ)層開始,僅安裝運行時所需的軟件包,即tzdata。然后,從先前的版本中復(fù)制容器在運行時所需的兩個文件:二進(jìn)制solunar_ws和庫libmicrohttpd.so.12。
查看鏡像構(gòu)建過程:
[root@helper c]# docker build -t davidwei/capp:1.0 . Sending build context to Docker daemon 2.56kB Step 1/8 : FROM alpine:3.12 3.12: Pulling from library/alpine Digest: sha256:36553b10a4947067b9fbb7d532951066293a68eae893beba1d9235f7d11a20ad Status: Downloaded newer image for alpine:3.12 ---> 13621d1b12d4 Step 2/8 : RUN apk add git build-base tzdata zlib-dev && wget https://ftp.gnu. org/gnu/libmicrohttpd/libmicrohttpd-latest.tar.gz && tar xfvz libmicrohttpd- latest.tar.gz && (cd libmi*; ./configure; make install) && git clone https://github.com/kevinboone/solunar_ws.git && make -C solunar_ws ---> Using cache ---> 1d295e9520a1 Step 3/8 : FROM alpine:3.12 ---> 13621d1b12d4 Step 4/8 : RUN apk add tzdata ---> Using cache ---> bb67735c5825 Step 5/8 : COPY --from=0 /solunar_ws/solunar_ws / ---> 7eff173bd44c Step 6/8 : COPY --from=0 /usr/local/lib/libmicrohttpd.so.12 /usr/local/lib ---> d64545f7695e Step 7/8 : USER 1000 ---> Running in 34c744835d6f Removing intermediate container 34c744835d6f ---> 6c8ba9f65b94 Step 8/8 : CMD ["/solunar_ws"] ---> Running in ce84fd4cfb84 Removing intermediate container ce84fd4cfb84 ---> fb0ab1acd1b0 Successfully built fb0ab1acd1b0 Successfully tagged davidwei/capp:1.0
鏡像構(gòu)建成功后,如圖2-15所示。

圖2-15 查看構(gòu)建好的鏡像
我們可以在本地運行容器鏡像:
#docker run -d -p 8080:8080 davidwei/capp:1.0
然后通過瀏覽器訪問應(yīng)用,代碼如下,訪問結(jié)果如圖2-16所示。
http://localhost/day/london/jun%2020

圖2-16 訪問C語言應(yīng)用
在OpenShift中,我們可以使用以下三種方式部署應(yīng)用。
- 利用Dockerfile部署應(yīng)用,自動生成Deployment。
- 部署容器鏡像,自動生成Deployment。
- 手工書寫Deployment、Service等對象,部署容器鏡像。
下面展示第三種部署方法,yaml文件如下所示:
kind: DeploymentConfig apiVersion: apps.openshift.io/v1 metadata: name: solunar-ws spec: replicas: 1 strategy: type: Rolling selector: name: solunar-ws template: metadata: name: solunar-ws labels: name: solunar-ws spec: containers: - env: - name: SOLUNAR_WS_LOG_LEVEL value: "1" name: solunar-ws image: quay.io/davidwei/capp:1.0 imagePullPolicy: Always ports: - containerPort: 8080 protocol: TCP livenessProbe: failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 tcpSocket: port: 8080 timeoutSeconds: 1 readinessProbe: failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 tcpSocket: port: 8080 timeoutSeconds: 1 resources: limits: memory: 128Mi securityContext: privileged: false --- kind: Service apiVersion: v1 metadata: name: solunar-ws spec: ports: - name: solunar-ws port: 8080 protocol: TCP targetPort: 8080 selector: name: solunar-ws
從之前的步驟可以看出,在OpenShift上運行C語言應(yīng)用是完全沒問題的。但是,由于C語言無法像Java語言那樣實現(xiàn)外部構(gòu)建(mvn),因此我們不建議讓C語言應(yīng)用參與到OpenShift的CI/CD中。我們在書寫Dockerfile的時候,需要以Alpine Linux為基礎(chǔ)鏡像,把C語言應(yīng)用編譯和運行所依賴的環(huán)境都做到容器鏡像中。如果應(yīng)用的源碼發(fā)生變化,則在OpenShift上以Dockerfile的方式重新部署應(yīng)用即可。
在OpenShift上選擇以Dockerfile方式部署應(yīng)用,輸入Dockerfile所在的git地址,選擇自動生成Route和Deployment,如圖2-17所示。

圖2-17 在OpenShift上部署C語言應(yīng)用
在介紹了C語言應(yīng)用上容器云后,接下來我們介紹如何將應(yīng)用遷移到輕量級應(yīng)用服務(wù)器。
2.1.8 容器云的混沌工程
混沌工程是在分布式系統(tǒng)上進(jìn)行實驗的學(xué)科,目的是建立系統(tǒng)抵御生產(chǎn)環(huán)境中失控條件的能力以及信心。測試混沌工程本身是一種生產(chǎn)演練,即通過周期化和自動化的生產(chǎn)演練,發(fā)現(xiàn)未知的故障場景,處理未知場景下的問題,從而提升系統(tǒng)的可用性。
接下來,我們簡單介紹混沌工程的發(fā)展?;煦绻こ淌?010年由Netflix提出的,到2014年,混沌思想成為Netflix的一種企業(yè)文化(內(nèi)部設(shè)置混沌工程師崗位)。2015年Netflix提出混沌工程原則。2016年,第一個混沌工程商業(yè)化的產(chǎn)品出現(xiàn):Gremlin。國內(nèi)對混沌工程探索比較多的公司是阿里巴巴。它開源了ChaosBlade混沌工程工具。
想到混沌工程,我們就會想到混沌測試,也會想到傳統(tǒng)的壓力測試?;煦鐪y試和壓力測試的主要區(qū)別如下所示。
- 對象:混沌測試側(cè)重現(xiàn)實世界意外事件引起的系統(tǒng)不穩(wěn)定;而壓力測試偏向于系統(tǒng)自身的流程不穩(wěn)定。
- 目標(biāo):混沌測試側(cè)重實踐無法預(yù)知的信息,幫助我們更好地認(rèn)識系統(tǒng);而壓力測試更偏重是否達(dá)到預(yù)期。
- 結(jié)果:混沌測試用來探索未知、發(fā)現(xiàn)新知識;壓力測試主要用來驗證。
- 環(huán)境:混沌測試離生產(chǎn)越近越好,而且要持續(xù)自動化實驗;壓力測試通常離生產(chǎn)越遠(yuǎn)越好,主要是內(nèi)部環(huán)境的自主控制。
混沌工程的五個原則如下。
- 建立穩(wěn)定狀態(tài)的假設(shè):混沌工程只有在系統(tǒng)穩(wěn)定的情況下才能做,即在穩(wěn)定的系統(tǒng)上做混沌工程。
- 多樣化現(xiàn)實世界時間:混沌工程的故障,必須是模擬真實世界的物理事件,如拔網(wǎng)線、機房停電、磁盤滿了、內(nèi)存燒了。
- 在生產(chǎn)環(huán)境運行實驗:應(yīng)該在生產(chǎn)環(huán)境運行測試,只有這樣才會最真實?;煦绻こ桃欢ㄊ窃诜植际较到y(tǒng)中做,如果是單機系統(tǒng),一定會影響生產(chǎn)的業(yè)務(wù)。
- 持續(xù)自動化實驗:不做樣子工程,要做持續(xù)化模擬實驗。
- 最小化爆炸半徑:最小化爆炸半徑?jīng)]做好的典型場景是“切爾諾貝利事件”。在生產(chǎn)上的故障測試,造成整個核電站出現(xiàn)問題,導(dǎo)致核泄漏。我們一定要控制故障范圍,比如模擬一個CPU故障,而不是所有CPU故障。
目前混沌測試的工具較多,除了有阿里開源的ChaosBlade Box,還有其他開源工具,如Powerfulseal、Litmus、Kraken、Chaos Mesh。目前國內(nèi)企業(yè)使用ChaosBlade Box較多。如果客戶對構(gòu)建混沌工程平臺無太多要求,可以直接使用ChaosBlade Box。企業(yè)使用混沌工程應(yīng)該是來構(gòu)建一個平臺,而不僅僅是對開源工具的驗證。因此我們在構(gòu)建混沌工程平臺時,可能需要多種開源工具進(jìn)行集成。
混沌工程平臺需要具備的功能可以從工具視角和流程視角兩方面來看。
從流程視角來看,混沌工程需要具備以下四種功能。
1)實驗計劃管理功能:模板管理、流水線編排、演練方案設(shè)計、審批流程(技術(shù)方案評審)管理。
2)自動化執(zhí)行功能:執(zhí)行控制與風(fēng)險管控,故障注入,應(yīng)急恢復(fù),自動化操作腳本、代理。
3)故障觀察功能:評價系統(tǒng)健康的KPI指標(biāo),故障感知涉及的主動撥測、被動監(jiān)控、數(shù)據(jù)可視化等功能,應(yīng)急處置協(xié)同連接功能。
4)事后環(huán)境恢復(fù)功能:環(huán)境恢復(fù)的自動化、環(huán)境恢復(fù)的數(shù)據(jù)分析、總結(jié)報告、跟進(jìn)閉環(huán)。
從流程視角來看,混沌工程需要在以下方面實現(xiàn)如下功能。
1)決策層面,接受復(fù)雜與不確定性,認(rèn)同故障常態(tài)化,并推動有效應(yīng)對故障的架構(gòu)設(shè)計與應(yīng)急管理。
2)執(zhí)行層面,加強故障注入、故障觀察、故障恢復(fù)的管控能力,控制好故障影響范圍,在對生產(chǎn)保持敬畏之心的基礎(chǔ)上踐行混沌工程,并建立持續(xù)優(yōu)化的閉環(huán)協(xié)同機制。我們使用混沌工程最終是為了解決問題。
3)場景層面,生產(chǎn)環(huán)境注入故障實驗,實際協(xié)同應(yīng)急環(huán)境執(zhí)行應(yīng)急管理。
4)工具層面,加強故障注入的風(fēng)險管控、操作留痕,并與實際工作場景涉及的工具連接。
我們以為某客戶設(shè)計的混沌工程平臺的建設(shè)步驟為例,如表2-1所示。
表2-1 混沌工程平臺建設(shè)步驟

混沌工程平臺的目標(biāo)架構(gòu)如圖2-18所示。

圖2-18 混沌工程平臺的目標(biāo)架構(gòu)
為了幫助讀者對開源混沌測試工具有所了解,接下來我們介紹Kraken工具的驗證效果。需要指出的是,Kraken比較適合簡單的Kubernetes/OpenShift故障注入場景,本節(jié)列出該工具的驗證效果只是為了幫助讀者理解容器云的故障注入實現(xiàn),并非推薦讀者使用Kraken。
Kraken工具是紅帽主導(dǎo)的開源項目,以故意注入故障并在Kubernetes/OpenShift環(huán)境中造成混亂的方式進(jìn)行測試。構(gòu)建Kraken的目標(biāo)是確認(rèn)在故障注入期間和之后,處于混亂狀態(tài)的Kubernetes/OpenShift組件不僅能夠恢復(fù),而且在性能和規(guī)模方面不會降低。
通過Kraken,我們可以簡單的方式在Kubernetes/OpenShift集群中注入混亂。用戶可以持續(xù)引起混亂,并從長遠(yuǎn)角度觀察集群如何響應(yīng)各種故障。另外,可以驗證集群能否從一組故障注入引發(fā)的混亂中完全恢復(fù)到其正常的健康狀態(tài)。Kraken的工作示意圖如圖2-19所示。

圖2-19 Kraken工作示意圖
Kraken底層調(diào)用PowerfulSeal(一種測試Kubernetes的開源工具)。該工具將故障注入Kubernetes集群中,以盡早發(fā)現(xiàn)問題。紅帽在PowerfulSeal中打開了許多增強功能,以改善該工具的覆蓋范圍。
Kraken支持以下幾個混亂場景。
1. Pod混亂場景
Pod的健康狀態(tài)不僅關(guān)系到Pod是否已啟動并正在運行,還關(guān)系到其能否接收和響應(yīng)請求以及能否從混亂注入中恢復(fù)的能力。通過調(diào)整配置文件,用戶可以殺死任何命名空間中的Pod。Kraken當(dāng)前具有在以下命名空間中殺死Pod并得到預(yù)期結(jié)果的方案。
- etcd:驗證資源持久性內(nèi)的混亂情況不會破壞etcd集群。
- openshift-apiserver:殺死一個Pod副本,看看我們是否仍然能夠在沒有停機的情況下訪問OpenShift API。
- openshift-kube-apiserver:破壞包括Pod、Service,rc等在內(nèi)的API對象的有效性,并確認(rèn)配置不受影響。
- Prometheus:對OpenShift的警報和監(jiān)視組件造成嚴(yán)重破壞,并且看不到警報中斷。
- 隨機OpenShift命名空間:大規(guī)模的Pod殺死功能,能夠測試OpenShift和用戶應(yīng)用程序所有區(qū)域的彈性。
2. 節(jié)點混亂場景
Kraken支持以下幾種節(jié)點混亂方案。
- 關(guān)閉節(jié)點:將節(jié)點實例按指定的時間停止。Kraken還使用戶能夠在節(jié)點實例停止后啟動它。
- 重啟節(jié)點:重新啟動節(jié)點實例。
- 終止節(jié)點:終止節(jié)點實例,在集群中刪除該節(jié)點。
- 讓節(jié)點崩潰:混亂場景導(dǎo)致內(nèi)核崩潰,從而使節(jié)點崩潰。
- 停止節(jié)點的kubelet服務(wù):Kraken提供了一種方案來停止節(jié)點的kubelet服務(wù)。它還使用戶能夠在停止kubelet服務(wù)之后啟動它。
目前,Kraken支持以停止、重新引導(dǎo)和終止等適用于AWS云類型的任何節(jié)點實例(后面一定會適應(yīng)到私有云場景)的混亂情況。
3. 集群關(guān)閉場景
Kraken提供了一個混亂場景,可以關(guān)閉所有節(jié)點(包括控制平面),并在指定的持續(xù)停止時間后重新啟動它們,以查看集群是否從混亂注入中恢復(fù)、穩(wěn)定并能夠滿足請求。
Kraken可以作為Kubernetes部署在集群內(nèi)部運行。但是,建議從集群外部運行Kraken,以確?;煦缱⑷氩粫馔鈿⑺繩raken所運行的Pod。我們將Kraken安裝在一臺獨立的虛擬機上,對Kubernetes/OpenShift發(fā)起測試。由于篇幅有限,這里不展示Kraken安裝的步驟,具體步驟見https://github.com/cloud-bulldozer/kraken/blob/master/docs/installation.md。
我們查看Kraken工具的配置文件的核心部分,文件路徑為#cat /home/david/kraken/config/config.yaml。
kraken: distribution: openshift # 確定發(fā)行版是Kubernetes還是Openshift kubeconfig_path: /home/david/1/kubeconfig # kubeconfig的路徑 exit_on_failure: False # 當(dāng)一個后動作方案失敗時退出 litmus_version: v1.10.0 # 要安裝的Litmus版本 litmus_uninstall: False # 如果失敗,卸載Litmus chaos_scenarios: # 要加載的policies/chaos列表 - pod_scenarios: # 要加載的pod故障場景 - - scenarios/etcd.yml - - scenarios/regex_openshift_pod_kill.yml - scenarios/post_action_regex.py - node_scenarios: # 要加載的節(jié)點故障場景 - scenarios/node_scenarios_example.yml - pod_scenarios: - - scenarios/openshift-apiserver.yml - - scenarios/openshift-kube-apiserver.yml - time_scenarios: # 要加載的時間錯亂故障場景 - scenarios/time_scenarios_example.yml - litmus_scenarios: # 要加載的Litmus場景 - - https://hub.litmuschaos.io/api/chaos/1.10.0?file=charts/generic/ node-cpu-hog/rbac.yaml - scenarios/node_hog_engine.yaml - cluster_shut_down_scenarios: - - scenarios/cluster_shut_down_scenario.yml - scenarios/post_action_shut_down.py
在上面的配置文件中,最關(guān)鍵的是設(shè)置distribution和kubeconfig_path。配置文件其余部分是測試場景對應(yīng)的yaml配置文件和Python腳本。如果我們想修改某個測試項,修改對應(yīng)的yaml文件即可,例如修改節(jié)點測試場景的yaml文件。如果我們不想測試某些項目,將yaml文件中對應(yīng)的行注釋掉或刪除即可。yaml文件路徑為[david@helper kraken]$ cat scenarios/node_scenarios_example.yml.
node_scenarios: - actions: - node_stop_start_scenario - stop_start_kubelet_scenario - node_crash_scenario node_name: label_selector: node-role.kubernetes.io/worker with matching label_selector is selected for node chaos scenario injection instance_kill_count: 1 timeout: 120 - actions: - node_reboot_scenario node_name: label_selector: node-role.kubernetes.io/worker instance_kill_count: 1 timeout: 120
在上面的配置文件中,我們對集群關(guān)閉場景進(jìn)行了混沌測試。接下來,我們對主要混沌測試過程進(jìn)行分析。
啟動混沌測試后,Kraken會通過kubeconfig_path指定的文件獲取OpenShift集群信息,如圖2-20所示。

圖2-20 Kraken獲取OpenShift集群信息
查看Kill Pod的測試場景,測試通過,如圖2-21所示。

圖2-21 Kill Pod的測試場
查看Kill API Server場景,如圖2-22所示。

圖2-22 Kill API Server場景
Crash節(jié)點場景如圖2-23所示。

圖2-23 Crash節(jié)點場景
查看API Server Pod,有一個Pod被刪除后自動重建,如圖2-24所示。

圖2-24 API Server Pod被刪除后自動重建
結(jié)合使用Kraken與Cerberus,除了可以完成全面的集群運行狀況檢查外,還可以在合理的時間內(nèi)仔細(xì)檢查目標(biāo)分組是否從混亂注入中恢復(fù)。
2.1.9 微服務(wù)治理框架的選擇
目前主流的微服務(wù)治理框架主要是Spring Cloud。而Istio作為新一代微服務(wù)框架,越來越受到關(guān)注。在本節(jié)中,我們分享如何選擇這兩種微服務(wù)框架。
Istio被引入的主要原因是傳統(tǒng)微服務(wù)存在以下問題。
- 多語言技術(shù)棧不統(tǒng)一:C++、Java、PHP、Go。Spring Cloud無法提出非Java語言的微服務(wù)治理。
- 服務(wù)治理周期長:微服務(wù)治理框架與業(yè)務(wù)耦合,上線周期長,策略調(diào)整周期長。
- 產(chǎn)品能力弱:Spring Cloud缺乏平臺化和產(chǎn)品化的能力,可視化能力弱。
那么,是不是說企業(yè)一定需要使用Istio?不是。表2-2是對Spring Cloud與Istio的簡單對比。
表2-2 Spring Cloud與Istio的對比與選擇

也就是說,如果企業(yè)的開源語言主要是Java、更新升級不頻繁、無過多高級治理功能需求、業(yè)務(wù)規(guī)模不是非常大,使用Spring Cloud是比較合適的。
如果企業(yè)要引入Istio,引入成本有多高?具體分三種情況,如表2-3所示。
表2-3 企業(yè)引入Istio的成本

接下來,我們對在OpenShift上通過Spring Cloud和Istio實現(xiàn)的企業(yè)微服務(wù)治理進(jìn)行對比,如表2-4所示。
表2-4 Spring Cloud與Istio的實現(xiàn)對比


從開放性以及先進(jìn)性角度來說,建議將服務(wù)網(wǎng)格Istio作為首選微服務(wù)應(yīng)用框架。接下來我們介紹Istio在實踐中的使用建議。
Istio運維方面的建議包括版本選擇、備用環(huán)境、評估范圍、配置生效、功能健壯性參考、入口流量選擇。當(dāng)然,這些建議只是基于目前我們在測試過程中得到的數(shù)據(jù)總結(jié)的。隨著Istio使用越來越廣泛,相信最佳實踐將會越來越豐富。
1. 版本選擇
Istio是一個迭代很快的開源項目。截止到2021年5月,社區(qū)最新的Istio版本為1.9。
頻繁的版本迭代會給企業(yè)帶來一些困擾:是堅持使用目前已經(jīng)測試過的版本,還是使用社區(qū)的最新版本?在前文中我們已經(jīng)提到,紅帽針對Istio有自己的企業(yè)版,通過Operator進(jìn)行部署和管理。出于安全性和穩(wěn)定性的考慮,紅帽Istio往往比社區(qū)要晚兩個小版本左右。因此建議使用紅帽Istio的最新版本。目前看,社區(qū)的最新版本的Istio的穩(wěn)定性往往不盡如人意。
2. 備用環(huán)境
針對相同的應(yīng)用,在OpenShift環(huán)境中部署一套不被Istio管理的環(huán)境。比如文中的三層微服務(wù),獨立啟動一套不被Istio管理的應(yīng)用,使用OpenShift原本的訪問方式即可。這樣做的好處是,每當(dāng)進(jìn)行Istio升級或者部分參數(shù)調(diào)整時都可以提前進(jìn)行主從切換,讓流量切換到?jīng)]有被Istio管理的環(huán)境中,將Istio升級調(diào)整驗證完畢后再將流量切換回來。
3. 評估范圍
由于Istio對微服務(wù)的管理是非代碼侵入式的。因此通常情況下,業(yè)務(wù)服務(wù)需要進(jìn)行微服務(wù)治理,需要被Istio納管。而對于沒有微服務(wù)治理要求的非業(yè)務(wù)容器,不必強行納管在Istio中。當(dāng)非業(yè)務(wù)容器需要承載業(yè)務(wù)時,被Istio納管也不需要修改源代碼,重新在OpenShift上注入Sidecar部署即可。
4. 配置生效
如果系統(tǒng)中已經(jīng)有相關(guān)對象的配置,我們需要使用oc replace -f指定配置文件來替換之前配置的對象。Istio中有的配置策略能夠較快生效,有的配置需要一段時間才能生效,如限流、熔斷等。新創(chuàng)建策略(oc create -f)的生效速度要高于替換性策略(oc replace -f)。因此在不影響業(yè)務(wù)的前提下,可以在應(yīng)用新策略之前,先刪除舊策略。
此外,Istio的配置生效,大多是針對微服務(wù)所在的項目,但也有一些配置是針對Istio系統(tǒng)。因此,在配置應(yīng)用時,要注意指定對應(yīng)的項目。
在OpenShift中,Virtual Service和Destination Rules都是針對項目生效,因此配置應(yīng)用時需要指定項目。
5. 功能健壯性參考
從筆者大量的測試效果看,健壯性較強的功能有基于目標(biāo)端的藍(lán)綠、灰度發(fā)布,基于源端的藍(lán)綠、灰度發(fā)布,灰度上線,服務(wù)推廣,延遲和重試,錯誤注入,mTLS,黑白名單。
健壯性有待提升的功能有限流和熔斷。
所以,從整體上看,Istio的功能雖日趨完善,但仍有待提升。
6. 入口流量方式選擇
在創(chuàng)建Ingress網(wǎng)關(guān)的時候,會自動在OpenShift的Router上創(chuàng)建相應(yīng)的路由。Ingress網(wǎng)關(guān)能夠暴露的端口要多于Router。所以,我們可以根據(jù)需要選擇通過哪條路徑來訪問應(yīng)用。在Istio體系中的應(yīng)用不使用Router也可以正常訪問微服務(wù)。但是PaaS上運行的應(yīng)用未必都是Istio體系下的,其他非微服務(wù)或者非Istio體系下的服務(wù)還是要通過Router訪問。此外,Istio本身的監(jiān)控系統(tǒng)和Kiali的界面都是通過Router訪問的。
相比Spring Cloud,Istio較好地實現(xiàn)了微服務(wù)的路由管理。但在實際生產(chǎn)中,僅有微服務(wù)的路由管理是不夠的,還需要諸如不同微服務(wù)之間的業(yè)務(wù)系統(tǒng)集成管理、微服務(wù)的API管理、微服務(wù)中的規(guī)則流程管理等。
2.1.10 容器云常用的中間件與數(shù)據(jù)服務(wù)選擇
前面我們提到,容器云主要適合承載無狀態(tài)的應(yīng)用。那么,容器云常用的中間件和數(shù)據(jù)服務(wù)都有哪些?企業(yè)客戶應(yīng)該如何選擇呢?本節(jié)將詳細(xì)介紹。
對于消息中間件,我們針對常見的3種消息中間件進(jìn)行對比,如表2-5所示。
表2-5 常見消息中間件對比

我們可以得出如下結(jié)論:
- RocketMQ是唯一支持BASE事務(wù)特征的消息中間件,適用于微服務(wù)的事務(wù)消息;
- ActiveMQ Artemis提供跨語言支持,可以實現(xiàn)可靠消息傳遞;
- Kafka適合日志、行為數(shù)據(jù)等海量數(shù)據(jù)的場景。
在容器云中,我們通??梢允褂肦ocketMQ、ActiveMQ Artemis和Kafka這三種消息中間件中的任意一種。如果不需要實現(xiàn)BASE事務(wù),使用ActiveMQ Artemis即可。在海量數(shù)據(jù)場景中,建議使用Kafka。
對于關(guān)系型數(shù)據(jù)庫,我們對以下3種常見關(guān)系型數(shù)據(jù)庫進(jìn)行對比,如表2-6所示。
表2-6 關(guān)系型數(shù)據(jù)庫的對比

我們可以得出如下結(jié)論:
- 在非容器環(huán)境中,建議使用Oracle數(shù)據(jù)庫,暫時不作變更;
- 對于新建的系統(tǒng),如果是容器云環(huán)境,建議采用MySQL數(shù)據(jù)庫,不僅開源而且可水平擴展,為向分布式數(shù)據(jù)庫體系演進(jìn)打好基礎(chǔ);
- 遺留系統(tǒng)改造時逐步從Oracle DB向MySQL遷移。
對于分布式關(guān)系型數(shù)據(jù)庫,我們對以下5種常見分布式關(guān)系型數(shù)據(jù)庫進(jìn)行對比,如表2-7所示。
表2-7 分布式關(guān)系型數(shù)據(jù)庫對比

我們可以得出如下結(jié)論:
- 在非強一致性的業(yè)務(wù)場景下,建議使用商業(yè)閉源的PolarDB-X;
- 在強一致性的業(yè)務(wù)場景下,可以使用TiDB和OceanBase,對于穩(wěn)定性要求高的場景,推薦選用OceanBase;如果場景中有OLAP,則推薦選用TiDB。
從開源的角度看,我們建議在容器云上使用TiDB分布式關(guān)系型數(shù)據(jù)庫。
對于分布式緩存,我們對以下4種緩存進(jìn)行對比,如表2-8所示。
表2-8 分布式緩存對比

從表2-8可以看出,Redis是成熟度最高、使用度最廣泛的商業(yè)開源鍵–值(Key-value)型數(shù)據(jù)庫。在容器云上,我們使用Redis作為分布式緩存。
對于文檔存儲型NoSQL產(chǎn)品,我們對比如下4種方案,如表2-9所示。
表2-9 NoSQL方案對比

從表2-9中可以得出結(jié)論:MongoDB是成熟度最高、使用度最廣泛和可擴展性最好的文檔型數(shù)據(jù)庫。我們在容器云上選擇使用MongoDB文檔型數(shù)據(jù)庫。
對于流程及規(guī)則引擎產(chǎn)品,我們對比如下4種方案,如表2-10所示。
表2-10 流程及規(guī)則引擎方案對比

結(jié)合表2-10的對比,在容器云上,我們推薦使用jBPM。
綜上所述,在容器云中,我們推薦的開源中間件和數(shù)據(jù)服務(wù)如表2-11所示。
表2-11 推薦使用的開源中間件和數(shù)據(jù)服務(wù)

- 中臺架構(gòu)與實現(xiàn):基于DDD和微服務(wù)
- IT服務(wù)供應(yīng)鏈協(xié)調(diào)
- 企業(yè)IT架構(gòu)轉(zhuǎn)型之道:阿里巴巴中臺戰(zhàn)略思想與架構(gòu)實戰(zhàn)
- 數(shù)字化運維:IT運維架構(gòu)的數(shù)字化轉(zhuǎn)型
- 數(shù)據(jù)科學(xué)家訪談錄
- 微服務(wù)治理:體系、架構(gòu)及實踐
- 微信公眾平臺搭建與開發(fā)揭秘(第2版)
- Axure RP8 網(wǎng)站和APP原型制作 從入門到精通
- 這才是用戶體驗設(shè)計:人人都能看懂的產(chǎn)品設(shè)計書
- IT能力與企業(yè)信息化
- 數(shù)據(jù)中臺:讓數(shù)據(jù)用起來(第2版)
- IT服務(wù)管理及CMMI-SVC實施
- 日志管理與分析(第2版)
- IT傳:信息技術(shù)250年
- 云計算解碼