在軟件研發過程中,“測試環境”是部署最頻繁、也是開發者使用最頻繁的一種運行環境,穩定而易用的測試環境能夠極大提高開發者的工作效率和幸福感。為更好的將阿里巴巴在測試環境管理方面的實踐和經驗跟廣大開發者分享,《雲效說碼》策劃了《阿里巴巴Kubernetes測試環境開源工具箱》系列直播視頻,由阿里巴巴技術專家林帆(金戟)和鄭雲龍(砧木) 來為大家講述。
本系列分享共有三節內容,本文整理自砧木的第二次分享《單人開發場景下的測試環境實踐》。
【以下為分享實錄,有刪節】
《阿里巴巴測試環境管理概述》要點回顧
在正式開始本次分享之前,我們首先回顧一下上一次分享中我的同事金戟分享的要點。在測試環境管理中,我們主要遇到兩個問題,第一個是本地與集群雙向互通的問題,在阿里巴巴集團內部主要通過基於CNI(Conteinre Network Interface)機制改造Kubernetes的IP邏輯實現的“扁平化的內網IP”這個方法來解決,這種方式更適合大型集團企業。第二個問題是多人協作開發時,路由的可訪問性控制問題,在阿里巴巴內部我們是通過“項目環境”與“隔離域”實現的。
程序員小黑的困擾:測試環境不穩定導致集成效率低下
本次分享,我們將把視角從阿里巴巴集團內部轉向外部開發者,特別是廣大開發者所在的中小團隊,聊聊他們如何解決前文中提到的“本地與集群雙向互通”的問題。
我們先來思考一個問題:在本地開發的時候,有哪些讓你感到痛苦的事情?
為了幫助大家更好回憶,我們假象了一位主人公——程序員小黑。小黑所在公司採用了微服務相關的技術實踐,公司的平臺根據業務情況被劃分為多個“服務”,小黑所在團隊負責的是其中單獨一個業務領域。小黑團隊會使用平臺中的一些公共服務,同時他們也會為平臺中的其它服務提供標準的API,方便其它服務調用數據。
為了降低整個平臺的運維成本,小黑公司使用了阿里雲提供的Kubernetes服務來搭建他們的測試環境及生產環境,通過雲效提供的項目協作“看板”管理項目的需求及迭代進度。同時雲效也提供了DevOps相關的能力支持,打通了從代碼開發到軟件發佈上線的端到端的過程。小黑公司基於這套DevOps體系,不斷的對產品進行迭代和優化。
相對於採用“DevOps”之前,小黑公司的研發效能已經得到極大提升,但近期小黑卻遇到了一些困擾。他發現,由於測試環境不穩定,讓他浪費了大量的時間在“集成”這件事情上。
其實,團隊中的每位成員都希望儘快完成本地開發的功能的驗證工作,目前情況下,小黑團隊成員只能先將代碼提交到代碼倉庫,然後通過流水線將代碼部署到測試環境,因此“代碼提交”會變得非常頻繁,也就意味著在大部分時間裡,你的測試環境會處於更新、發佈狀態中,整個測試環境的可用性就會變得非常差。甚至有的時候,因為個別成員在本地開發完成後,對代碼沒有進行充分驗證就進行了測試提交,導致整個測試環境“掛掉”。有時因為有緊急的需求需要快速上線,測試環境會被這些緊急變更獨佔。小黑只能在測試環境可用的短暫的時間裡儘可能地去驗證自己開發的功能,這就導致小黑最近情緒很低落。
小黑的困擾一:聯調其它服務。
其實小黑的需求很簡單,他希望在本地代碼開發完成之後,能夠儘可能快的跟其它服務進行聯調,來驗證他開發的功能是否OK,但是現在他唯一能依賴的就是那套“公共環境”。
在本地完成代碼開發後,如何高效的與其它服務進行聯調呢?經過分析發現,在本地進行聯調效率最高,使用公共環境進行測試成本最低,兩全其美的辦法就是,在本地直接訪問雲上集群的環境進行測試。對這個“命題作文”,開發者和企業有很多不同的選擇,除了在第一次分享中我同事介紹的方法外,我們還推出了一個更輕量的方式通過KT-Connect工具實現。
KT-Connect是阿里巴巴雲效團隊研發的面向Kubernetes的本地開發者輔助工具(已經開源),通過“Connect”命令可以實現一鍵連接雲上任意的Kubernetes集群。連接完成之後,可以快速建立本地到集群的VPN網絡,同時將Kubernetes集群的DNS解析能力整合到本地,開發者可以像在集群中一樣可以直接通過PodIP,ClusterIP以及DNS域名訪問到集群內的服務。
小黑的困擾二:其它服務調用我
在這個案例中,小黑既是服務的消費者,同時也會提供一些公共的API供其它服務調用。這時只打通本地到集群的服務,並不能完全解決小黑的問題,必須同時讓集群中的服務可以訪問本地的服務。
KT-Connect同樣可以幫助我們解決這個問題,這就需要使用“Exchange”和“Mesh”命令。
Exchange(交換)命令通過在集群內部署代理容器,替換集群內的原有應用,並將所有對代理容器的請求直接轉發到本地端口。這是一種“完全替換”,這就意味著在同一時間點,只有一位開發者可以將他本地的服務加入到集群中。為了解決這個問題,KT-Connect提供了第三個命令——Mesh(混合)。當我們在本地運營“Mesh”命令後,我們同樣會把本地服務加入到集群裡面,但是會保持原有的目標服務狀態不變,並且本地服務會繼承目標服務中所有的標籤。依照K8S本身服務發現的原理,請求流量會被隨機地轉發到原有服務或本地的服務。同時配合Istio的流量規則,就可以讓所有正常流量依然保持對原應用的訪問,而只對一些有特殊標記的的請求轉發到本地。從而可以實現在一套公用測試環境的基礎上各自獨立的完成本地的集成聯調。
KT-Connect帶來高效的測試體驗
如前文所述,通過KT-Connect我們可以實現從本地到集群的雙向互通。在團隊裡,其實還有很多“小黑”,我們可以看到這樣一個場景:小黑A可以通過“Mesh”命令把本地服務加入到測試環境裡,並且可以讓集群中一部分特定的流量轉發到本地,這樣他可以與集群中的其它服務進行聯調。小黑B通過“Connect”命令連接到集群,直接在本地進行測試。在某些情況下,小黑B需要依賴的服務剛好是小黑A正在開發的版本,小黑B只要按照Istio的流量規則設置可以調用小黑A服務的值,就可以跟小黑A的服務進行聯調。對於小黑C,他既需要調用集群中的服務,又需要集群中的服務回調到本地,所以他在本地既運營了 “Connect”又運行了“Mesh”。如上所示,小黑團隊中的所有成員的測試活動都是建立在一套公共環境的基礎之上,但是彼此又都有一個相對獨立的測試環境,具有很好的可用性。
KT-Connect背後的原理
KT-Connect背後有什麼黑科技嗎?答案是:沒有。我們只是綜合利用了兩個大家在日常工作中都會用到的能力,通過Kubectl的端口轉發可以實現將集群中服務的端口映射到本地,通過SSH協議建立本地與集群之間的隧道。
以“Connect”命令為例,瞭解一下KT-Connect背後的原理。如上圖所示,當開發者在本地運行“Connect”命令後,首先會創建一個shadow pod實例,這個實例會運行“SSH Server”和“DNS Server”,當實例創建成功之後,就可以通過“port-forward”將代理容器的22端口轉映射到本地,如2222端口。此時,就可以通過本地的2222端口建立與集群內部的連接。
“Exchange”和與“Connect”命令背後的原理類似,我們也會先創建一個代理容器,並通過“port-forward”將代理容器的端口映射到本地。然後根據Exchange的目標服務,判斷將代理容器的哪一個端口的請求全部轉發到本地的特定端口。
“Mesh”與“Exchange”的最大的差異在於“Exhange”會將原應用的Replicas(副本)直接降到0,會將集群內所有對原應用的流量全部轉發到本地。而 “Mesh”則是在保持原有應用Pod不變的前提下,創建一個新的代理容器並且繼承原應用的所有標籤,並會增加一個隨機的version標籤。配合Istio的流量規則,可以讓所有正常流量依然保持對原應用的訪問,而只對一些有特殊標記的的請求轉發到本地。從而可以實現在一套公用測試環境的基礎上各自獨立的完成本地的集成聯調。
最後用《持續交付》中的一句話來總結今天的分享:集成通常是一個非常痛苦的過程。那麼就應該在每次提交代碼後就進行集成,而且應該從項目一開始就這麼做。其實句話還可以做一個調整,我們提倡在代碼提交之“前”就進行驗證。
非常感謝大家的聆聽,歡迎大家加入雲效開發者交流群和KT-Connect工具用戶群與我們交流。
【下期預告】
【直播日期】5月6日 16:00
【直播主題】多人協作場景下的測試環境實踐
【直播講師】鄭雲龍 阿里巴巴技術專家
【觀看方式】雲效開發者交流群直播(釘釘群號:群號:23362009)
【關於雲效】
雲效,企業級一站式DevOps平臺,源於阿里巴巴先進的研發理念和工程實踐,致力於成為數字企業的研發效能引擎!雲效提供從“需求 ->開發->測試->發佈->運維->運營”端到端的在線協同服務和研發工具,通過人工智能、雲原生技術的應用助力開發者提升研發效能,持續交付有效價值。