阿里云 云原生下的開發(fā)測試

來源:云棲號
作者:云棲號
時間:2020-08-20
2048
在云原生時代下,軟件的迭代速度越來越快,對測試的要求也越來越高,很多開發(fā)者開始使用Kubernetes來管理測試環(huán)境。在這個過程中,開發(fā)者會遇到很多困難,其中最主要的兩個問題是:一、本地環(huán)境與Kubernetes集群網(wǎng)絡(luò)不通問題;二、共用測試環(huán)境時,相互干擾的問題。

測試環(huán)境管理之困與阿里巴巴的解決之道

在云原生時代下,軟件的迭代速度越來越快,對測試的要求也越來越高,很多開發(fā)者開始使用Kubernetes來管理測試環(huán)境。在這個過程中,開發(fā)者會遇到很多困難,其中最主要的兩個問題是:一、本地環(huán)境與Kubernetes集群網(wǎng)絡(luò)不通問題;二、共用測試環(huán)境時,相互干擾的問題。

在阿里巴巴內(nèi)部,我們主要通過扁平的內(nèi)網(wǎng)IP和項(xiàng)目環(huán)境兩個機(jī)制來解決以上痛點(diǎn)。扁平的內(nèi)網(wǎng)IP主要是基于CNI(Conteinre Network Interface)機(jī)制改造Kubernetes的IP邏輯實(shí)現(xiàn)的,可以使集群中的每個Pod分配到的IP與本地機(jī)器分配到的IP處于一個大的網(wǎng)絡(luò)環(huán)境下,這樣就可以解決本地環(huán)境和集群之間互通的問題。項(xiàng)目環(huán)境是基于RPC、消息中間件的虛擬環(huán)境,從表面上看,每個項(xiàng)目環(huán)境都是一套獨(dú)立完整的測試環(huán)境,由一系列服務(wù)組成集群,而實(shí)際上,除了個別當(dāng)前使用者想要測試的服務(wù),其余服務(wù)都是通過路由系統(tǒng)和消息中間件虛擬出來的,指向公共基礎(chǔ)環(huán)境的相應(yīng)服務(wù)。這樣操作的好處是,第一不會占用大量的開發(fā)資源;第二,不會影響公共基礎(chǔ)環(huán)境的穩(wěn)定性。

ia_3300000006.jpg

阿里巴巴的這種測試環(huán)境帶來的測試體驗(yàn)非常爽,本地與集群雙向互通,每個子項(xiàng)目都可以獨(dú)占一個“項(xiàng)目環(huán)境”,彼此不會干擾。但是這種測試環(huán)境管理方式實(shí)施起來比較復(fù)雜,只適合大型的集團(tuán)公司,我們希望將這種測試體驗(yàn)以“更輕”的方式實(shí)現(xiàn),普惠更多開發(fā)者。于是云效團(tuán)隊(duì)推出了云原生測試環(huán)境工具箱,主要包括kt-connect和kt-virtual-environment這兩個開源工具。

通過kt-connect解決本地與集群雙向互通問題

首先,我們來聊一聊如何使用Kubernetes測試環(huán)境開源工具箱中的kt-connect解決“本地與集群雙向互通”的問題。

我們假設(shè)有一位主人公叫“程序員小黑”,他所在公司采用了微服務(wù)相關(guān)的技術(shù)實(shí)踐。小黑在做本地開發(fā)的過程中,會遇到兩種聯(lián)調(diào)場景,即我需要聯(lián)調(diào)其它服務(wù)和其它服務(wù)調(diào)用我。

我們先來看第一個場景:聯(lián)調(diào)其它服務(wù)。前面講到本地環(huán)境和K8S集群中的網(wǎng)絡(luò)是相互隔離的,那么在本地完成代碼開發(fā)后,如何高效的與其它服務(wù)進(jìn)行聯(lián)調(diào)呢?最“簡單粗暴”的一種方式,就是在本地完整的部署一套測試環(huán)境,這種方式的優(yōu)點(diǎn)很明顯,效率最高,而且沒有外部依賴。缺點(diǎn)也同樣明顯,一是對開發(fā)人員的素質(zhì)要求非常高,二是要占用大量本地的開發(fā)資源,對本地開發(fā)機(jī)的性能要求很高。第二種方式是利用Kubernetes等工具在本地部署一套K8S集群,這種方式可以在一定程度上降低開發(fā)人員“上手成本”,但是也同樣存在占用大量本地開發(fā)資源的問題。還有一種處理方式是利用VPN調(diào)用K8S集群中的服務(wù),這種方式存在兩個問題,一個是本地的服務(wù)調(diào)用是脫離了Istio的流量控制的,第二個問題VPN這種方式只解決了本地到集群的通訊,對于回調(diào)這種方式是解決不了的。

ia_3300000007.jpg

那么,有沒有更簡單的方式呢?答案是肯定的,通過KT-Connect工具可以讓開發(fā)者一鍵建立本地到Kubernetes集群的網(wǎng)絡(luò)連接。開發(fā)者只需要運(yùn)行一個“connect”命令,就可以自動在集群中創(chuàng)建一個代理容器,并且通過這個代理容器建立本地與集群的VPN連接,同時KT-Connect也會內(nèi)置DNS服務(wù),本地服務(wù)可以直接通過服務(wù)的名稱進(jìn)行服務(wù)調(diào)用,就好像本地的程序運(yùn)行在K8S集群中一樣。在KT-Connect中,我們給這個代理容器取了一個名字“shadow pod”,即“影子”。它就像是本地服務(wù)在集群中的影子,通過它來完成本地服務(wù)與集群中服務(wù)的相互調(diào)用。

接下來,我們來看第二個場景:其它服務(wù)調(diào)用我。在聯(lián)調(diào)時,小黑不僅需要調(diào)用其它人的服務(wù),同時作為服務(wù)的生產(chǎn)者又會被其它服務(wù)調(diào)用。這時只打通本地到集群的服務(wù)是不能滿足聯(lián)調(diào)測試需求的,必須同時讓集群中的服務(wù)也可以訪問本地的服務(wù)。

ia_3300000008.jpg

這就需要使用KT-Connect的第二個命令——“Exchange”。Exchange(交換)命令會在集群內(nèi)部署一個代理容器,并替換集群中指定服務(wù)的目標(biāo)容器,從而將發(fā)往該服務(wù)的所有流量攔截并轉(zhuǎn)發(fā)到本地端口。這是一種“完全替換”,這就意味著在同一時間點(diǎn),只有一位開發(fā)者可以將他本地的服務(wù)加入到集群中。為了解決這個問題,KT-Connect提供了第三個命令——Mesh(混合)。當(dāng)我們在本地運(yùn)營“Mesh”命令后,我們同樣會把本地服務(wù)加入到集群里面,但是會保持原有的目標(biāo)服務(wù)狀態(tài)不變,并且本地服務(wù)會繼承目標(biāo)服務(wù)中所有的標(biāo)簽。依照K8S本身服務(wù)發(fā)現(xiàn)的原理,請求流量會被隨機(jī)地轉(zhuǎn)發(fā)到原有服務(wù)或本地的服務(wù)。同時配合Istio的流量規(guī)則,就可以讓所有正常流量依然保持對原應(yīng)用的訪問,而只對一些有特殊標(biāo)記的的請求轉(zhuǎn)發(fā)到本地。從而可以實(shí)現(xiàn)在一套公用測試環(huán)境的基礎(chǔ)上各自獨(dú)立的完成本地的集成聯(lián)調(diào)。

KT-Connect背后的原理

我們通過KT-Connect的“connect”“Exchange”“Mesh”命令實(shí)現(xiàn)了本地到集群的雙向網(wǎng)絡(luò)互通,看起來似乎很神奇,其實(shí)背后并沒有什么黑科技。我們只是綜合利用了Kubernetes原有的特性及SSH這個我們經(jīng)常會用到的網(wǎng)絡(luò)協(xié)議,通過Kubectl的端口轉(zhuǎn)發(fā)可以實(shí)現(xiàn)將集群中服務(wù)的端口映射到本地,通過SSH協(xié)議建立本地與集群之間的隧道。

ia_3300000009.jpg

以“Connect”命令為例,了解一下KT-Connect背后的原理。如上圖所示,當(dāng)開發(fā)者在本地運(yùn)行“Connect”命令后,首先會創(chuàng)建一個代理容器(shadow pod),這個代理容器會運(yùn)行“SSH Server”和“DNS Server”。當(dāng)代理容器啟動成功之后,就可以通過“port-forward”將代理容器的22端口轉(zhuǎn)映射到本地,如2222端口。此時,本地服務(wù)就可以通過本地的2222端口建立與集群內(nèi)部的連接。

ia_3300000010.jpg

“Exchange”和與“Connect”命令背后的原理類似,我們也會先創(chuàng)建一個代理容器,并通過“port-forward”將代理容器的端口映射到本地。然后根據(jù)Exchange的目標(biāo)服務(wù),判斷將代理容器的哪一個端口的請求全部轉(zhuǎn)發(fā)到本地的特定端口。

“Mesh”與“Exchange”的最大的差異在于“Exchange”會將原應(yīng)用的副本數(shù)直接降到0,會將集群內(nèi)所有對原應(yīng)用的流量全部轉(zhuǎn)發(fā)到本地。而“Mesh”則是在保持原有應(yīng)用Pod不變的前提下,創(chuàng)建一個新的代理容器并且繼承原應(yīng)用的所有標(biāo)簽,還會增加一個隨機(jī)的version標(biāo)簽。這時我們就可以通過Istio規(guī)則,精確控制流量。

ia_3300000011.jpg

如前文所述,通過KT-Connect我們可以實(shí)現(xiàn)從本地到集群的雙向互通。我們可以看到這樣一個有趣的場景:小黑A可以通過“Mesh”命令把本地服務(wù)加入到測試環(huán)境里,并且可以讓集群中一部分特定的流量轉(zhuǎn)發(fā)到本地,這樣他可以與集群中的其它服務(wù)進(jìn)行聯(lián)調(diào)。小黑B通過“Connect”命令連接到集群,直接在本地進(jìn)行測試。在某些情況下,小黑B需要依賴的服務(wù)剛好是小黑A正在開發(fā)的版本,小黑B只要按照Istio的流量規(guī)則設(shè)置可以調(diào)用小黑A服務(wù)的值,就可以跟小黑A的服務(wù)進(jìn)行聯(lián)調(diào)。對于小黑C,他既需要調(diào)用集群中的服務(wù),又需要集群中的服務(wù)回調(diào)到本地,所以他在本地既運(yùn)營了“Connect”又運(yùn)行了“Mesh”。

上文描述的其實(shí)是一種理想情況,需要建立在我們的測試環(huán)境是一種穩(wěn)定狀態(tài)的基礎(chǔ)之上。但在現(xiàn)實(shí)情況下,由于頻繁的代碼變更測試環(huán)境往往處于一種不太穩(wěn)定的狀態(tài)。接下來我們會介紹如何使用云原生測試環(huán)境工具箱中的kt-virtual-environment打造穩(wěn)定的測試環(huán)境,讓開發(fā)者可以更好地進(jìn)行協(xié)同研發(fā)工作。

共用測試環(huán)境相互干擾問題及常見解決方案

在一個中大規(guī)模研發(fā)團(tuán)隊(duì)負(fù)責(zé)的項(xiàng)目中,往往一個系統(tǒng)里包含許多(微)服務(wù),而且服務(wù)之間存在鏈?zhǔn)揭蕾?,難以獨(dú)立啟動運(yùn)行。這時就很容易出現(xiàn)“共用測試環(huán)境相互干擾”的問題,比如一個開發(fā)者重新部署、重啟測試環(huán)境時,可能會打斷所有正在測試的開發(fā)者;一個開發(fā)者提交了有BUG的代碼,所有開發(fā)者都可能受影響;一個開發(fā)者為了排查問題,單步調(diào)試測試環(huán)境服務(wù)時,所有開發(fā)者測試請求會被攔截。

如何來解決這個問題呢?以往的思路是準(zhǔn)備多套測試環(huán)境。雖然這種方式可以暫時緩解開發(fā)過程中的相互影響,但是這會帶來額外的資源分配和管理問題,特別是當(dāng)沒有那么多并行開發(fā)時會產(chǎn)生非常嚴(yán)重的資源浪費(fèi)。

于是出現(xiàn)了一種“改進(jìn)”方法,企業(yè)通過用helm或自制工具自動化地快速創(chuàng)建一套環(huán)境,用完即刪。該方法在一定程度上解決閑置資源回收的問題,但是也沒有那么“完美”。在實(shí)際操作過程中,環(huán)境的創(chuàng)建其實(shí)并沒有那么“快速”,往往需要等待幾分鐘甚至幾十分鐘的時間。而且如果為每個子項(xiàng)目的成員分別拉一套環(huán)境,資源浪費(fèi)依然嚴(yán)重。

在多人協(xié)同場景下,如何做到測試環(huán)境不相互干擾又不產(chǎn)生極大的資源浪費(fèi)呢?在阿里巴巴內(nèi)部主要通過“項(xiàng)目環(huán)境”的方案解決。

“項(xiàng)目環(huán)境”的本質(zhì)是基于路由隔離實(shí)現(xiàn)的一個“虛擬環(huán)境”。我們通過一個實(shí)例來簡單了解一下。

ia_3300000012.jpg

如上圖中藍(lán)色部分所示,由服務(wù)A、服務(wù)B、服務(wù)C、服務(wù)D組成一個完整的測試環(huán)境,我們稱為“公共基礎(chǔ)環(huán)境”(也稱默認(rèn)環(huán)境)。當(dāng)某位開發(fā)者需要進(jìn)行項(xiàng)目開發(fā)的時候,他不需要把應(yīng)用或服務(wù)部署到公共基礎(chǔ)環(huán)境中,而是單拉出來一部分資源(服務(wù)C和服務(wù)D)并復(fù)用部分公共基礎(chǔ)環(huán)境資源(服務(wù)A和服務(wù)B)形成“項(xiàng)目環(huán)境”。這樣操作的好處是,第一不會占用大量的開發(fā)資源;第二,不會影響公共基礎(chǔ)環(huán)境的穩(wěn)定性。

我們主要通過打“環(huán)境標(biāo)”的形式形成獨(dú)立的“隔離域”,比如[dev]代表公共基礎(chǔ)服務(wù)實(shí)例的標(biāo)簽值,[dev.proj]代表項(xiàng)目環(huán)境的服務(wù)實(shí)例。同一個環(huán)境標(biāo)形成一個獨(dú)立的“隔離域”,這是基于路由規(guī)則實(shí)現(xiàn)的。如果服務(wù)請求是來自一個有環(huán)境標(biāo)的服務(wù)實(shí)例,它的服務(wù)請求會優(yōu)先尋找跟它具有相同環(huán)境標(biāo)的實(shí)例,如果沒有,會尋找它上一級的環(huán)境標(biāo),這叫做“路由兜底”。比如上圖中服務(wù)請求來自帶有[dev.proj]環(huán)境標(biāo)的實(shí)例C,需要調(diào)用服務(wù)B,但是發(fā)現(xiàn)沒有帶環(huán)境標(biāo)[dev.proj]的服務(wù)B,于是尋找?guī)в猩弦患壄h(huán)境標(biāo)[dev]的服務(wù)B。

ia_3300000013.jpg

我們還可以將本地開發(fā)機(jī)加入項(xiàng)目環(huán)境。比如開發(fā)者“小黑”在本地啟動了一個服務(wù)實(shí)例C,他給這個服務(wù)實(shí)例打的環(huán)境標(biāo)是[dev.proj.local],通過前面介紹路由規(guī)則我們了解到帶環(huán)境標(biāo)的服務(wù)發(fā)出的請求會優(yōu)先尋找?guī)嗤h(huán)境標(biāo)的服務(wù),如果找不到則會尋找?guī)в猩弦患壄h(huán)境標(biāo)的服務(wù),于是服務(wù)C[dev.proj.local]、服務(wù)D[dev.proj]和公共基礎(chǔ)環(huán)境中服務(wù)A[dev]、服務(wù)B[dev]就組成了一個新的的“項(xiàng)目環(huán)境”(圖中紅色部分)。

ia_3300000014.jpg

這時“小黑”的同事也加入了項(xiàng)目,他在本地啟動了一個服務(wù)A,如果他沒有對這個服務(wù)打“環(huán)境標(biāo)”的話,他會默認(rèn)使用“公共基礎(chǔ)環(huán)境”進(jìn)行測試。這時小黑在他自己的“項(xiàng)目環(huán)境”中的任何調(diào)試都不會影響到小黑的同事,反之亦然。

ia_3300000015.jpg

后來小黑的同事和小黑加入了同一個子項(xiàng)目,他們之間需要“聯(lián)調(diào)”。這時,小黑的同事只要給他本地的服務(wù)打上一個和小黑的“項(xiàng)目環(huán)境”相同的環(huán)境標(biāo)即可,如上圖紅色部分。

總結(jié)一下前面介紹的概念:“隔離域”是由路由規(guī)則形成的虛擬邊界;每個“環(huán)境標(biāo)”都會形成一個獨(dú)立的“隔離域”;“隔離域”之間可以存在部分或完全重合;“隔離域”的成員會隨集群中服務(wù)實(shí)例所帶“環(huán)境標(biāo)”動態(tài)變化。

如何使用kt-virtual-environment打造項(xiàng)目環(huán)境

kt-virtual-environment是一種基于Service Mesh的微服務(wù)環(huán)境復(fù)用工具,源于阿里巴巴內(nèi)部的項(xiàng)目環(huán)境實(shí)踐。通過Pod上的虛擬環(huán)境標(biāo)簽,kt-virtual-environment能夠自動將測試環(huán)境網(wǎng)絡(luò)動態(tài)隔離成多個虛擬隔離域,同時以簡單規(guī)則在隔離域間局部復(fù)用Pod實(shí)例,從而達(dá)到只需很少資源成本即可創(chuàng)建大量不同微服務(wù)版本組合的獨(dú)立測試環(huán)境的目的。

ia_3300000016.jpg

下面我們來了解一下如何使用kt-virtual-environment打造項(xiàng)目環(huán)境。通過前面的介紹,我們知道相同的“環(huán)境標(biāo)”會形成一個獨(dú)立的“隔離域”。所以首先我們需要為服務(wù)實(shí)例打上環(huán)境標(biāo),在kt-virtual-environment中是通過為為pod(或容器)添加約定的Label的方式實(shí)現(xiàn)的。在服務(wù)調(diào)用過程中,需要為應(yīng)用程序添加一些邏輯,才能讓“環(huán)境標(biāo)”順利在上下文之間傳遞,這個過程類似SkyWalking、Zipkin等鏈路追蹤工具的SDK端所做的事情,讓“環(huán)境標(biāo)”通過HTTP頭在請求鏈路上一直保持傳遞。第三步,我們需要在集群中配置Virtual Environment類型的資源實(shí)例,詳細(xì)配置的結(jié)構(gòu)如上圖所示。

ia_3300000017.jpg

kt-virtual-environment實(shí)現(xiàn)的基本原理是:觀察并持續(xù)監(jiān)聽環(huán)境中的所有服務(wù)和開發(fā)資源,動態(tài)生成Service Mesh控制面規(guī)則,實(shí)現(xiàn)核心隔離邏輯。當(dāng)前kt-virtual-environment僅支持基于Istio的規(guī)則,未來會增加基于其它控制面的Service Mesh規(guī)則的實(shí)現(xiàn)。

阿里巴巴使用項(xiàng)目環(huán)境的最佳實(shí)踐

ia_3300000018.jpg

“項(xiàng)目環(huán)境”在阿里巴巴內(nèi)部已近發(fā)展多年,下面我將一些優(yōu)秀的實(shí)踐分享給大家。理論上,“環(huán)境標(biāo)”的層級可以無限多,但是我們的經(jīng)驗(yàn)是最好不要超過三級。因?yàn)槿龑拥摹碍h(huán)境標(biāo)”基本上可以滿足95%以上的研發(fā)場景。

以三層環(huán)境標(biāo)實(shí)現(xiàn)的項(xiàng)目環(huán)境舉例。第一層一般只有一個環(huán)境標(biāo),比如[dev],這是對應(yīng)默認(rèn)隔離域(公共環(huán)境)使用的環(huán)境標(biāo),這樣做會讓整個路由規(guī)則比較簡單,大家不用猜測“路由兜底”最后會“兜”到哪里去。這個頂級的[dev]環(huán)境標(biāo)對應(yīng)的測試環(huán)境是不需要開發(fā)者自己去部署的,一般是通過“流水線”等自動化工具部署的穩(wěn)定版本。對于某個子項(xiàng)目,我們可以基于頂級環(huán)境標(biāo)建立一個二級環(huán)境標(biāo),如[dev.proj1],這樣會形成這個子項(xiàng)目的隔離域(項(xiàng)目環(huán)境)。在這個隔離域中,只需要開發(fā)者自己部署需要改動的服務(wù)實(shí)例即可,其它不需要改動的服務(wù)實(shí)例可以復(fù)用公共環(huán)境中實(shí)例。有的時候,某位開發(fā)者可能要對某服務(wù)進(jìn)行比較大的改動或者他不希望這個服務(wù)被其它同事訪問到,他可以基于“項(xiàng)目環(huán)境”再創(chuàng)建一個“個人環(huán)境”。在這個個人環(huán)境中,他既可以調(diào)用子項(xiàng)目中的服務(wù),也可以調(diào)試本地開發(fā)的新的服務(wù)版本,并且不會影響到其他開發(fā)者。以上,是我們比較推薦的項(xiàng)目環(huán)境的用法。

總結(jié):

云原生測試環(huán)境工具箱共包含兩款獨(dú)立的工具:kt-connect和kt-virtual-environment。kt-connect是一款本地工具,主要是幫助開發(fā)者打通本地和集群網(wǎng)絡(luò),實(shí)現(xiàn)本地加入隔離域。kt-virtual-environment是一種基于Service Mesh的微服務(wù)環(huán)境復(fù)用工具,通過觀察并持續(xù)監(jiān)聽環(huán)境中的所有服務(wù)和開發(fā)資源,動態(tài)生成Service Mesh控制面規(guī)則,實(shí)現(xiàn)核心隔離邏輯。只需要一次性部署,開發(fā)者不會頻繁使用到。目前兩款工具已經(jīng)開源,大家可以進(jìn)入Github社區(qū)進(jìn)行下載使用。

ia_3300000019.jpg

立即登錄,閱讀全文
原文鏈接:點(diǎn)擊前往 >
版權(quán)說明:本文內(nèi)容來自于云棲號,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個人觀點(diǎn),不代表快出海對觀點(diǎn)贊同或支持。如有侵權(quán),請聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
阿里云助力《誅仙世界》端游正式開服!
阿里云助力《誅仙世界》端游正式開服!
近?,完美世界游戲歷時多年打造的新國?仙俠MMORPG端游《誅仙世界》在阿?云上正式開服。
阿里云
云服務(wù)
2024-12-29
一文詳解阿里云AI大基建
一文詳解阿里云AI大基建
面向AI時代,阿里云基礎(chǔ)設(shè)施是如何創(chuàng)新與發(fā)展的?計(jì)算、網(wǎng)絡(luò)、存儲、服務(wù)器、集群、可觀測等,阿里云全新升級的AI Infra到底有哪些重磅更新?
阿里云
云服務(wù)
2024-11-02
AI時代云安全新范式,阿里云安全能力全線升級!
AI時代云安全新范式,阿里云安全能力全線升級!
AI時代,云安全面臨著新的挑戰(zhàn),不僅要持續(xù)面對以往的傳統(tǒng)問題,更需要全新理念落地于產(chǎn)品設(shè)計(jì)、技術(shù)演進(jìn)、架構(gòu)設(shè)計(jì),才能實(shí)現(xiàn)效果、性能、和成本的最優(yōu)解。
AI
阿里云
云服務(wù)
2024-09-27
連續(xù)四年!阿里云領(lǐng)跑中國公有云大數(shù)據(jù)平臺
連續(xù)四年!阿里云領(lǐng)跑中國公有云大數(shù)據(jù)平臺
近日,國際數(shù)據(jù)公司(IDC)發(fā)布《中國大數(shù)據(jù)平臺市場份額,2023:數(shù)智融合時代的真正到來》報告——2023年中國大數(shù)據(jù)平臺公有云服務(wù)市場規(guī)模達(dá)72.2億元人民幣,其中阿里巴巴市場份額保持領(lǐng)先,占比達(dá)40.2%,連續(xù)四年排名第一。
阿里云
云服務(wù)
2024-09-18
優(yōu)質(zhì)服務(wù)商推薦
更多