编程 linux Windows 程序员 Firefox Android 开源 Ubuntu shell Python centos apache 微软 mysql nginx php google 云计算 java wordpress

使用容器還是使用類似Chef、Puppet這類的配置管理工具?

容器會取代你對配置管理的需求嗎?或者說兩者可以共存嗎?它們應該如何共存?本文主要對比了傳統的配置管理和現在比較火的容器管理之間的差別,並對兩者分別進行了概括,可以讓讀者初步了解兩者之間的區別,並感受到容器技術的力量。

每一個開發和運營團隊都有著或多或少相同的目標,編寫幹凈的、可維護的和高性能的代碼,盡可能在不宕機的情況下部署代碼,並為用戶帶來極速和愉悅的體驗。增加部署次數,但卻要求不宕機,這談何容易?我想實現這個目標的方法少說也有幾百個,我們需要建立一個托管平臺,這個平臺上要有大量系統管理員過去通常手工操縱的東西。

現在『平臺』這個術語有些被過度使用了,在這裏,平臺是指運行代碼的計算機以及運行的方式,具體到實際環境,平臺可能是你機櫃裏的一臺服務器,一些Shell腳本,也可能是一個公有的PaaS平臺,也可能是牛逼哄哄的AWS或者其它。
配置管理回顧
大約一年之前,理論上最好的方法是使用配置管理工具來自動化服務器基礎設施以及部署工作流,一些比較流行的工具包括:
Chef
Puppet
Salt
Ansible
CFEngine

使用配置管理工具,你需要編寫代碼來描述你希望如何安裝和配置系統的一些組件。當你在服務器上執行代碼的時候,它應該在理想狀態下結束運行。使用這種工具的好處是你可以抽象掉一些各種不同的操作系統在處理類似包管理這樣的功能時所帶來的不同。

例如,你可以寫一個bash腳本用來在UbuntuDebian上安裝libxml2:
#!/bin/bash
apt-get install -y libxml2

但是,當你在CentOS或者Fedora上使用這個腳本的時候會發生什麽呢?它可能無法正常運行,因為這些發行版使用的是不同的包管理器。

取而代之,你可以用Chef寫一個代碼塊,它可以抽象掉不同的發行版之間的差異。你可以在libxml2包存在的任何地方執行這個相同的Chef代碼,它都會正常運行。
package “libxml2” do
action :install
done

用以部署的配置管理
因為我對Chef非常熟悉並且在腦海中仍然記憶猶新,所以我將討論一下它的配置資源和我在使用時碰到的一些陷阱。Chef的配置資源基於Capsitrano,Capsitrano被視為代碼部署的最好選擇,所以我這裏所寫並非是要嘮叨它。

在你的Chef recipe代碼中,配置資源的語法其最簡單的形式看起來像這樣:
deploy 'private_repo' do
repo 'git@github.com:acctname/private-repo.git'
user 'ubuntu'
deploy_to '/tmp/private_code'
ssh_wrapper '/tmp/private_code/wrap-ssh4git.sh'
action :deploy
end

chef-client通過某種方式的循環保持單一運行時,在同一個服務器上部署多個項目的現象並不少見。

一個這樣的簡單示例如下:
%w(project1 project2).each do |project|
deploy ‘#{project}’ do
    repo 'git@github.com:acctname/#{project}-repo.git'
    user 'ubuntu'
    deploy_to '/var/www'
    ssh_wrapper '/tmp/private_code/wrap-ssh4git.sh'
    action :deploy
end
done

對於這種方式如何結束運行,存在一些問題:
如果項目1由於某種原因部署失敗,比如Git的倉庫權限問題,而你並沒有處理這樣的錯誤,接下來會導致後續的部署接連失敗。
如果你必須通過bundler、npm或者類似的工具構建部署模塊,勢必運行會非常緩慢,在某些情況下可能會花費幾分鐘甚至更長。如果模塊構建失敗,Chef會崩潰,除非你非常明智地提前考慮到這種情況。
通常情況下,從Git拉取很慢。
如果GitHub崩了,你就無法部署。如果你正在新服務器的引導過程中自動擴展和部署代碼,碰到這種情況是非常糟糕的。

圍繞這些問題有很多解決辦法,比如提前構建模塊並將其存儲在向s3這樣的對象存儲庫中,將你的recipe拉到本地解壓而不是在雲端構建他們。還有一些人將他們的GitHub倉庫映射到一個本地服務器,然後從本地服務器拉取。總體來說,我的觀點是,使用配置管理工具是非常的復雜並且很容易出錯。
容器回顧
容器是時下的新寵,但它絕不是一項新技術。從2.6.24版本開始,由於加入了cgroup的支持,Linux內核已經支持容器。谷歌已經使用了十幾年來支持他們巨大的全球性基礎設施。在過去的兩年裏,像Docker這種初創公司以及一些大型企業如紅帽、亞馬遜、谷歌和IBM在他們的主機產品中增加了對容器的支持,這已經使得容器在開發者和運維工程師中成為了最流行的話題。通過使用Linux中現有的工具如cgroups和 namespace,並且使得它們對於普通用戶來說更加簡單和方便,Docker產生了巨大影響。

容器使應用程序的跨平臺可移植性比以往任何時候都更容易,它解決了開發環境與生產環境差異的老問題。作為曾經的運維工程師,我不記得已經聽到過多少次這種聲音,“生產環境出問題了…代碼在本地運行的很好”。這就造成了開發人員編寫代碼和運維團隊部署代碼出現分歧而不是相互協作的現狀。
容器的優勢
相比配置管理系統來說,特別是談到部署的時候,容器有著明顯的優勢。
所有原本在你的cookbook、playbook、manifest等文件中的邏輯現在都寫在Dockerfile中,Dockerfile直接依附於應用的倉庫,它被設計用來構建。這就意味著,事情會更加條理並且管理Git倉庫的人也可以修改和測試應用程序的自動化。
對於開發者來說,容器或是Docker比他們絞盡腦汁去折騰本地部署要容易的多,它消除了整個團隊要理解如何使用你所選擇的、與Vagrant緊密聯系的配置管理系統的需求。
所有應用程序的依賴關系都與容器捆綁,這就意味著在部署的時候沒有必要在雲端的每臺服務器上去構建。這會使得部署和回滾更加迅速。
由於無需每次部署都從Git上拉取,這就消除了GitHub中斷的風險並且使你避免了無法部署。當然,如果你依賴 DockerHub 或其他托管鏡像註冊表,還是會有可能碰到這個問題。
容器促成標準化,這使得像集中式日誌記錄,監測和指標這樣的系統,無論容器中運行的是什麽,都能夠輕松地卡入到位。總的來說,這將對部署時的問題監測以及輕松地推行這類監控解決方案的能力產生巨大影響。

但是,仍然有些不足,對嗎?嗯…是的。
Dockerfile不會給你同配置文件一樣的控制權,因為你的應用程序在各個環境如dev、staging、production之間切換。你會遇到這種情況,你的Dockerfile必須根據環境變量調用外部腳本來編輯雲端中Docker鏡像裏的配置文件。在某些情況下,你甚至可能需要針對每個環境編寫不同的Dockerfile,如果你的應用程序沒有遵循“十二要素應用宣言”的最佳實踐,這通常會是一個問題。
關於 Docker的安全模式,有很多負面的說法,即使在運行過程中孵化出一個競爭性的容器。雖然最近有可能在容器內確認各個層的校驗和,但是從長期來看,這是不可能的。一些掌控中間層的人可能毫不費力就能汙染下層容器。

配置管理和容器可以兼容嗎?
當然可以。

即使不是全部的也有相當大的一部分流行的配置管理系統擁有針對Docker集成的hook。Chef有一種集成方案,允許你使用Chef cookbook和recipe構建Docker鏡像以及管理如何把你的容器部署到服務器上。Ansible也有完成類似目標的集成。

有些情況下,我會說:“是的,可以同時使用兩者”:

你已經使用了其中一種配置管理系統並且你想嘗試使用容器。

這將是很容易的嘗試,你可以得到一些即時的反饋,看看是否要繼續深入到更加復雜或全部功能的主機平臺。對於你的基礎設施,所有需要你真正改變的是增加Docker並將它作為應用程序的包裝,你會繼續以同樣的方式將它們部署到同一服務器。雖然這樣有些不妥,但因為使用了群集托管平臺,便可以顯著提高資源利用率,並能為你節省很多資金。 

你在部署無法輕易在容器內運行的東西。

有一些確實比較古老的軟件有時需要你去運行和管理,其中有一些不能很好地與容器兼容,使得它們自動安裝和管理的唯一方法是使用配置管理。如果你遇到了使用容器時不會遇到的嚴重的合規性要求或者要求你在特權模式下運行它們,這也會是一個潛在的問題。 
你應該同時使用兩者嗎?
理想狀況下,答案是No。隨著全棧容器管理系統的發布,在2015年,你大可不必擔心要同時使用兩者才能夠完全自動化你的基礎設施。當然,一些容器管理系統確實需要配置管理來自動化它的配置…我猜測他們可能思考地不夠透徹。

一般來說,如果你要同時使用兩者:
配置管理將只用於安裝Docker,業務流程系統,配置PAM/ ssh身份驗證和調整OS的sysctl值。基本上不涉及應用程序的部署。
Docker和你選擇的業務流程系統用來運行應用程序和特定的軟件包。

延伸阅读

    评论