1. 程式人生 > >測試環境docker化—容器集群編排實踐

測試環境docker化—容器集群編排實踐

發布 多臺 穩定 並保存 mage 共享 gis war 快速部署

本文來自網易雲社區

作者:孫婷婷


背景

在前文《測試環境docker化—基於ndp部署模式的docker基礎鏡像制作》中已經詳述了docker鏡像制作及模塊部署的過程,按照上述做法已可以搭建測試環境。但是在實踐過程中發現存在很多問題:

  1. 在一臺雲主機上搭建多個模塊,容易出現資源不足的情況(我們在實驗過程中有臺雲主機好幾次宕機,經常要刪掉不用的鏡像容器);

  2. 部分模塊之間需要相互調用,為方便部署多套環境簡化配置修改,部署時需要確定容器的ip地址;

  3. 手動敲命令一個個構建容器,n個模塊就要敲n個構建指令,構建容易出錯;

基於上述原因,同時參考組內大神倪子的實踐《細說Mammut大數據系統測試環境Docker遷移之路》,我們也嘗試了引入容器集群編排,來進一步優化測試環境docker化的過程。


容器集群搭建

為解決一臺測試環境雲主機可能支撐不了一套環境的問題,我們考慮使用多臺雲主機組成一個容器集群,將多個deploy容器負載均衡的部署到多臺雲主機上,來實現環境的穩定和資源的合理利用。

要實現多主機的容器部署和分配,需要引入集群調度工具。目前業界比較主流的調度管理工具有Docker Swarm、Google Kubernetes 和 Apache Mesos(基於Marathon框架),其中目前已占領上風的是Kubernetes,成為容器編排管理的最佳實踐工具。但是參考倪子的文章和介紹,我最終決定繼續選擇Swarm來進行實踐。在Swarm的學習調研過程中,我發現區別於倪子實踐使用的Docker Swarm,docker1.12版本已經進一步推出了內置的簡單易用的Swarm mode集群。老的Docker Swarm使用獨立的外部KV存儲(比如Consul、etcd、zookeeper),搭建獨立運行的Docker主機集群,使用KV存儲配置進行服務發現。新版的Swarm mode則將docker swarm包含到docker引擎中,並內置了服務發現工具,使得集群搭建進一步簡化為直接使用docker swarm命令初始化一臺主機作為manager,其他機器加入該swarm成為worker即可。具體命令如下(我們的測試環境共使用3臺雲主機):

#將一臺主機指定為manager,該命令會返回唯一一個集群唯一token,且該節點會同時作為manager和worker運行sudo docker swarm init --listen-addr 10.165.148.87:2377 --advertise-addr 10.165.148.87#在另兩臺主機上運行上述命令返回的join命令,即可加入該swarm集群sudo docker swarm join     --token SWMTKN-1-0cytn4js5b8jn0vibtk935y7jptqxv63ttiqui1qhi2uo07emx-cr80z41yz9v2tsn8vyxgy6k2u \    10.165.148.87:2377

以上命令即完成集群搭建,可通過sudo docker node ls命令查看集群中的節點。此後用戶便可以通過manager節點操作整個集群,把多臺Docker主機當做一臺主機來部署容器服務和管理。


跨主機通信

docker官方文檔介紹,當我們在一臺主機上初始化一個swarm或者將一臺雲主機加入到一個swarm中時,該主機上將會默認創建兩種新的網絡:

  • 一種是名稱為ingress的overlay型網絡。ingress主要負責swarm集群中服務之間的負載均衡和服務發布。若用戶在新建swarm service時未指定自定義的overlay網絡,它會自動加入ingress。

  • 另一個中名稱為docker_gwbridge的bridge型網絡。它是一個用於連接overlay型網絡(包括ingress)和獨立docker主機的物理網絡的虛擬網橋。

備註:理論上docker_gwbridge是自動創建的,但是不知道為什麽我在實踐過程中沒有找到docker_gwbridge,最後自己重新創建了該網絡。若想自定義創建和設置docker_gwbridge,那麽必須在初始化或者加入swarm前創建,否則之後創建的容器端口將無法成功映射至主機端口。

當我們發布服務時,可以創建一個私有網絡,實現跨主機之間的容器通信。在Docker1.9版本之後,Dokcer給大家帶來了一種原生的跨主機容器網絡解決方案,該方案基於VXLAN的覆蓋網技術、依靠獨立的外部KV存儲(比如Consul、etcd、zookeeper)來通過註冊於同一存儲的配置來實現“服務發現”和“DNS”解析,從而實現私有網絡的跨主機通信;同時在Docker1.12版本之後,我們只要通過Swarm mode搭建集群,而後創建overlay網絡,直接用“原生態”的swarm來發現進行通信。

#若需要自定義創建docker_gwbridge或加入swarm後未發現docker_gwbridge,可以通過退出swarm後自定義創建;註意若想手動創建,必須要在加入swarm集群之前sudo docker network create --subnet 192.168.18.0/24 --opt com.docker.network.bridge.name=docker_gwbridge --opt com.docker.network.bridge.enable_icc=false --opt com.docker.network.bridge.enable_ip_masquerade=true docker_gwbridge#創建私有overlay網絡,用於跨主機容器通信,-- opt 指定網絡安全模式sudo docker network create --driver overlay --subnet 192.168.47.0/24 --opt encrypted overlay-net

私有網絡創建完成後,只需在創建容器服務時指定自定義網絡,容器變會在創建時自動加入該網絡,實現容器間通信。

好了,現在容器之間可以互相訪問了。但是每次容器啟動的時候overlay都會動態分配一個虛擬IP地址,這樣容器之間互相調用的時候就會需要在每次容器啟動後再去容器中修改IP地址,當配置文件較多時修改起來會更加麻煩。熟悉docker engine的人一定知道link這個功能,Swarm mode則提供了一個類似的service discovery功能,它會將容器的虛擬IP映射到swarm的內置dns中,使用服務名稱service name來作為域名。那麽訪問容器的IP則只需要訪問服務名稱,使得容器間通信更加方便。


compose部署

到此其實測試環境docker化的基本工作已經完成了,但是結合前文鏡像制作的內容,我們的測試環境部署需要至少1個compile容器+n個deploy容器,deploy容器中也可能有多個web服務,各個容器需要暴露port,添加各自的entry.sh,若是通過docker service create命令一個個創建,一不小心就會配置錯誤導致容器無法啟動;配置多套環境的可復制性也會差很多。

一個簡單的辦法是使用compose進行容器編排,將各命令簡化為只需要編寫compose的yaml文件即可。Docker1.13版本之後增加了compose v3,在Swarm的基礎上引入了stack對service鏡像的管理和編排,使得容器服務的部署更加簡單。compose v3的語法可以參考Compose file version 3 reference,註意其與v2有些許不同。

我們在項目部署中,考慮到compile容器需要先行創建,以便在deploy部署前完成項目代碼的構建,我們將整個測試環境的部署分割為3個yaml文件:

  • compose-compile.yaml:用於compile容器先行創建

  • compose-dependency.yaml:用於項目中依賴模塊容器創建(比如zk、kafka、redis、mysql等)

  • compose-deploy.yaml:裏面添加了項目各個模塊的容器創建指令

我們在搭建完swarm環境+準備好各配置文件後,由於compose同時可以自定義創建network,最終我們僅需要三行命令即可創建一套測試環境:

#生成dependency應用,該應用中包含項目部署所需要的相關依賴,包括kafka、zk等 sudo docker stack deploy --with-registry-auth -c ./compose-dependency.yaml antispamdependency#生成compile應用,創建antispamcompile-compile服務完成項目編譯sudo docker stack deploy --with-registry-auth -c ./compose-compile.yaml antispamcompile#生成antispam應用,該應用中包含各模塊部署的相關服務sudo docker stack deploy --with-registry-auth -c ./compose-deploy.yaml antispam


測試環境docker自動部署

在完成compile和deploy鏡像的制作後,可以將鏡像保存在蜂巢,以方便部署環境時拉取。同時為保證每個deploy容器在創建後能自動拉取compile容器中構建好的編譯模塊進行模塊部署,我們為各個功能模塊編寫了相應的entry.sh並保存在網易git倉庫中,entry.sh文件實現相應的構建模塊拉取、部分配置修改和模塊啟動。同時在deploy鏡像中內置一個inter-entry.sh,該腳本用於deploy啟動時拉取entry項目,並通過容器啟動參數運行相應的entry.sh文件。

inter-entry.sh文件內容如下:

#!/bin/bashgit clone ssh://git@xxxx:22222/hzsuntingting/xxx-docker-entries.git /usr/local/docker-entry/xxx-docker-entries/echo $1chmod 777 /usr/local/docker-entry/xxx-docker-entries/entries/$1/usr/local/docker-entry/xxx-docker-entries/entries/$1

同時docker-entries項目中保存了compile編譯項目需要的build.xml和容器編排需要的yaml文件,這樣項目測試環境docker化只需要增加一個docker-entries項目,該項目目錄結構如下:

技術分享圖片

最終,在搭建完swarm環境和準備好文件後,一個項目使用docker部署的流程如下圖所示:

  1. 主機下載各依賴模塊的鏡像創建相應的依賴模塊的容器;

  2. 修改被部署項目的接口調用配置為docker服務的service name,例如部分模塊需要調用zk,而docker部署環境中zk的service name為dependency_zookeeper,則直接將調用ip改為該服務名即可;

  3. 主機下載compile鏡像創建compile容器,容器在git拉取項目代碼和docker-entries(裏面含有build.xml),進行項目構建打包,並httpServer等待其他模塊拉取;

  4. 主機下載deploy鏡像創建各deploy容器,容器內置的inter-entry.sh運行在git拉取docker-entries;

  5. 各deploy模塊拉取docker-entries後,根據容器啟動的entrypoint參數運行相應的entry.sh,到compile容器中拉取相應的構建模塊,解壓,修改配置並啟動。

技術分享圖片


總結

到此,測試環境docker化的自動化部署過程基本完成,組內成員已可實現用幾行命令即完成一套環境的部署工作。但是在實踐過程中,還有很多需要優化的地方,例如:目前各跨主機容器之間的文件共享采用的是起一個簡單的httpServer+wget的方式以及git的方式替代,必須要指定確定的路徑,在腳本編寫過程中需要仔細比對,容易出錯,若實現跨主機的文件共享則會避免更多錯誤問題。同時,查看網上資料,Swarm mode集群會折損系統約50%的性能,後續替換為k8s來實踐,肯定為更有利於測試環境來完成異常測試等對系統穩定和性能要求比較高的測試。


例行一坑,讓大家少走彎路~

1. 指定主機為manager時,若機器有多個ip地址,需在其後加參數“--advertise-addr 10.165.148.87 ”,否則會報錯

技術分享圖片

2. 創建overlay網絡時可以用subnet參數指定用於網絡的子網,如果不指定,swarm會自動選擇一個子網,但是根據官網的描述這個自動指定的子網可能會引起container通信的問題

3.compose的yaml編寫時,volumes中type:volume需要版本在3.2及以上,否則會返回services.compile.volumes.0 must be a string

4.在一開始從蜂巢拉取鏡像的時候報錯如下,原因是其他主機節點無權限,需要通過--with-registry-auth參數來增加權限。

unable to pin image hub.c.163.com/neteaseqa2017/compile to digest: errors:
denied: requested access to the resource is denied
unauthorized: authentication required



網易雲容器服務為用戶提供了無服務器容器,讓企業能夠快速部署業務,輕松運維服務。容器服務支持彈性伸縮、垂直擴容、灰度升級、服務發現、服務編排、錯誤恢復及性能監測等功能, 點擊可免費試用。

網易雲免費體驗館,0成本體驗20+款雲產品!

更多網易研發、產品、運營經驗分享請訪問網易雲社區。


相關文章:
【推薦】 微服務監控探索
【推薦】 接口文檔神器Swagger(下篇)

測試環境docker化—容器集群編排實踐