天天看點

(六):大型項目容器化改造

虛拟化和容器化是項目雲化不可避免的兩個問題。虛拟化由于是純平台操作,一個運作于linux作業系統的項目幾乎不需要做任何改造就可以支援虛拟化。而項目如果要支援容器化則需要做許多細緻的改造工作。容器化相對于虛拟化的優勢也相當明顯,運作于裸機性能高,秒級啟停容器,更不用說開發、測試、布署一緻的環境(DevOps理念),以及上篇提到的微服務的能力。大家還可以找到各種文章來介紹容器化(Docker)的知識,這裡我們就不一一贅述。下面我們會根據項目的實際情況,介紹下容器化改造會面臨的問題和解決方案。

大型項目容器化改造

上一篇:(五):C++分布式實時應用架構——微服務架構的演進

技術交流合作QQ群:436466587 歡迎讨論交流

  版權聲明:本文版權及所用技術歸屬smartguys團隊所有,對于抄襲,非經同意轉載等行為保留法律追究的權利!

  虛拟化和容器化是項目雲化不可避免的兩個問題。虛拟化由于是純平台操作,一個運作于linux作業系統的項目幾乎不需要做任何改造就可以支援虛拟化。而項目如果要支援容器化則需要做許多細緻的改造工作。容器化相對于虛拟化的優勢也相當明顯,運作于裸機性能高,秒級啟停容器,更不用說開發、測試、布署一緻的環境(DevOps理念),以及上篇提到的微服務的能力。大家還可以找到各種文章來介紹容器化(Docker)的知識,這裡我們就不一一贅述。下面我們會根據項目的實際情況,介紹下容器化改造會面臨的問題和解決方案。

(六):大型項目容器化改造
(六):大型項目容器化改造

  一個幾十萬行c++代碼、大幾十個應用程式的大型項目進行容器化。如何對原來的代碼改造最小,甚至代碼都不需要修改。如何靜悄悄的,甚至不讓業務程式員發覺。如何将業務鏡像的體積做到最小。如何快速地制作一個業務鏡像。這些一直是困擾我們多時的問題。容器分類的時候,如果需要對代碼組織方式和架構進行調整,對于幾十萬行的項目将會是一個災難。容化改造完後,如果開發模式變化太劇烈,無可避免會面臨幾十個、上百個業務程式員重新學習适應的過程,成本驚人。業務鏡像的大小直接影響對現場更新容器友善與否的問題,特别是當項目在海外,網絡速度不是很快的情況下。自動化、快速的鏡像制作是能否進行靈活開發的關鍵。

  一、如何開始

  如何将一個運作于linux的項目挪到容器裡面去運作通常是遇到的第一個問題。網上找一個帶gcc編譯器和linux作業系統的基礎鏡像,基于這個鏡像可以先制作一個編譯和CI檢查(代碼檢查、運作單元測試等等)的建構鏡像。利用建構鏡像進行編譯和CI檢查,然後基于基礎鏡像制作運作鏡像,将編譯好的庫和可執行程式拷貝進去(通過Dockerfile)。這樣一個最簡單鏡像就制作好了。

  

(六):大型項目容器化改造

  上面方法做出來的業務鏡像可以運作,但有兩個問題,制作的時間特别長(我們項目需要一個小時)、鏡像的業務層特别大(我們項目有1個G)。兩個問題不是特别嚴重,但如果項目拿去商用就是一個很麻煩的問題。

  二、容器分層

  容器分層的概念是Docker的核心概念,就是支援每個容器可以“繼承”自另外一個容器。這裡的繼承跟面向對象裡的繼承應該是同一個概念。這樣除了可以帶來“繼承”特性的好處,底層鏡像變動時,不需要去更新上層的鏡像,這樣就可以少更新很多東西。的确很妙,面向對象的繼承我都沒覺得有這麼好用!受這個特性影響,我們将項目用到的第三方庫單獨提出來做成一層。制作的流程也相應地變成下圖所示。

(六):大型項目容器化改造
(六):大型項目容器化改造

  雖然過程多了一步,但效果也是立竿見影的,業務層的制作時間從原來1個小時縮短為12分鐘,大小也變為100M左右。

   三、業務容器分類

  在Docker最佳實踐的建議裡面,建議一個容器最好隻跑一種程式,或者一類程式。像原來那樣,一個容器跑幾十個程序一定是不合适的。分類清晰的容器也便于管理和進行各種操作。同時,在微服務的最佳實踐裡面,建議将項目的代碼分割成一個個的微服務。每個微服務的代碼由不同的團隊維護,各自獨立。我們先暫時不讨論這種方式的優缺點。原先的項目是一個幾十萬行、幾十個程式的大項目,有幾十個人開發人員,有無數的公共子產品,每個子產品間互相引用也很普遍,每個程式由數量不等的子產品來組成。如果按上面的建議來進行Docker的業務分類,無疑會給項目帶來巨變,并且涉及組織架構的大調整,幾乎是一個不可能的任務。那麼如何做既可以對容器進行分類,又保持原有的開發模式不變。有時候察覺不到改變才是推進一項新技術的最佳方式。

  方法其實也很簡單,容器裡面有一個叫docker-entrypoint.sh的角本,管理容器啟動後要啟動哪些程序。上面我們已經制作了一個項目統一的鏡像,在分類的時候,我們隻要根據不同類型容器,修改不同的docker-entrypoint.sh來啟動不同類型的程序就可以了。要配合設定不同的環境變量,不同的配置檔案等等。當然,這一切都很容易!

#!/bin/bash
set -e
supervisord

if [ "$1" = 'help' ]; then
   echo 'Tips: '
   echo 'docker xxxx bash to load the bash CLI'
   echo ''
   echo ''
   exit
fi

# use exec and gosu to trap unix signal
# application can be add here follow this sample

if [ "$1" = 'start' ]; then
   cd $HOME
   bash config_ocs.sh           
   source ~/.bash_profile
   RuleCache -C
   sleep 5
   
   bash start_clean_data.sh
   
   sleep 600 # just for test
fi

# default

exec "$@"      
(六):大型項目容器化改造

 未完待續……