DockOne微信分享(六十八):應用容器env化實戰

貓飯先生發表於2017-10-18
本文講的是DockOne微信分享(六十八):應用容器env化實戰【編者的話】隨著Docker技術的火熱發展, Docker在程式碼構建釋出中扮演著越來越重要的角色。Docker讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到流行的Linux機器上。Docker非常適用於如下場景:
  • 應用容器的自動化打包和釋出;
  • 自動化測試和持續整合、釋出;


這次主要和大家聊聊應用容器在配置管理中遇到的問題。首先是介紹現有容器常用的配置檔案載入方式,接下來重點介紹數人云元件在自動化打包和釋出遇到的問題和解決方法。

現有的主要Docker載入配置的方式

首先簡單介紹下現有容器的載入配置檔案的方式。

  • 掛載宿主機配置檔案的方式
    通過docker run -v 引數將宿主機上的配置檔案掛載到容器指定目錄中如:
    docker run -v /myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf --name myredis redis redis-server /usr/local/etc/redis/redis.conf
    

    這種方式對於單例項應用比較方便。

  • 下載配置中心檔案的方式
    這種方法首先需要建立配置中心,例如用Nginx等Web服務元件,提前將配置檔案放在指定目錄,在Dokcerfile entrypoint中拉取配置中心檔案的指令碼,之後容器啟動就自動拉取配置中心的配置。
  • 通過環境變數傳入到容器中
    通過docker run -e 引數將將環境變數傳入到容器如:
    docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6
    


應用容器的自動化打包和釋出中遇到的問題

數人云元件採用微服務架構,將服務拆分,分別採用相對獨立的服務對各方面進行管理,彼此之間使用統一的介面來進行交流,架構變得複雜,但優勢非常明顯。為了保證高可用,這些容器一般都執行在多個VM上,服務例項前是一層諸如HAPROXY的負載均衡器,它們負責在各個例項間分發請求。數人云分測試、演示、生產三種環境進行持續整合、釋出,同時數人云元件通過Docker+Mesos+Marathon進行應用容器的封裝下發和管理。首先說下我們容器釋出遇到的問題——配置檔案多,如何進行統一的管理?

我們由於採用微服務架構,就產生了各個模組的配置,導致配置檔案過多;其次數人云的三套環境,如MySQL等基礎元件IP、Port等配置不同,導致配置成倍增加;最後採用高可用架構,也造成了配置檔案的增多。 下面是數人云Mesos系統架構流程圖:

1.png


Marathon、Jenkins作為Framework註冊在mesos-master上,動態排程mesos-slave資源。

  • Marathon負責應用的釋出
  • Jenkins負責程式碼打包、映象構建


Mesos Framework截圖如下:

2.png


若單純-v的掛載方式需提前將配置檔案放在mesos-slave所在的宿主機上,新加slave時也需進行相同的操作,且當配置檔案需要更新時,需更新每臺mesos-slave宿主機上的配置檔案,這顯然不夠靈活,所以我們剛開始採用應用容器啟動下載配置中心檔案的方式。

早期的配置中心,如下圖所示:

3.png


此時存在的問題有:

  • 因為是多種環境,雖然把這些配置都在Configserver上集中配置,但是需要手動修改這些配置。手動修改容易出錯,例如Dev更新了一個服務,可能過了一週才會更新到生產環境。那個時候再去修改生產就很容易出錯,導致無法執行。
  • 如果配置發生了Bug需要回滾,手動修改也是不合適的。


我們進行了改進,引進Jenkins後工作流程如下圖:

4.png


我們用Jenkins把它們整體串起來,我們的第一個工作是把所有的配置檔案抽象化,各種環境的檔案抽象出來一個模板,放在GitLab上。它的資料是放在資料庫裡面,這樣組合起來是一個完整的配置檔案。各個環境的值是不一樣的。 我們的運維平臺觸發Jenkins,Jenkins去排程我們的ConfigCenter API,它傳入兩個引數,一個是需要更新的環境,另一個是更新哪個服務。之後API去做對比,從資料庫去讀現有的配置檔案的模板Tag,再去讀新模板的Tag進行對比。

如果這個檔案需要更新,把它從資料庫拉過來,資料做匹配,渲染成我們最終的配置檔案,再傳到Gitlab上。剩下的通過Jenkins 觸發 Configserver去調Gitlab下載最新的配置檔案到Configserver伺服器,Jenkins再去呼叫Marathon去重啟服務,服務就會成功更新配置檔案。 這很好解決了配置檔案對應檔案,但還是存在以下一些問題:

  • 配置格式不統一,配置有env 、congfig.js 、.yaml 、.xml 等配置檔案,各種配置檔案需要在應用容器釋出前進行替換,當新增配置檔案項時,需重新編寫模版,替換匹配內容較為繁瑣。
  • Marathon釋出應用採用了配置檔案的方式,在Marathon介面看不到配置檔案的內容,需後臺檢視,增加了運維複雜度。


後來我們對應用進行env化改造,統一配置檔案格式,且配置通過變數傳遞給Marathon,使得所有配置在Marathon介面上可見 。

以下是具體的工作,我們對開發進行了規約。

產品模組GitHub目錄規約結構

除了程式碼和產品開發的一些檔案外,還需要規約一下目錄結構:

module_name -
          |
           - deploy -
                    |
                    - env  
                    |
                    - deploy-marathon.sh
                    |
                    - compile.sh
           |
            - dockerfiles -
                         |
                         - Dockerfile_compile_env
                         |
                         - Dockerfile_runtime


在GitHub中更新env檔案,這個由開發提供維護,裡面有對應env檔案如下圖:

5.png


改進後具體的流程圖如下:

6.png


以上主要對配置檔案進行env化,減少配置替換複雜度,將配置存在於Marathon釋出指令碼中。

更新後產生的marathon applist:

7.png


單個應用容器配置:

8.png


  • 採用env化有助於配置檔案的統一維護和管理,新版Marathon很好的支援了應用的更新和回滾,除去了容器啟動對靜態配置檔案的依賴,使應用容器更新發布、回滾更加方便。從介面上可以看到所有容器配置資訊,使排錯管理也變得方便。
  • 線下數人云企業版元件採用和線上相同的映象和env變數,通過API獲取對應版本的envfile和Docker映象,之後將所有配置檔案抽離到一個配置檔案中,實施的同事只需修改這張配置檔案,從而省去修改其他配置檔案的步驟,使得實施過程更加簡單。


以上就是數人云元件配置管理碰到的問題,以及env化解決方式,歡迎大家提出寶貴意見。

Q&A

Q:Mesos執行一個任務,如果發現該任務執行過程中需要加大資源,Mesos如何做到對任務資源的彈性擴容?如果採用Docker的話,是新建更多的Docker容器還是直接擴大現有Docker的大小?

A:一般是擴充套件更多的Docker容器個數,除非是某個任務有最小資源要求,才要擴大單個Docker的大小。

Q:開發人員使用的本地環境變數如何管理?例如一個應用,有資料庫,有搜尋引擎,還有兩個Java APP,不同開發可能需要嗯環境不同,例如我是搜尋功能的開發,需要連結公共的資料庫,而有些開發需要自己有資料庫,搜尋引擎卻需要連結公共的。這種配置,如何管理?

A:這種最好將資料庫環境變了進行區分,配置兩個或多個類似環境變數。

Q:請問MySQL資料庫怎麼隨Docker遷移?備份和恢復有什麼好的建議嗎?

A:MySQL現在是固定主機主從同步,沒有對MySQL做遷移,我們的資料現在備份是定時全備份,正在嘗試使用MariaDB叢集Galera Cluster ,但還沒有上生產,當然有共享儲存的話就最好不過啦。

Q:請問線上服務更新war包,如何能使對外服務不間斷嗎?

A:數人云目前採用程式碼版本和映象版本統一,對外服務不間斷,數人云目前的做法是對應用進行無狀態改造,後通過marathon put更新容器。

Q:請問 配置檔案的話生產環境和開發環境怎麼區分?

A:生產環境和測試環境都是隔離的,配置檔案配置不同的引數即可。

Q:請問對類似Java應用jdbc、spring.xml等配置檔案如何管理?

A:XML配置 通過sed替換傳入的環境變數。

Q:生產上配置項變更怎麼操作?

A:生產配置的值需要修改時 ,在configcenter頁面中修改,再觸發Jenkins更新配置檔案的job, 生產新的配置檔案 ,再呼叫marathon API 更新task進行更新。

Q:業務的配置是和環境配置放在一起的麼?

A:是的,都是通過envfile進行統一的。

Q:請問你們針對應用彈性擴充套件是自感應的嗎?如果是,請問是基於什麼策略做的,監控報警還是什麼?

A:數人云是通過監控報警觸發彈性擴充套件的,如監控介面返回的時間,容器記憶體使用率等。

Q:請問你們對環境變數是採用什麼樣的管理方法?有相應的命名規範嗎?環境變數多了,會出現管理方面的問題吧。

A:環境變數鍵值由開發維護,運維需要提前瞭解新增環境變數,目前在配置中心裡維護,容器環境變數變數命名規範很重要,我們目前採用服務名+需連線的元件名+屬性 進行命名的,且環境變數全部大寫。

以上內容根據2016年7月14日晚微信群分享內容整理。分享人方誌浩,92年的程式猿,畢業之後一直在數人云,對 Docker 和 Mesos 有深入研究,目前做數人云平臺打包部署以及部分客戶專案實施工作,喜歡在實踐中嘗試新事物並總結。 DockOne每週都會組織定向的技術分享,歡迎感興趣的同學加微信:liyingjiesz,進群參與,您有想聽的話題或者想分享的話題都可以給我們留言。

原文釋出時間為:2016-07-15

本文作者:方誌浩

本文來自雲棲社群合作伙伴Dockerone.io,瞭解相關資訊可以關注Dockerone.io。

原文標題:DockOne微信分享(六十八):應用容器env化實戰


相關文章