Linux中國

Ansible和Docker的作用和用法

為什麼使用 Ansible

我重度使用 Chef 已經有4年了(LCTT:Chef 是與 puppet 類似的配置管理工具),基礎設施即代碼的觀念讓我覺得非常無聊。我花費大量時間來管理代碼,而不是管理基礎設施本身。不論多小的改變,都需要相當大的努力來實現它。使用 Ansible,你可以一手掌握擁有可描述性數據的基礎架構,另一隻手掌握不同組件之間的交互作用。這種更簡單的操作模式讓我把精力集中在如何將我的技術設施私有化,提高了我的工作效率。與 Unix 的模式一樣,Ansible 提供大量功能簡單的模塊,我們可以組合這些模塊,達到不同的工作要求。

除了 Python 和 SSH,Ansible 不再依賴其他軟體,在它的遠端主機上不需要部署代理,也不會留下任何運行痕迹。更厲害的是,它提供一套內建的、可擴展的模塊庫文件,通過它你可以控制所有的一切:包管理器、雲服務供應商、資料庫等等等等。

為什麼要使用 Docker

Docker 的定位是:提供最可靠、最方便的方式來部署服務。這些服務可以是 mysqld,可以是 redis,可以是 Rails 應用。先聊聊 git 吧,它的快照功能讓它可以以最有效的方式發布代碼,Docker 的處理方法與它類似。它保證應用可以無視主機環境,隨心所欲地跑起來。

一種最普遍的誤解是人們總是把 Docker 容器看成是一個虛擬機,當然,我表示理解你們的誤解。Docker 滿足單一功能原則,在一個容器裡面只跑一個進程,所以一次修改只會影響一個進程,而這些進程可以被重用。這種模型參考了 Unix 的哲學思想,當前還處於試驗階段,並且正變得越來越穩定。

設置選項

不需要離開終端,我就可以使用 Ansible 來在這些雲平台中生成實例:Amazon Web Services,Linode,Rackspace 以及 DigitalOcean。如果想要更詳細的信息,我於1分25秒內在位於阿姆斯特丹的2號數據中心上創建了一個 2GB 的 DigitalOcean 虛擬機。另外的1分50秒用於系統配置,包括設置 Docker 和其他個人選項。當我完成這些基本設定後,就可以部署我的應用了。值得一提的是這個過程中我沒有配置任何資料庫或程序開發語言,Docker 已經幫我把應用所需要的事情都安排好了。

Ansible 通過 SSH 為遠端主機發送命令。我保存在本地 ssh 代理上面的 SSH 密鑰會通過 Ansible 提供的 SSH 會話分享到遠端主機。當我把應用代碼從遠端 clone 下來,或者上傳到遠端時,我就不再需要提供 git 所需的證書了,我的 ssh 代理會幫我通過 git 主機的身份驗證程序的。

Docker 和應用的依賴性

我發現有一點挺有意思的:大部分開發者非常了解他們的應用需要什麼版本的編程語言,這些語言依賴關係有多種形式:Python 的包、Ruby 的打包系統 gems、node.js 的模塊等等,但與資料庫或消息隊列這種重要的概念相比起來,這些語言就處於很隨便的境地了——隨便給我個編程語言環境,我都能把資料庫和消息隊列系統跑起來。我認為這是 DevOps 運動(它旨在促進開發與運維團隊的和諧相處)的動機之一,開發者負責搭建應用所需要的環境。Docker 使這個任務變得簡單明了直截了當,它為現有環境加了實用的一層配置。

我的應用依賴於 MySQL 5.5和 Redis 2.8,依賴關係放在「.dockercontainerdependencies」文件裡面:

gerhard/mysql:5.5
gerhard/redis:2.8

Ansible 會查看這個文件,並且通知 Docker 載入正確的鏡像,然後在容器中啟動。它還會把這些服務容器鏈接到應用容器。如果你想知道 Docker 容器的鏈接功能是怎麼工作的,可以參考Docker 0.6.5 發布通知.

我的應用包括一個 Dockerfile,它詳細指定了 Ruby Docker 鏡像的信息,這裡面的步驟能夠保證把正確的 Ruby 版本載入到鏡像中。

FROM howareyou/ruby:2.0.0-p353

ADD ./ /terrabox

RUN 
  . /.profile ;
  rm -fr /terrabox/.git ;
  cd /terrabox ;
  bundle install --local ;
  echo '. /.profile && cd /terrabox && RAILS_ENV=test bundle exec rake db:create db:migrate && bundle exec rspec' > /test-terrabox ;
  echo '. /.profile && cd /terrabox && export RAILS_ENV=production && rake db:create db:migrate && bundle exec unicorn -c config/unicorn.rails.conf.rb' > /run-terrabox ;
# END RUN

ENTRYPOINT ["/bin/bash"]
CMD ["/run-terrabox"]

EXPOSE 3000

第一步是複製應用的所有代碼到 Docker 鏡像,載入上一個鏡像的全局環境變數。這個例子中的 Ruby Docker 鏡像會載入 PATH 配置,這個配置能確保鏡像載入正確的 Ruby 版本。

接下來,刪除 git 歷史,Docker 容器不需要它們。我安裝了所有 Ruby 的 gems,創建一個名為「/test-terrabox」的命令,這個命令會被名為「test-only」的容器執行。這個步驟的目的是能正確解決應用和它的依賴關係,讓 Docker 容器正確鏈接起來,保證在真正的應用容器啟動前能通過所有測試項目。

CMD 這個步驟是在新的 web 應用容器啟動後執行的。在測試環節結束後馬上就執行/run-terrabox命令進行編譯。

最後,Dockerfile 為應用指定了一個埠號,將容器內部埠號為3000的埠映射到主機(運行著 Docker 的機器)的一個隨機分配的埠上。當 Docker 容器裡面的應用需要響應來自外界的請求時,這個埠可用於反向代理或負載均衡。

Docker 容器內運行 Rails 應用

沒有本地 Docker 鏡像,從零開始部署一個中級規模的 Rails 應用大概需要100個 gems,進行100次整體測試,在使用2個核心實例和2GB內存的情況下,這些操作需要花費8分16秒。裝上 Ruby、MySQL 和 Redis Docker 鏡像後,部署應用花費了4分45秒。另外,如果從一個已存在的主應用鏡像編譯出一個新的 Docker 應用鏡像出來,只需花費2分23秒。綜上所述,部署一套新的 Rails 應用,解決其所有依賴關係(包括 MySQL 和 Redis),只需花我2分鐘多一點的時間就夠了。

需要指出的一點是,我的應用上運行著一套完全測試套件,跑完測試需要花費額外1分鐘時間。儘管是無意的,Docker 可以變成一套簡單的持續集成環境,當測試失敗後,Docker 會把「test-only」這個容器保留下來,用於分析出錯原因。我可以在1分鐘之內和我的客戶一起驗證新代碼,保證不同版本的應用之間是完全隔離的,同操作系統也是隔離的。傳統虛擬機啟動系統時需要花費好幾分鐘,Docker 容器只花幾秒。另外,一旦一個 Dockedr 鏡像編譯出來,並且針對我的某個版本的應用的測試都被通過,我就可以把這個鏡像提交到一個私有的 Docker Registry 上,可以被其他 Docker 主機下載下來並啟動一個新的 Docker 容器,而這不過需要幾秒鐘時間。

總結

Ansible 讓我重新看到管理基礎設施的樂趣。Docker 讓我有充分的信心能穩定處理應用部署過程中最重要的步驟——交付環節。雙劍合璧,威力無窮。

從無到有搭建一個完整的 Rails 應用可以在12分鐘內完成,這種速度放在任何場合都是令人印象深刻的。能獲得一個免費的持續集成環境,可以查看不同版本的應用之間的區別,不會影響到同主機上已經在運行的應用,這些功能強大到難以置信,讓我感到很興奮。在文章的最後,我只希望你能感受到我的興奮!

我在2014年1月倫敦 Docker 會議上講過這個主題,已經分享到 Speakerdeck了。

如果想獲得更多的關於 Ansible 和 Docker 的內容,請訂閱 changlog 周報,它會在每周六推送一周最有價值的關於這兩個主題的新聞鏈接。

如果你想為我們的 Changlog 寫一篇文章,請使用 Draft repo,他們會幫到你的。

下次見,Gerhard

via: http://thechangelog.com/ansible-docker/

作者:Gerhard Lazu 譯者:bazz2 校對:wxy

本文由 LCTT 原創翻譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國