1. 程式人生 > >基於 Docker 快速部署多需求 Spark 自動化測試環境

基於 Docker 快速部署多需求 Spark 自動化測試環境

引言

在進行資料分析時,Spark 越來越廣泛的被使用。在測試需求越來越多、測試用例數量越來越大的情況下,能夠根據需求快速自動化部署 Spark 環境、快速完成所有測試越來越重要。

本文基於 Docker、Jenkins、Apache Ant、Apache Tomcat、Git、Shell 等技術或工具,根據使用者對 Spark 版本、Scala 版本、JDK 版本、測試範圍、測試版本等需求的不同,快速完成 Spark Cluster 環境以及相應的 Client 端測試環境的部署,進而實現快速自動化測試、結果呈報,從而提高開發測試效率。

Docker 等相關技術和工具介紹

Docker 介紹

Docker 是世界領先的開源應用容器引擎,提供了一個可供開發者打包其應用的可移植容器。開發者可以使用 Docker 來消除合作編碼時所出現的"我的機器"問題,運營商可以使用 Docker 來執行和管理不同容器中的應用,企業可以使用 Docker 更加快速安全的建立敏捷軟體交付管道。Docker 主要包括四部分:Docker Client、Docker Image、Docker Daemon、Docker Container。

Dockerfile 是為了快速構建 Docker Image 設計的,是一個包含了可用來建立映象命令的指令碼。當執行 docker build 命令時,Docker 可以通過從 Dockerfile 中自動讀取指令來建立映象。

Docker Compose 是一個用來定義和執行多容器複雜應用的工具。你可以使用一個 YAML 檔案來配置你的應用和服務,然後僅使用一條命令就可以啟動已配置的所有服務。

本系統中我們使用 Docker 來快速部署不同 Spark 版本、Scala 版本、JDK 版本的 Spark Cluster Server 和 Test 客戶端,通過 Docker Compose 啟動所需要的服務。

Spark 介紹

Spark 是一種與 Hadoop 相似的專門為大資料處理設計的開源叢集計算環境,使用 Scala 語言實現,以通用、易用為目標。Spark 的中間輸出結果可以儲存在記憶體中,不必重新讀寫 HDFS,從而使其具有 Hadoop MapReduce 所沒有的優點,更適用於資料探勘與機器學習等演算法。

本系統中我們將不同版本的 Spark 部署在 Docker 中,通過 Dockerfile 控制 Spark 的版本選擇,從而快速部署不同版本 Spark Cluster Server。

Jenkins 介紹

Jenkins 是一種開源的持續整合工具,提供一個開放易用的平臺用於監控持續重複工作,使得我們可以進行持續的軟體版本釋出和測試。

本系統中我們使用 Jenkins 建立 job 來控制測試的啟動與停止,也可以進行週期性任務。

Git 介紹

Git 是一個免費開源的分散式版本控制系統,可以高效地處理各種大小專案。Git 易於學習,效能高效,在廉價本地分支、方便的中轉區、多工作流等方面都超越了傳統的 SCM 工具,如 Subversion,Perforce,CVS,ClearCase 等。

本系統中使用 Git 進行程式碼的維護及實時更新。

Apache Ant 介紹

Apache Ant 是一種用於在 Java 環境下進行軟體開發的自動化工具,可以進行編譯、測試、部署等步驟,其構建檔案預設名為 build.xml,Ant 具有很好的跨平臺性且操作簡單。

本系統中我們使用 Ant 進行程式碼的編譯、測試以及測試報告的生成。

Apache Tomcat 介紹

Apache Tomcat 是一個開源的輕量級    Web應用軟體容器,可以用來響應 HTML 頁面的訪問請求,在中小型系統和併發使用者訪問場景中被廣泛使用。

本系統中我們使用 Tomcat 來展現測試報告(即測試結果),使得多使用者可以併發訪問測試報告。

Shell 介紹

Shell 指令碼是在 Linux/Unix 系統中使用的一種類似於 Windows/Dos 批處理的指令碼,功能與.bat 類似。Shell 是一種命令語言,可以互動式的執行使用者命令,將各類命令依據邏輯關係放入檔案中可以一次性執行,是Linux 系統下廣泛使用的一種指令碼。

本文中我們使用的系統是支援 Docker 的 Linux Ubuntu 14.04,依靠 Shell 指令碼將各個步驟聯絡起來組成一個完整的流程。

本文主要從自動化的系統整體構架以及環境部署流程方面進行介紹,扼其重點,以求給讀者提供一個部署此類環境或系統的操作思路和流程,對於特別細節、特殊或者過於通用的部分不做詳解,如一些軟體的安裝教程在網路上隨處可見,本文不再贅述。下面章節首先介紹整個系統構架,然後對系統構架中各個部分進行具體介紹,最後進行總結。

環境部署測試整體架構

本章主要介紹自動化測試系統的整體框架和流程,如圖 1 所示。我們通過在 Jenkins Server 上建立 Job 作為整個系統的測試入口,Jenkins 發起測試請求之後,接下來會進行環境部署(即圖中 Deploy 階段)和測試(即圖中 Test 階段)。環境部署包括通過 Docker 部署 Spark Cluster 和 Test Client,即測試所需要的伺服器端和客戶端。環境部署完畢後便可進行測試,從指定地方獲取測試所需要的 Build 和 Code,Code 可以通過 Git 在本機上維護更新,通過對程式碼進行測試所必須的一些配置,然後便可進行編譯、測試,測試執行完畢後對所生成的 xml 檔案進行生成報告(HTML 檔案生成),此處編譯、測試、report 生成均由 Ant 實現,所生成的 report 展示由 Tomcat 實現,最後通過 Linux 系統的郵件功能給指定郵箱傳送郵件完成整個測試流程。

圖 1. 自動化測試系統整體架構

Jenkins 任務

測試請求由 Jenkins 發起,安裝 Jenkins 並新建 Remote SSH 任務後,在 Script 執行視窗指定配置資訊,如圖 2 所示,包括 build_num、scope、sparkVersion、javaVersion、model,分別表示要進行測試的 build 版本(以 jar 包的形式存在),測試的範圍(Regression、Smoke、MiniSmoke 所定義 case 的範圍依次減小),Spark 版本(如 1.6.0、1.6.2、2.0.1、2.1.1 等,scala 版本由 spark 決定),Java 版本(如 openjdk8、ibmjdk8 等),模組(程式碼中所包含的要測試的模組)。這些配置資訊通過位於遠端機器上的 Shell 指令碼 getPropsFromJenkins.sh 下發到機器上的配置檔案中以便進行後續部署和測試流程。機器上的 buildScope.props 和 model.props 檔案用於儲存從 Jenkins 上獲取的資訊,後續所有需要這些資訊的操作均從這兩個檔案中讀取。需要特別說明的是 model 的各模組間逗號表示序列執行,分號表示並行執行,序列只需要啟動一個 Client 端即可,並行需要啟動多個 Client 端併發執行,這部分將在後續章節具體介紹。

圖 2. Jenkins 任務配置

Spark Cluster

Deploy 階段將根據 Jenkins 下發的配置資訊進行 Docker Spark Cluster 和 Client 的部署。

用於建立 Docker Spark Cluster 映象及啟動 Container 的指令碼很多,程式碼內容也過於複雜,本節難以一一完全介紹,依舊依據之前約定對重點部分進行介紹,以為讀者提供思路,具體細節可通過網路或者參考資料進一步深入研究。

每個版本的 Spark Docker 指令碼我們都放在一個獨立資料夾中,按照"spark-$spark_version-$java_version"的方式命名。以 spark-2.1.1-openjdk-8 為例,該資料夾結構如圖 3 所示,資料夾中所含 xml 格式檔案與實際安裝的 Spark 環境對應檔案類似,只是在 Docker 中我們使用 namenode 作為 container 的名字,core-site.xml 中要使用"hdfs://namenode:9000"替代實際環境中的"fs.default.name"。yarn-site.xml 中可以使用"yarn.nodemanager.resource.memory-mb"對 YARN 可使用的實體記憶體總量進行控制,預設 8192M,本系統我們為了並行兩個 Client 端同時測試設定為 65536M。

圖 3. spark-2.1.1-openjdk-8 資料夾結構

yarn-cluster 資料夾下的 Dockerfile 檔案是整個 cluster 的核心,用於建立 Spark Cluster 映象,內容主要包括配置 SSH 無密碼訪問、安裝 Java 並配置環境變數、下載安裝 Hadoop、載入 xml 檔案(core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml)、下載安裝 Spark、開放 Spark 執行所需埠等。如圖 4 所示為 Dockerfile 部分內容。

圖 4. Dockerfile 片段

bootstrap.sh 檔案主要用於在啟動 container 時自動啟動對應的 Spark 程序,如 start-dfs.sh、start-yarn.sh。其主要內容如圖 5 所示。

圖 5. bootstrap.sh 片段

我們使用 docker-compose 啟動 container 來保證整個 Spark Cluster 工作為一個整體,其主要使用檔案為 docker-compose.yml,如圖 6 所示。圖中還可以新增其他節點,本處為了簡化只使用 namenode 一個節點。

圖 6. docker-compose.yml 片段

Shell 指令碼建立 Spark Cluster 映象以及啟動 container 的命令如圖 7 所示,$spark_version 和$java_version 來決定切換到對應的 Spark 資料夾進行某個版本的建立,使用"docker build –t spark-2.1.1 ."命令建立 spark-2.1.1 的映象,執行"docker-compose up -d"用於在後臺啟動 spark-2.1.1 的 container。

圖 7. Spark Cluster 映象和啟動指令碼

Test Client

Client 端只需要啟動一個系統為 Linux、帶有所需軟體的 Container,所以與 Server 端相比 Client 端的 Docker 指令碼要簡單的多,只需要一個 Dockerfile 檔案用於建立 Client 映象即可,針對各種 Spark 版本的 Dockerfile 檔案按照"dockerfile-$spark_version-$java_version"的方式命名存放,執行時根據 Spark 版本資訊將對應的檔案拷貝成 dockerfile 的檔案來建立映象,檔案內容包括安裝 JDK、Scala、Spark、Ant 等。此處仍然以 Spark-2.1.1 為例,如圖 8 所示,在此指令碼中我們下載安裝了 scala-2.11.8、spark-2.1.1-bin-hadoop2.7 以及 Ant,並且配置了部分所需要的環境變數。

圖 8. Client Dockerfile 指令碼

Client 端映象的建立命令為"docker build -t client:v1 .",為了使得 Client 端和 Server 端的通訊更加通暢可以通過在上節 docker-compose.yml 中加入 Client 。如圖 9 所示,client1 表示我們只啟動一個 Client 端,沒有並行。如果需要啟動兩個 Client 端並行,在指令碼後繼續新增 client2 對應程式碼即可,與 client1 類似,client 數目的控制由 shell 指令碼通過 model 資訊確定。

圖 9. 新增 client 的 docker-compose.yml

在 Spark Cluster 和 Client 映象建立完成後,通過"docker-compose up -d"啟動對應的 Container,Container 執行情況如圖 10 所示。

圖 10. namenode 和 client container

Test

環境部署完畢後接下來就是要利用程式碼進行實際的測試,即 Test 階段。

Test Configuration 主要是利用 Jenkins 上指定的配置資訊對程式碼進行特定的配置,比如通過 wget 命令從遠端下載 Jenkins 上所指定的 build 版本,在此 build 上對程式碼進行編譯等。本機上通過 Git 維護一套程式碼,並且進行實時更新以獲取最新程式碼。如上節圖 10 所示 Client 啟動時已通過 volumes 命令將本機的 dockerShare 資料夾共享進 Client 的 docker container 內部,以便於在 docker 內部進行編譯測試。

Test 和 Report 為測試的主題階段,依據程式碼進行編譯測試和報告生成,這一階段是通過 Apache Ant 實現的,我們先來看一下 Ant 的構建檔案 build.xml。build.xml 的內容主要包括以下幾部分:程式碼編譯所依賴的 jar 包、編譯命令、測試命令、建立 report 命令。

如圖 11 所示,"build"指定了編譯依賴於"clean,prebuild",以及要編譯檔案的目錄和檔案字尾(.scala 檔案)。"run"指定了要執行的檔案即實際測試的檔案(.class 檔案),"showoutput"指定是否輸出所有的 log 日誌,"printsummary"指定是否輸出每個檔案執行完畢後的總結(即總共多少個 case,成功失敗數目各為多少),"haltonfailure"指定是否遇到錯誤就停止,"include name="用於控制要測試的 scope 和模組(分別從 buildScope.prop 和 model.props 中獲取),如此處 scope 為"MiniSmoke",模組為 aa,新增一個模組則新加一行"include name=",可通過 Shell 控制。"report"指定利用測試完畢後所生成的所有名稱為"TEST-*.xml"的檔案生成 report。

圖 11. build.xml 片段

編譯、測試、Report 階段依次執行命令為"ant build"、"ant run"和"ant report",測試並生成 report 之後將生成的 report 檔案全部放入 Apache Tomcat 特定目錄中並且啟動 Tomcat,即可通過 Tomcat 的埠訪問 report 內容。為了完全實現自動化,我們將此訪問連結通過郵件系統傳送到指定的郵箱中,可以通過 Linux 系統下的 sendmail 功能傳送,也可以通過 Jenkins 的 mail 功能傳送,即流程中的 Mail Notification 階段。

如圖 12 所示,郵件所收到的 report 連結是以"ip:埠/目錄/build 號_scope/index.xml"的樣式存在,Tomcat 預設埠是 8080,可以自行修改(apache-tomcat-7.0.77/conf/server.xml 中),本系統中我們改成了 8888,build 號_scope 保證了多個 report 並存互不影響從而使得我們可以同時管理很多歷史 report 以便於後續檢視。

圖 12. report 頁面

總結

基於 Docker 的環境部署及測試涉及大量細節,如各個軟體的安裝配置、整個系統各個部分是如何通過 shell 指令碼一一串聯起來以完成整個流程、report 頁面上各種資訊的顯示、程式碼編譯出錯後停止後續流程自動傳送郵件將錯誤資訊通知維護人員等等,由於內容過於繁瑣且文章篇幅有限在此不能一一介紹,在實際環境部署測試過程中大家可以具體體會。文中所涉及的軟體技術均為當今業界比較流行的技術,參考資料也相對較多,網路或官網上均可以查詢到相關幫助,有興趣的可以做進一步深入研究。

需要軟體測試資料的朋友,可以來加群:747981058。群內會有不定期的發放免費的資料連結,這些資料都是從各個技術網站蒐集、整理出來的,如果你有好的學習資料可以私聊發我,我會註明出處之後分享給大家。