Docker是現在開發應用程序的不錯選擇;因為對於一個研發組來說,部署一個應用再也不用像以前那樣繁瑣的修改、設置配置文件了;因為對於Docker來說它“屏蔽”了應用程序的運行環境,不管你使用Mac、Linux還是Windows都能用相同的方式運行。
但是,當你使用Docker將應用部署到生產環境時,你會覺得Docker還是有些“弱”,至少從Ruby On Rails(ROR)的角度出發是這樣的。當我查找與測試了很多不同的部署方法與Docker鏡像後發現:確實沒有一個確切而且標准的部署方案。在這篇文章中我會分享一種生產環境部署ROR應用的最佳實踐。
標准在實際操作之前,我們列舉生產環境部署應用的標准:
## 操作就像之前我說過的,我希望部署過程越簡單越好。如果你看過Docker:Part4這個視頻,可能對以下命令有所熟悉,它啟動了一個叫db的容器(跑postgres數據庫),之後又啟動了一個叫web的容器,最後將容器“web”跟容器“db”連接起來。
$dockerrun-d--namedbtraining/postgres$dockerrun-i-t--nameweb--linkdb:db-p45000:80
當然如果你照著這麼做來部署程序,當你敲了很多次這樣的命令後,而且保證不遺漏的敲了很多次這種命令後,你會發現這是個“坑爹的”噩夢。這就是為什麼會有Fig的原因。
FIG如果你用Dockerfile來定義如何生成你的容器,那麼Fig則可以幫你定義整個容器的運行框架。Fig將“添加數據卷(add volumes)”、“連接容器”(link container)與“映射端口”等操作都封裝到一個YAML的描述文件中;如同前面提到的CodeTV中描述的那個操作在Fig中簡化成如下形式:
web:build:.ports:-"80:80"links:-dbdb:image:postgresports:-"5432"volumes:-/etc/postgresql-/var/log/postgresql-/var/lib/postgresql
我在YAML中定義了兩個容器:web與db;容器web生成自當前文件夾下的Dockerfile,向外暴露了80號端口,同時鏈接到了容器db。容器db生成自DockerHub的PostgreSQL鏡像,向外暴露5432號端口。使用此YAML配置文件,fig可以用以下命令生成容器,然後依照配置文件的意圖啟動它們。
$figbuild$figup-d
Fig會先啟動被鏈接的容器db,這樣容器web就不至於連不上數據庫。-d參數表示以後台運行的方式啟動容器,這樣可以保證用戶登出操作系統後,容器任然在運行。您可以登錄Fig的官方網站獲取更多的配置信息。
部署現在我們可以很容易的啟動一個Docker容器,但是怎麼在生產環境下部署Docker容器呢?如果在生產環境下安裝了Fig與Docker,我們所有要做的就是克隆之前的容器鏡像,然後用相同的fig命令來啟動容器。但是,現在的問題是如何更新線上運行的容器。
不幸的是,Fig可以非常優雅的啟動一個容器,但是它並不擅長更新並重啟服務。當然,你可以在代碼倉庫拉取程序的更新,然後重新運行以上的fig命令來達到這個目的;但是,在容器在更新代碼,重新啟動的過程中,就不能對外提供服務了。為了應對這種情況,我們使用原生的Docker命令,並引入Nginx做反向代理(注:軟負載)來解決這個問題。
我們首先把容器監聽的端口修改掉,因為Nginx需要監聽80號端口。我們這麼修改:
web:build:.ports:-"8080:80"links:-db...
通過修改Fig的配置文件,我們的web容器修改成監聽8080號端口。而Nginx要配置成8080與8081端口的負載均衡;所以Nginx的配置如下:
upstreamdocker{server127.0.0.1:8080;server127.0.0.1:8081;}server{listen80;location/{proxy_passhttp://docker;}}
重啟Nginx後,Nginx就開始在8080與8081號端口之間做反向代理(軟負載);當其中任何一個端口失效後,Nginx將請求自動轉發到另一個,直到失效後的端口恢復。這樣,我們就能從Git中拉取更新,然後運行下面的命令將其啟動:
$dockerrun-d--nameweb1--linkcodetvjournal_db_1:db-p8081:80codetvjournal_web:latest
當我們確定8081號端口的web1容器啟動並服務正常後,我們就可以停止8080號端口的服務並開始為8080號端口服務進行更新了。我推薦使用原生的docker命令而不使用Fig來完成這個工作,因為這樣可以避免干擾到正在運行的db容器(注:作者可能指的是之前寫好的YAML,裡面包含了啟動db容器的配置)
我們可以用上述方法創建很多個web容器,只要保證它們占用的端口與容器名不同即可;同時使用Nginx在它們前端做負載即可實現不掉線的程序升級。
自動化那麼問題又來了,怎麼將上述的更新流程自動化運行呢?有兩個方式可以達到:
所以,使用Docker在生產環境中部署服務不像你想象中那麼容易。我推薦大家試試上面所說的方法;同時分享你自己的實踐經驗給大家,這會幫助大家一同使用Docker。Docker還是個很年輕的產品,同時又是個非常熱門的產品,它肯定會在未來不斷的演化升級。
原文來自:https://www.codeschool.com/blog/2015/...
轉載地址:http://www.linuxprobe.com/docker-production-env.html
http://xxxxxx/Linuxjc/1134244.html TechArticle