本文是數人云工程師方誌浩在DockOne微信羣分享的實錄,與你們聊一聊應用容器在配置管理中遇到的問題以及解決方法。mysql
隨着Docker技術的火熱發展, Docker在代碼構建發佈中扮演着愈來愈重要的角色。Docker讓開發者能夠打包他們的應用以及依賴包到一個可移植的容器中,而後發佈到流行的Linux機器上。Docker很是適用於以下場景:redis
應用容器的自動化打包和發佈;spring
自動化測試和持續集成、發佈。sql
此次主要和你們聊聊應用容器在配置管理中遇到的問題。首先是介紹現有容器經常使用的配置文件加載方式,接下來重點介紹數人云組件在自動化打包和發佈遇到的問題和解決方法。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
這種方式對於單實例應用比較方便。架構
下載配置中心文件的方式app
這種方法首先須要創建配置中心,例如用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系統架構流程圖:
Marathon、Jenkins做爲Framework註冊在mesos-master上,動態調度mesos-slave資源。
Marathon負責應用的發佈
Jenkins負責代碼打包、鏡像構建
Mesos Framework截圖以下:
若單純-v的掛載方式需提早將配置文件放在mesos-slave所在的宿主機上,新加slave時也需進行相同的操做,且當配置文件須要更新時,需更新每臺mesos-slave宿主機上的配置文件,這顯然不夠靈活,因此咱們剛開始採用應用容器啓動下載配置中心文件的方式。
早期的配置中心,以下圖所示:
此時存在的問題有:
由於是多種環境,雖然把這些配置都在Configserver上集中配置,可是須要手動修改這些配置。手動修改容易出錯,例如Dev更新了一個服務,可能過了一週纔會更新到生產環境。那個時候再去修改生產就很容易出錯,致使沒法運行。
若是配置發生了Bug須要回滾,手動修改也是不合適的。
咱們進行了改進,引進Jenkins後工做流程以下圖:
咱們用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界面上可見 。
如下是具體的工做,咱們對開發進行了規約。
除了代碼和產品開發的一些文件外,還須要規約一下目錄結構:
module_name - | -deploy - | -env | -deploy-marathon.sh | -compile.sh | -dockerfiles - | -Dockerfile_compile_env | -Dockerfile_runtime
在GitHub中更新env文件,這個由開發提供維護,裏面有對應env文件以下圖:
改進後具體的流程圖以下:
以上主要對配置文件進行env化,減小配置替換複雜度,將配置存在於Marathon發佈腳本中。
更新後產生的marathon applist:
單個應用容器配置:
採用env化有助於配置文件的統一維護和管理,新版Marathon很好的支持了應用的更新和回滾,除去了容器啓動對靜態配置文件的依賴,使應用容器更新發布、回滾更加方便。從界面上能夠看到全部容器配置信息,使排錯管理也變得方便。
線下數人云企業版組件採用和線上相同的鏡像和env變量,經過API獲取對應版本的envfile和Docker鏡像,以後將全部配置文件抽離到一個配置文件中,實施的同事只需修改這張配置文件,從而省去修改其餘配置文件的步驟,使得實施過程更加簡單。
以上就是數人云組件配置管理碰到的問題,以及env化解決方式,歡迎你們提出寶貴意見。
Q:請問MySQL數據庫怎麼隨Docker遷移?備份和恢復有什麼好的建議嗎?
A:MySQL如今是固定主機主從同步,沒有對MySQL作遷移,咱們的數據如今備份是定時全備份,正在嘗試使用MariaDB集羣Galera Cluster ,但尚未上生產,固然有共享存儲的話就最好不過啦。
Q:請問配置文件的話生產環境和開發環境怎麼區分?
A:生產環境和測試環境都是隔離的,配置文件配置不一樣的參數便可。
Q:請問對相似Java應用jdbc、spring.xml等配置文件如何管理?
A:XML配置經過sed替換傳入的環境變量。
Q:生產上配置項變動怎麼操做?
A:生產配置的值須要修改時 ,在configcenter頁面中修改,再觸發Jenkins更新配置文件的job, 生產新的配置文件 ,再調用marathon API 更新task進行更新。
Q:業務的配置是和環境配置放在一塊兒的麼?
A:是的,都是經過envfile進行統一的。
Q:請問大家對環境變量是採用什麼樣的管理方法?有相應的命名規範嗎?環境變量多了,會出現管理方面的問題吧。
A:環境變量鍵值由開發維護,運維須要提早了解新增環境變量,目前在配置中內心維護,容器環境變量變量命名規範很重要,咱們目前採用服務名+需鏈接的組件名+屬性 進行命名的,且環境變量所有大寫。