摘要:應當存在一類特殊的集成測試容器。集成測試容器應當運行在全部微服務都已經(jīng)部署到位的運營環(huán)境之下,包括測試分段或者生產(chǎn)環(huán)境。因此,我們將所有依賴性都限制在集成測試容器當中。
當我們構(gòu)建好Docker鏡像并利用多套容器共同組合成應用程序,建立起持續(xù)交付通道,了解了如何將新創(chuàng)建的鏡像納入到生產(chǎn)或者測試環(huán)境當中之后,新的問題來了——我們該如何測試自己的Docker容器?
測試的策略多種多樣,反映了各種各樣的測試性格:天真型,懶人省事型,超前理想主義型,完美主義處女座型……那么你是哪一型?
下面我們就對其各自的方案利弊進行逐一分析。
“天真”型方案
大多數(shù)人會將此作為默認方案。其利用CI服務器實現(xiàn)任務執(zhí)行。在這項方案中,開發(fā)人員利用Docker作為軟件包管理器,其實際效果優(yōu)于jar/rpm/deb方案。CI服務器對應用程序代碼進行編譯,而后執(zhí)行測試(包括單元、服務及功能等)。Docker中的build可復用以生成新的鏡像,由此生成的鏡像不僅包含應用程序的“二進制代碼”,同時亦擁有運行時所必需的依賴性及配置。
不過為了實現(xiàn)應用程序的可移植性,我們需要放棄開發(fā)與測試的可移植能力。在這種情況下,我們無法在CI之外重新建立同樣的開發(fā)與測試環(huán)境。為了創(chuàng)始這樣一套新的測試環(huán)境,我們需要設置測試工具(正確版本與插件)、配置運行時與操作系統(tǒng)設定,同時獲取相同版本的測試腳本與測試數(shù)據(jù)。
為了解決上述難題,我們需要考慮以下方案。
應用&測試容器方案
現(xiàn)在我們嘗試創(chuàng)建單一捆綁包,其中應用程序“二進制代碼”中包含全部必需的軟件包、測試工具(包括對應版本)、測試工具插件、測試腳本以及其它各類測試環(huán)境元素。
這套方案的優(yōu)勢包括:
測試環(huán)境自身擁有可重復性——我們能夠在CI、開發(fā)、分段或者生產(chǎn)環(huán)境當中使用完全相同的測試工具實現(xiàn)完全相同的測試效果。
我們能夠立足特定時間點捕捉測試腳本,所以可將其復用于任意環(huán)境。
我們不需要對測試工具進行二次設置與配置——其已經(jīng)成為鏡像中的組成部分。
但這種方式也存在著顯著弊端:
鏡像體積直線增長——這是因為其中包含有測試工具、必要軟件包、測試腳本甚至是測試數(shù)據(jù)。
特定測試配置可能對鏡像運行時環(huán)境造成污染,甚至引入不必要的依賴性(集成測試中需要用到)。
我們還需要考慮如何處理測試結(jié)果與記錄日志;如何將其導出以及向哪里導出。
通過以下經(jīng)過簡化的 Dockerfile,我們可以了解上述方案的整個流程。
FROM "":" " WORKDIR " " # install packages required to run app and tests RUN apt-get update && apt-get install -y " and " # add app runtime and required packages " and " # add testing tools and required packages && rm -rf /var/lib/apt/lists/* # copy app files COPY app app COPY run.sh run.sh # copy test scripts COPY tests tests # copy "main" test command COPY test.sh test.sh # ... EXPOSE, RUN, ADD ... for app and test environment # main app command CMD [run.sh, " "] # it"s not possible to have multiple CMD commands, but this is the "main" test command # CMD [/test.sh, " "]
毫無疑問,應該有更好的容器內(nèi)測試方案可供選擇。
測試感知型容器方案
目前,Docker承諾以“Build -> Ship -> Run”這一簡單操作完成鏡像構(gòu)建、發(fā)布至注冊表并在其它位置運行等任務。不過恕我直言,其中還缺少了Test這一重要環(huán)節(jié)。正確且完整的流程應該是Build -> Test -> Ship -> Run。
下面讓我們看看能夠為Docker命令提供“測試友好”型語法與擴展的Dockerfile是如何建立而成的。當然,其中并不涉及真正的語法,只是我個人更偏好這樣表述。我定義出了自己的“理想”版本(真的只是理想版本,僅供大家借鑒其中的思想,小數(shù)注),大家應該能夠看出其中可用于實踐的指導思路。
ONTEST [INSTRUCTION]
首先定義一條特殊的ONTEST指令,其與現(xiàn)有ONBUILD指令非常相似。ONTEST指令會向鏡像添加一條觸發(fā)指令,其在隨后鏡像接受測試時自動執(zhí)行。任意build指令都可被注冊為觸發(fā)條件。
ONTEST指令可由一條新的docker test命令進行識別。
docker test [OPTIONS] IMAGE [COMMAND] [ARG...]
事實上,docker test命令的語法與docker run命令非常相似,二者只存在一項區(qū)別:前者會自動生成一套新的“可測試”鏡像,甚至為其提供
下面我們來看看經(jīng)過修改的Dockerfile——其中包含新的ONTEST指令。
FROM "":" " WORKDIR " " # install packages required to run app RUN apt-get update && apt-get install -y " and " # add app runtime and required packages && rm -rf /var/lib/apt/lists/* # install packages required to run tests ONTEST RUN apt-get update && apt-get install -y " and " # add testing tools and required packages && rm -rf /var/lib/apt/lists/* # copy app files COPY app app COPY run.sh run.sh # copy test scripts ONTEST COPY tests tests # copy "main" test command ONTEST COPY test.sh test.sh # auto-generated volume for test results # ONTEST VOLUME "/var/tests/results" # ... EXPOSE, RUN, ADD ... for app and test environment # main app command CMD [run.sh, " "] # main test command ONTEST CMD [/test.sh, " "]
如何實現(xiàn)“測試感知容器”
我們相信,Docker應該會將docker-test作為容器管理生命周期中的組成部分。當下我們都需要更為簡便的解決方案,因此我在這里提出一套接近于理想情況的實現(xiàn)辦法。
如之前所提到,Docker擁有ONBUILD這樣一條非常實用的指令。該指令允許我們在已經(jīng)成功的build之上觸發(fā)另一build指令。其基本思路是在運行docker-test命令的同時,使用ONBUILD指令。
以下為docker-test命令的執(zhí)行流程:
docker-test將在應用程序Dockerfile當中搜索ONBUILD指令,而后……
利用初始Dockerfile生成一條臨時的Dockerfile.test
執(zhí)行docker build -f Dockerfile.test [OPTIONS] PATH,其中包含受docker build命令支持的其它選項:-test將自動被添加至tag選項當中。
如果構(gòu)建成功,則執(zhí)行 docker run -v ./tests/results:/var/tests/results [OPTIONS] IMAGE:TAG-test [COMMAND] [ARG...]
移除Dockerfile.test文件
那么,為什么不創(chuàng)建一個無需配合ONBUILD指令的Dockerfile.test文件?
這是因為,為了測試正確的鏡像(及標簽),我們需要保證FROM始終在測試目標的image:tag中得到更新。
不過前面提到的方案仍然存在局限——其不適用于“onbuild”鏡像(即用于自動化構(gòu)建應用的鏡像),例如Maven:onbuild。
下面來看一條簡單的docker-test命令實現(xiàn)流程。其中強調(diào)了一大重要概念:docker-test命令應當能夠處理build與run命令選項,同時能夠妥善處理錯誤狀況。
#!/bin/bash image="app" tag="latest" echo "FROM ${image}:${tag}" > Dockerfile.test && docker build -t "${image}:${tag}-test" -f Dockerfile.test . && docker run -it --rm -v $(pwd)/tests/results:/var/tests/results "${image}:${tag}-test" && rm Dockerfile.test
讓我們把注意力集中在最值得關注的重要部分。
集成測試型容器方案
假設我們的應用程序由數(shù)十甚至數(shù)百項微服務構(gòu)建而成,同時假設我們已經(jīng)擁有一套自動化CI/CD通道,其中每項微服務都由CI進行構(gòu)建與測試,并在之后被部署到某種環(huán)境當中(例如測試、分段或者生產(chǎn)環(huán)境)。聽起來不錯,對吧?我們的CI會對各項微服務進行分別測試——運行單元與服務測試(或者API合同測試)。甚至有可能進行微集成測試——即將測試運行在特設的子系統(tǒng)之上(例如使用docker compose)。
但這又會帶來一些新問題:
實際集成測試或者長期運行測試該如何完成(例如性能與壓力測試)?
彈性測試該如何實現(xiàn)(例如‘混亂猴子’測試)?
如何實現(xiàn)安全掃描?
那些需要耗費較長時間且運行在完整操作系統(tǒng)之上的測試與掃描要如何完成?
應該有一種更好的辦法來替代這種直接將新的微服務版本交付至生產(chǎn)環(huán)境的作法,我們也需要更為密切的監(jiān)控手段。
應當存在一類特殊的集成測試容器。這些容器將僅包含測試工具與測試元素:測試腳本、測試數(shù)據(jù)、測試環(huán)境配置等等。為了簡化此類容器的編排與自動化流程,我們應當定義并遵循某些約定并使用元數(shù)據(jù)標簽(Dockerfile中的LABEL指令)。
集成測試標簽
test.type – 測試類型,負責定義integration; 可屬于 integration, performance, security, chaos 或者其它任意文本之一; 此標簽代表其屬于一套集成測試容器
test.results – 用于存放測試結(jié)果的VOLUME ; 默認位置為 /var/tests/results
test.XXX -任何其它相關元數(shù)據(jù),僅使用test.后綴名作為標簽名稱
集成測試容器
集成測試容器其實就是一種常規(guī)Docker容器,其中不包含任何應用程序邏輯及代碼。它的惟一用途就是創(chuàng)建可重復且可移植的測試流程。以下為建議納入集成測試容器的內(nèi)容:
測試工具 - Phantom.js, Selenium, Chakram, Gatling, …
測試工具運行時 - Node.js, JVM, Python, Ruby, …
測試管理配置 – 環(huán)境變量, 配置文件, 引導腳本, …
測試 -作為經(jīng)過編譯的軟件包或者腳本文件存在
測試數(shù)據(jù) – 任何用于測試的數(shù)據(jù)文件類型: json, csv, txt, xml, …
測試啟動腳本 -用于運行測試的部分“main”啟動腳本,僅負責創(chuàng)建test.sh并借此啟動該測試工具。
集成測試容器應當運行在全部微服務都已經(jīng)部署到位的運營環(huán)境之下,包括測試、分段或者生產(chǎn)環(huán)境。這些容器可與其它服務采取完全一致的部署方式。其利用同樣的網(wǎng)絡層,因此能夠訪問多項其它服務;使用選定的服務發(fā)現(xiàn)方法(通常為DNS)。在實際集成測試當中,我們必須對多項服務進行訪問——旨在模擬并驗證自身系統(tǒng)是否能夠在多種不同環(huán)境下正常運行。將集成測試納入應用服務容器不僅會增加容器自身體積,同時亦會在各服務之間帶來不必要的依賴性。因此,我們將所有依賴性都限制在集成測試容器當中。一旦測試(以及相關測試工具)被打包在該容器內(nèi),我們亦可在包括開發(fā)者設備在內(nèi)的任意環(huán)境下重復運行同樣的測試流程。大家還能夠?qū)崿F(xiàn)回滾,即根據(jù)需要運行任意集成測試容器版本。
文章來源:TERRA NULLIUS
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/26651.html
摘要:二緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項目來說,理論上來說是沒必要用太復雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。 Docker出現(xiàn)后,容器技術(shù)在互聯(lián)網(wǎng)領域得到了空前的普及,無論是大公司還是屌絲創(chuàng)業(yè)公司的碼農(nóng)基本上都會在各種技術(shù)社區(qū)或者各種演講會議上了解到過相關技術(shù),我們作為一家屌絲創(chuàng)業(yè)公司也不例外,去年對Docker做了一番了解,并在年前測試了一些方案,今天在這里總結(jié)一下遇到...
摘要:二緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項目來說,理論上來說是沒必要用太復雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。 Docker出現(xiàn)后,容器技術(shù)在互聯(lián)網(wǎng)領域得到了空前的普及,無論是大公司還是屌絲創(chuàng)業(yè)公司的碼農(nóng)基本上都會在各種技術(shù)社區(qū)或者各種演講會議上了解到過相關技術(shù),我們作為一家屌絲創(chuàng)業(yè)公司也不例外,去年對Docker做了一番了解,并在年前測試了一些方案,今天在這里總結(jié)一下遇到...
摘要:二緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項目來說,理論上來說是沒必要用太復雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。 Docker出現(xiàn)后,容器技術(shù)在互聯(lián)網(wǎng)領域得到了空前的普及,無論是大公司還是屌絲創(chuàng)業(yè)公司的碼農(nóng)基本上都會在各種技術(shù)社區(qū)或者各種演講會議上了解到過相關技術(shù),我們作為一家屌絲創(chuàng)業(yè)公司也不例外,去年對Docker做了一番了解,并在年前測試了一些方案,今天在這里總結(jié)一下遇到...
摘要:大家好今天我分享的主題與游戲行業(yè)相關,為大家介紹的是在騰訊游戲中的應用實踐。隨著技術(shù)的興起,我們開始調(diào)研在游戲容器化方面的應用。也就是說,將不同游戲業(yè)務部署到同一臺母機,采用綁定核的方式。在母機上架部署時,創(chuàng)建設備和設備并將它們進行關聯(lián)。 今天小數(shù)的推送內(nèi)容來自騰訊互娛高級工程師黃惠波,讓我們一起來看看吧~~~ 黃惠波,騰訊互娛高級工程師目前主要負責游戲計算資源容器化平臺的研發(fā)工作,包...
摘要:負責承載操作系統(tǒng)的分布式文件系統(tǒng)只需要使用必要的文件,而且事實上只需要下載并在本地緩存這部分必要數(shù)據(jù)。而第二項原則在于元數(shù)據(jù)即與文件存在相關的信息,而非文件內(nèi)容被優(yōu)先對待。這套鏡像隨后可進行任意分發(fā),并被用于啟動該項任務。 隨著Docker技術(shù)的日漸火熱,一些容器相關的問題也浮出水面。本文就容器數(shù)量激增后造成的分發(fā)效率低下問題進行了探討,并提出了一種新的解決方法。發(fā)現(xiàn)問題,解決問題,正...
閱讀 2677·2021-11-24 09:38
閱讀 1987·2019-08-30 15:53
閱讀 1248·2019-08-30 15:44
閱讀 3240·2019-08-30 14:10
閱讀 3591·2019-08-29 16:29
閱讀 1811·2019-08-29 16:23
閱讀 1108·2019-08-29 16:20
閱讀 1481·2019-08-29 11:13