一個小白的測試環境docker化之路

本文來自網易雲社區html


做者:葉子
java

學習docker搭建測試環境斷斷續續也有三個多月了,但願記錄一下這個過程。常言道,總結過去,展望將來嘛~文章淺顯,還望各位大神路太輕拍。node

按照國際慣例,先說一下背景:linux

目前我所處的項目組不斷擴大和發展,所以質量保障維度也須要不斷擴展。然而多種質量保障維度的開展須要多套測試環境的支持,目前項目組裏只有一套測試環境,按照傳統方法一步步手工搭建測試環境費時費力,有什麼方法能夠迅速搭建環境呢?固然是近幾年大火的docker啦。但是我是docker小白,以前只是簡單地看過幾篇docker入門的帖子,去官網上按照tutorial敲了一遍命令,但總感受是紙上談兵,一到實戰環節,依然無從下手。git

中國首富王健林說:「先定一個小目標「。咱們的項目裏面除了java web應用就是java app應用,java web應用說白了就是tomcat麼,之前本身手動部署過,看上去不會太難,那就從這個開始,先用docker部署一個項目中的tomcat應用好了。docker方面的知識是零基礎,老大推薦了一本書叫《第一本docker書》。web

這本書淺顯易懂,適合我這個小白,粗粗讀完前4章後,我就感受本身能夠上路了。redis

測試環境的應用模塊部署都是在ndp平臺上部署的,先簡單瞭解下ndp平臺部署web應用的原理,就是將代碼從git上拉下來,編譯打包好,找一臺雲主機,這臺雲主機上安裝了jdk和tomcat,而後把打包好的代碼放進tomcat裏,設置下端口號,啓動起來就行了。那若是用docker怎麼部署呢?讀完docker書就知道,其實一個docker容器就至關於一臺雲主機,咱們的雲主機是linux系統,拉一個linux系統的鏡像,啓動這個鏡像的容器後,我在裏面裝個jdk和tomcat,這不就和咱們的雲主機環境如出一轍了嘛~  docker

 

到這裏思路就清晰多了,第一步先搞個和雲主機環境同樣的docker容器,網上搜了一下後,發現直接就有現成的tomcat鏡像,tomcat自己也依賴jdk,並且也是基於linux環境的,第一步立馬就作完了,這速度槓槓滴。那接下來就是拉取代碼,編譯打包,而後放進去啓動就能夠了。因而乎,第一個問題就碰到了,代碼是有權限的,不是隨便就能夠拉取的。回想之前在雲主機上拉取代碼,是在這臺雲主機上生成一對ssh密鑰,而後把公鑰上傳到git lab上,這樣就能得到拉取代碼的權限了。都說實踐是檢驗真理的惟一標準,趕忙在剛剛啓動的docker容器裏試了一把,恩,行得通!但是這才一個docker容器啊,若是我再來幾個docker容器,每一個容器都要生成一對ssh密鑰,而後上傳,豈不累死。 怎麼辦呢?馬克思主義哲學說道過,要透過現象看本質,git識別權限的本質是什麼?是在於私鑰和公鑰的匹配!公鑰在git服務器上,那我本地只要有對應的私鑰就能夠了呀,我在建立容器的時候把一個git已有的公鑰所匹配的私鑰放進去,這樣容器就自帶git權限了嘛。  數據庫

代碼拉下來之後,下一步就是編譯打包,那先研究下ndp平臺是怎麼部署咱們測試環境的web應用的吧。看了一下,在ndp平臺上找到了這個web應用的一個build.xml,咦,這不就是ant工具的執行腳本麼,仔細一讀,果真是個編譯打包的腳本,其中關鍵的步驟是利用mvn clean install進行編譯打包的。ok,那在剛剛啓動的容器裏安裝一下ant和maven工具,而後用ant命令執行下這個build.xml,大功告成!  瀏覽器

執行完ant命令之後,發現生成了一個compressed的文件夾,裏面主要是編譯打包後生成的東西,以下圖:  

那麼這些編譯打包好的東西應該放在哪裏呢?再一次研究一下ndp部署的tomcat應用的目錄層級,內心估摸着我把docker容器中的目錄層級弄得和ndp同樣應該不會有什麼問題。通過對比發現,compressed文件內容和測試環境tomcat應用的webroot文件內容是同樣的,吼吼~  

此外,其餘目錄層級不同的地方羅列了一下,大概有以下幾個:  

大體讀了讀,tomcat是個腳本文件,用於啓動tomcat服務用的,裏面調用了./default/tomcat、init-functions和ratatelogs文件,那就把這些須要的文件都拷貝過來,並確保tomcat腳本里全部的調用路徑都正確。  

另外還須要修改的server.xml,將docBase地址指定爲compressed的絕對路徑  

 

將兩邊目錄層級弄的如出一轍後,就到了見證奇蹟的時刻,運行啓動命令:  

./tomcat start

查看日誌發現正常啓動,並沒有異常報錯,這真是個好兆頭。再用瀏覽器試試是否能訪問成功,看到預期的網頁打開了:)至此,第一個用docker方式部署的web應用模塊就完成啦  

鑑於項目裏有多個不一樣的web模塊,它們所依賴的基礎環境都同樣,所以打算構建一個基礎鏡像,將所須要的相同的配置文件都放入基礎鏡像中,而後各自模塊的編譯打包過程寫成一個Dockerfile,這樣就不用在容器裏手敲命令進行編譯打包了,Dockerfile僞代碼以下:  

FROM tomcat 基礎鏡像git clone 代碼COPY build.xml, 配置文件等到容器裏指定的路徑RUN build.xml,生成打包文件COPY 打包文件 TO destination filestart 啓動運行模塊

web應用搞定後,接下來就是java app模塊了。看了一下環境依賴,只須要裝個jdk環境就行,而後ndp上一樣有java app的構建腳本build.xml,再研究下npd部署的java app的目錄結構,該拷貝的拷貝,該修改的修改,照貓畫虎弄一遍,也啓動成功了。  

接下來就是優化下tomcat和java app這兩個基礎鏡像,而後再寫寫各自模塊的Dockerfile就好了  

 

每一個模塊都有本身的Dockerfile,這樣就能迅速構建模塊鏡像並啓動部署了。至此,利用docker部署項目的應用模塊就完成了。  

感謝上述過程當中提供大力幫助的集美貌與才華於一身的婷婷同窗~  

--------------------  

踩過的坑:  

一、在執行build.xml腳本進行構建時,遇到相似以下的報錯:  

 

 

緣由是所須要的jar包由於在maven遠程倉庫中沒法找到,首先檢查一下在docker容器安裝maven後,記得要把settings.xml設置成杭研的maven倉庫,若是還遇到這樣的錯誤,多是杭研maven倉庫裏沒有該jar包,或者由於網絡等其餘問題,沒法下載該jar包。基本上通用的jar包都能下載成功,有一些基於模塊之間依賴的jar包沒法下載到,若是你本地maven倉庫裏有這些jar包的話,能夠拷貝進容器的maven倉庫裏,或者在容器里拉取相互依賴模塊的代碼,經過mvm clean install命令將其打包進容器的maven倉庫裏。  

二、在容器裏啓動應用後,遇到沒法連通redis的問題:  

 

 

代碼裏填寫的redis地址是雲主機的私有ip地址,容器所在的宿主機與redis在不一樣租戶下,所以沒法經過私有ip進行連通訪問,容器的宿主機與redis同屬於一個機房,可經過機房ip進行訪問,與開發協商將代碼裏的依賴服務的ip地址都改成機房地址。  

三、在docker容器裏拷貝git hub的私鑰後,執行git clone命令出現如下狀況:  

 

 

這個提示已經比較清楚了,.ssh/id_rsa 這個私鑰文件權限 too open,修改私鑰的權限:chmod 0600 id_rsa 後便可git clone代碼了。  

--------------------  

然而好景不長,很快咱們就發現針對每一個應用模塊寫Dockerfile這種方式的不足,一是構建的鏡像太多,每一個模塊都要構建鏡像,而後啓動容器,鏡像也比較大,很是佔空間;二是因爲咱們項目的特殊性,有些應用模塊在構建時須要依賴別的項目的jar,當時爲了圖省事把依賴的jar直接放入基礎鏡像了,當依賴的jar發生變化時,個人基礎鏡像就要從新弄了,全部其餘模塊的鏡像都要從新弄,這可要了命啊。看來此計不是長久之計,還需另謀出路。  

通過以前的探索,咱們知道,ndp的部署模式是一盞指路明燈,以前就是照着ndp的部署腳本照葫蘆畫瓢過來的,那ndp平臺是怎麼解決不一樣模塊之間的打包依賴問題呢?粗粗研究了一下,發現ndp是統一在一個地方打包,而後將打包好的compressed文件分發到別的雲主機上進行部署。那按照這個思路,咱們也找一臺容器進行統一編譯打包,而後分發到不一樣的容器進行部署唄。  

 

 

如此一來,咱們只須要三個基礎鏡像,一個是用來編譯打包的鏡像,只須要安裝jdk,maven,ant等編譯打包工程所依賴的工具,一個是tomcat鏡像,一個是java環境鏡像,再寫一個腳本,僞代碼以下:  

get compressed file  #對應模塊的打包文件get config file           #對應模塊的部署配置文件start module            #啓動運行模塊

如何獲取對應的打包文件呢? wget 命令能夠從遠程服務器上下載文件,前提是不一樣容器之間的網絡須要互通。咱們能夠本身手動建立一個docker網絡,而後把不一樣的容器都手動加入這個網絡裏,這樣全部容器都在同一個網絡裏,應該就不存在網絡不通的問題了。獲取部署配置文件咱們採用了git pull方式,在git上維護全部模塊的部署配置文件。  

如此一來,當部署web模塊的時候就以tomcat鏡像來啓動容器並同時運行腳本,部署java app模塊的時候就以java app鏡像啓動容器並同時運行腳本,如此一來就不用給每一個模塊寫Dockerfile製做鏡像了,也節省了很多構建鏡像的空間。  

不過雖然節省了構建鏡像的空間,但容器運行的空間仍是要提供的。一臺雲主機的基本配置是4核 CPU,8GB 內存,而項目的模塊多達20幾個,所有模塊放在一臺雲主機上可吃不消。確定要搞多臺雲主機做爲一個集羣,把容器部署到這個集羣中。這時候就要用到容器編排工具了,編排工具負責如下幾點:  

  • 選擇最適合部署容器的機器,好比擁有最多空閒資源的機器

  • 發生機器故障,能自動把故障機器上的容器部署到其它節點。

  • 若是集羣添加了新的機器,從新平衡容器的分配狀況。

  • 若是容器故障了,重啓它。

  • ...

Docker自己內置了容器編排功能,稱爲docker swarm mode。網上有不少關於docker swarm mode的資料,在此就很少闡述了,大體過程以下:  

  1. 建立網橋:在每臺雲主機上建立docker_gwbridge網橋,注意,必須先建立網橋再建立swarm集羣

  2. 建立集羣:指定一臺雲主機做爲manager,初始化swarm

  3. 加入集羣:在其餘雲主機上運行docker swarm join命令,使其加入該swarm集羣

  4. 建立服務:使用docker service create來建立service,相似docker run 命令,建立的時候可直接運行腳本,執行部署過程

使用docker service create命令建立服務的時候須要指定大量參數,每次都要敲好長的命令,能夠用docker compose yaml模板,相似以下:  

version: "3.2"
services:
  compile:
    image: dockercloud/hello-world
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.hostname==docker-test
    ports:
      - "8080:8080"
    networks:
      - overlay_net

networks:
  overlay_net:
    driver: overlay

參考文章:《Docker Compose 配置文件詳解》

至此,咱們解決了編譯打包過程當中各個模塊相互依賴的問題,經過docker swarm mode方式實現了應用模塊集羣化部署的方式,接下來的目標就是將這些應用模塊依賴的其餘基礎服務拆分出來,如數據庫,redis,zookeeper等等,那樣子纔算完整的一套獨立的測試環境。  

網易雲容器服務爲用戶提供了無服務器容器,讓企業可以快速部署業務,輕鬆運維服務。

 

網易雲大禮包:https://www.163yun.com/gift

本文來自網易雲社區,經做者葉子受權發佈。


相關文章:
【推薦】 Lily-一個埋點管理工具
【推薦】 Amazon新一代雲端關係數據庫Aurora(上)
【推薦】 再也不任人欺負!手遊安全的進階之路

相關文章
相關標籤/搜索