使用 Chef 自動化部署一個 Web 服務器

使用 Chef 自動化部署一個 Web 服務器

隨着 DevOps 的流行,愈來愈多的工做被自動化處理。在搭建大規模的 IT 架構時,須要系統管理員夜以繼日地安裝配置服務器、調整各類參數等工做,直到Chef 的出現,將系統管理員從這種水深火熱的工做中解脫了出來,他們只須要編寫 Chef 腳本,描述出服務器所須要保持的狀態,而後運行腳本,服務器就配置好了。本文以配置一個 Web 服務器爲例,對 Chef 的概念和工做流程作一簡單介紹。html

王 羣鋒, 軟件工程師,  IBM程序員

2015 年 6 月 23 日web

  • expand內容數據庫

在 IBM Bluemix 雲平臺上開發並部署您的下一個應用。bootstrap

「這是一個最好的時代,也是一個最壞的時代。他們都在直奔天堂,而咱們都在直奔相反的方向。」緩存

90 後霸道總裁」 的超級課程表融資千萬美圓、WhatsApp 被 Facebook 以 190 億美圓收購……這個時代彷彿處處都充滿了機會。如今假設咱們也決定放棄朝九晚五的工做,要開發出一款 Web 應用改變這個世界,順便當上總經理、出任 CEO、贏取白富美、走向人生巔峯。七拼八湊,咱們的應用作出來了。它的架構很是簡單,若是非要描述的話,它的架構如圖 1 所示:服務器

圖 1. 應用架構

應用架構

這麼簡單的應用,咱們上網瀏覽一下資料,隨便租個服務器,安裝一個 Web 服務器,配置一下,應用順利上線。架構

幸福老是來得太快,很快咱們的應用就火了。隨着訪問量的增大,咱們須要單獨的數據庫服務器,一個都不夠,得來倆;應用服務器也不夠用了,再多添幾臺,上一個負載均衡;對數據庫的訪問又成了性能瓶頸,增長些數據庫緩存吧,最終,應用的架構變成了以下的樣子:

圖 2.    演進的應用架構

演進的應用架構

如今問題來了,面對如此複雜的架構,怎麼安裝和配置這些服務呢?Chef 就是用來解決這個問題的。

第一份「菜譜」(recipe)

讓咱們暫且就此打住,先來看看怎麼使用 Chef。首先須要在一臺 Linux 機器上安裝Chef Development Kit。若是您實在找不到一臺 Linux 機器也沒有關係,可以使用一個用於教學用途的在線虛擬機,該虛擬機上已經預裝了 Chef Development Kit,能夠直接使用。

Recipe 是 Chef 中主要執行任務的地方,翻譯成中文是「菜譜」的意思。咱們的第一份「菜譜」的主要功能是使用 Chef 生成一個文本文件,其內容爲:Hello Chef。讓咱們先新建一個 chef-repo 目錄,用來存放「菜譜」,而後在該目錄下建立第一個「菜譜」:hello.rb,其內容以下:

清單 1. hello.rb
file 'motd' do
content 'Hello Chef’
end

在命令行中執行:chef-appy hello.rb,輸出以下:

圖 3. 輸出

輸出

可 以看到,命令執行後生成 motd 文件,該文件的內容爲字符串:Hello Chef。這就是咱們的第一份「菜譜」,雖然簡單,可是卻歸納了 Chef 的基本工做原理:使用一個 Ruby 文件,即「菜譜」描述服務器應有的狀態,而後執行 Chef 命令配置服務器。

您可嘗試再次執行 chef-appy hello.rb,Chef 會檢測到 motd 文件已經存在,且文件內容和「菜譜」中所描述的一致,所以不進行任何操做;您還可嘗試手動刪除 motd 文件,再次執行 chef-appy hello.rb 後,又從新生成了 motd 文件。這正是配置服務器所須要的,每次配置都能保證狀態一致。

固然,咱們的第一份「菜譜」只是一道開胃小菜,下面咱們看看如何使用 Chef 部署一個 Web 服務器。

部署 Web 服務器

部署一個 Web 服務器比生成一個文件複雜,但道理倒是相同的,讓咱們先來看看代碼:

清單 2. webserver.rb
package 'httpd'
service 'httpd' do
    action [:start, :enable]
end

file '/var/www/html/index.html' do
  content '<html>
  <body>
    <h1>hello world</h1>
  </body>
</html>'
end

service 'iptables' do
  action :stop
end

這段代碼總共分紅四部分:第一部分安裝 Apache HTTP Server;第二部分啓動 HTTP 服務;第三部分生成主頁面;第四部分停用 iptables 服務,這一步主要是由於有些 Linux 安裝後,默認只打開 22 端口,其餘端口是被禁止的,停用 iptables 服務後,就能夠順利訪問 80 端口了,即 HTTP 協議所使用的端口。聰明的您朋友們,您能將這四部分和代碼對應起來嗎?

這裏要注意的是,這四部分的順序很是重要,必須先安裝 Apache HTTP Server,而後啓動它,這一點也不難想象,咱們手動配置服務器時不也如此嗎?

將 文件保存後,讓咱們再來運行 sudo chef-appy webserver.rb,由於腳本里包含安裝軟件包的操做,因此須要 root 權限,若是您不是以 root 帳號登陸(相信您不會真的這樣作吧?),務必在命令行前加 sudo,不然,Chef 會報錯。若是獲得相似下面的輸出,就證實服務器配置成功,打開瀏覽器,輸入http://localhost,能夠看到剛纔定製的主頁了吧?

圖 4. 輸出

輸出

然 而,做爲有「潔癖」的程序員,不難發現「菜譜」的第二部分好像混入了什麼奇怪的東西:一段 HTML 代碼。這段 HTML 代碼明顯和其餘部分不協調,若是網頁再變得複雜點,這份「菜譜」會變得很難管理。所以,咱們得想點什麼辦法,管理「菜譜」。方法就是「烹飪手冊」 (cookbook)。

「烹飪手冊」(cookbook)

和真實的烹飪同樣,「烹飪手冊」是用來組織「菜譜」的,在「烹飪手冊」裏,不光能夠定義各類「菜譜」,也能夠定義一些屬性文件或模板,這些屬性文件或模板能夠在「菜譜」裏直接引用。在實際工做中,咱們每每使用的也是「烹飪手冊」,而不是一個個單獨的「菜譜」。

讓咱們在當前目錄下新建一個文件夾 cookbooks,而後切換到該目錄,調用 chef generate cookbook learn_chef_httpd 會自動爲咱們生成一個「烹飪手冊」。「烹飪手冊」的目錄結構以下:

圖 5. 「烹飪手冊」目錄結構

「烹飪手冊」目錄結構

其中 recipes 目錄下的 default.rb 是默認的「菜譜」,讓咱們將其中內容替換爲以前編寫的「菜譜」。

現 在咱們要將原來「菜譜」中的 HTML 代碼移到一個外部文件中,使用 chef generate template learn_chef_httpd index.html 命令生成模板文件 index.html.erb,該文件被放置在 learn_chef_httpd/templates/default 目錄下。而後將該文件內容替換爲以前的 HTML,修改 default.rb,引用該模板,最終的「菜譜」變成了下面這個樣子:

清單 3. default.rb
package 'httpd'

service 'httpd' do
    action [:start, :enable]
end

template '/var/www/html/index.html' do
  source 'index.html.erb'
end

service 'iptables' do
  action :stop
end

在命令中執行 sudo chef-client --local-mode –runlist ‘recipe[learn_chef_httpd]’ ,打開瀏覽器,訪問http://localhost ,若是能正常訪問,那麼恭喜您完成了本身的第一個「烹飪手冊」!

真實環境下的 Chef

上 面的例子只是爲了展現如何編寫「菜譜」和「烹飪手冊」,真實環境下的 Chef 卻不是這樣工做的。在真實環境下,系統管理員在一臺電腦上編寫 Chef 腳本,而後使用上述方式調試,調試成功後,將腳本上傳至 Chef 服務器,咱們從控制檯向 Chef 服務器發命令,Chef 服務器會將配置下發到各個待配置服務器,在每一個服務器上運行 Chef,完成對服務器的配置。

圖 6.    Chef 原理

Chef 原理

爲此,咱們需作三點準備:一臺用於編寫 Chef 腳本的電腦、一臺 Chef 服務器、不少待配置的服務器。咱們已經有了一臺能夠編寫 Chef 腳本的電腦,爲了方便學習,Chef 服務器能夠選用Chef 官網提供的託管服務,另外須要幾臺待配置的服務器,記得不要在服務器上安裝 Chef,當咱們配置這些服務器時,Chef 會自動在上面安裝所需的工具。

註冊成功 Chef 的託管服務後,先建立一個組織,而後下載與之對應的 Starter Kit,解壓到當前目錄,該工具是用來作認證的,有了它,才能夠從本地鏈接 Chef    服務器。如今讓咱們刪除之前建立的「烹飪手冊」,轉而從 Chef 超市上 下載一個現成的手冊。Chef 超市是一個開發者交流「烹飪手冊」的地方,由於配置服務器的不少操做都是通用的,因此人們把這些配置作成手冊,放在一個地方,你們都能使用。咱們編寫 Chef 腳本,每每也是先上 Chef 超市去看看有沒有可用的手冊,若是有,直接拿過來,或者在此基礎上修改一下就能用,若是沒有,再考慮編寫本身的手冊。使用以下命令下載前面配置 Web 服務器的手冊:

knife cookbook site download learn_chef_httpd

將下載後的手冊解壓到 cookbooks 目錄,刪除壓縮包:

tar -zxvf learn_chef_httpd-0.1.0.tar.gz -C cookbooks
rm learn_chef_httpd*.tar.gz

接下來將該手冊上傳至 Chef 服務器,即咱們剛纔註冊的 Chef 託管服務:

knife cookbook upload learn_chef_httpd

打 開託管服務控制檯,在 Policy 選項卡下就能看見剛剛上傳成功的「烹飪手冊」。接下來咱們要作的工做是告訴 Chef 服務器來幫咱們讓服務器自舉,這一步會經過 SSH 登陸到待配置的服務器,下載並安裝 Chef,而後下載執行剛剛上傳到 Chef 服務器上的「烹飪手冊」。該操做只在第一次配置服務器時須要,自舉成功後,之後就再不須要自舉了:

knife bootstrap `address` --ssh-user `user` --ssh-password '`password`' \
--sudo --use-sudo-password --node-name node1 \
--run-list 'recipe[learn_chef_httpd]'

將其中的`address`、`user`、`password`替換爲待配置服務器的真實地址、用戶名和密碼。打開瀏覽器,輸入服務器地址,看看是否能訪問定製的主頁?

獲取服務器信息

Chef 不光能夠管理服務器,同時服務器將本身的信息上傳至 Chef 服務器。使用以下命令查看當前組織裏被管理的服務器:

knife node list

使用以下命令查看服務器信息,包括服務器的 IP 地址、機器名、操做系統等信息:

knife node show node1

有了這些信息後,咱們能夠從新修改模板,讓其顯示給定服務器的信息:

清單 4. index.html.erb
<html>
<body>
<h1>hello from <%= node['fqdn'] %></h1>
</body>
</html>

再將「烹飪手冊」上傳至 Chef 服務器,而後使用以下命令配置服務器:

knife ssh `address` 'sudo chef-client' --manual-list \
--ssh-user `user` --ssh-password '`password`'

同理,將`address`、`user`、`password`替換爲待配置服務器的真實地址、用戶名和密碼。打開瀏覽器,輸入服務器地址,看看改動是否生效?

只要一臺服務器配置成功,咱們即可以用一樣的方法配置幾十臺、上百臺。並且一旦配置發生變化,咱們只需修改腳本,全部服務器即可以得到相同的更新,這個時候,Chef 的威力就顯示出來了。

chef 仍是 knife?

細 心的您可能會注意到,上面的命令,一些是 chef *****,一些倒是 knife *****。初次接觸 Chef,很容易被這些命令搞混。這裏有一個簡單的規則:本地執行的命令以 chef 打頭,須要遠程鏈接到 Chef 服務器或待配置服務器的命令以 knife 打頭。

最後,讓咱們再複習一遍本文中所使用到的命令:

  1. 運行「菜譜」

    chef-appy hello.rb
  2. 使用 Chef 生成「烹飪手冊」

    chef generate cookbook learn_chef_httpd
  3. 使用 Chef 生成模板

    chef generate template learn_chef_httpd index.html
  4. 使用 Chef 運行「烹飪手冊」

    chef-client --local-mode –runlist ‘recipe[learn_chef_httpd]’
  5. 從 Chef 超市下載「烹飪手冊」

    knife cookbook site download learn_chef_httpd
  6. 向 Chef 服務器上傳「烹飪手冊」

    knife cookbook upload learn_chef_httpd
  7. 服務器自舉

    knife bootstrap `address` --ssh-user `user` --ssh-password '`password`' \
    --sudo --use-sudo-password --node-name node1 \
    --run-list 'recipe[learn_chef_httpd]'
  8. 獲取當前組織下的服務器列表

    knife node list
  9. 顯示服務器信息

    knife node show node1
  10. 使用 Chef 遠程運行「烹飪手冊」,配置服務器

    knife ssh `address` 'sudo chef-client' --manual-list \
     --ssh-user `user` --ssh-password '`password`'

結束語

隨 着雲計算和 DevOps 技術的發展,有人斷言系統管理員和 DBA 會面臨失業,將來的雲計算公司和數據庫公司只會僱傭少數系統管理員和 DBA 管理他們的 IT 基礎設施和數據庫。雖然做者不大同意「機器替代人工」這一觀點,但提前下手,學點東西總不是壞事,所謂技多不壓身嘛。

Chef 可以實現服務器配置的自動化,在 DevOps 運動中佔有重要的位置。本文經過一個配置 Web 服務器的例子,一步步引導你們如何使用 Chef。但願您讀完本文,能編寫出本身的第一個「烹飪手冊」。

相關文章
相關標籤/搜索