Chef 意爲「廚房」,咱們要作「菜」,天然須要有「菜譜」。事實上在 Chef 中分發到各服務器節點的不是「菜」,而是「菜譜」,服務器本身「作菜」,本身管理本身。html
Cookbook 規定了在 Chef 中執行的操做順序,決定了應用的構建步驟。能夠從市場中尋找一個 cookbook,市場地址:https://supermarket.chef.io/cookbooks/ 使用以下命令:nginx
knife cookbook site install nginx
它會進行版本控制,在提交歷史中留下建立記錄。shell
若是不適用版本控制,則能夠使用以下命令(不推薦):bash
knife cookbook site download nginx
在老的版本中,使用 knife 來與 Chef Server 進行交互,建立一個 cookbook 的命令是這樣的:服務器
knife cookbook create first_cookbook
而在新版本中,建立的命令變爲:app
chef generate app first_cookbook
在 repo 的 cookbook 目錄下新建時,輸入以下命令:ide
chef generate first_cookbook
執行命令後,能夠看到建立的目錄:測試
. ├── Berksfile ├── chefignore ├── LICENSE ├── metadata.rb ├── README.md ├── recipes │ └── default.rb ├── spec │ ├── spec_helper.rb │ └── unit │ └── recipes │ └── default_spec.rb └── test └── smoke └── default └── default_test.rb
在新版本 Chef 中,不會自動生成全部目錄,一個 cookbook 內可能包含的目錄及做用參見文檔:https://docs.chef.io/cookbooks.htmlui
接下來,咱們建立一個部署 nginx 的 cookbook,在這裏以 tengine 爲例:版本控制
首先,修改 recipes 目錄下的以 .rb
結尾的文件,該文件記錄了節點自身進行操做的步驟。
package 'pcre-devel' do action :install end package 'openssl' do action :install end package 'openssl-devel' do action :install end
上述腳本安裝了可能缺乏的依賴包,這裏 Chef 能夠幫咱們抹除平臺差別,例如在 Ubuntu 平臺使用 apt
和在 CentOS 使用 yum
的差別。
也能夠一步安裝多個依賴包:
package %w(pcre-devel openssl openssl-devel) action :install end
這裏可能產生的問題是,在不一樣的平臺包名可能不一樣,對不一樣環境下依賴包的版本不一樣。固然,Chef 會考慮到這一點,這裏不詳細展開,能夠參閱文檔:https://docs.chef.io/resource_package.html
安裝完依賴後,就須要下載 tengine 源碼,並進行編譯操做。這一步用 shell 命令很方便,因此在 recipe 中也是能夠定義一組 shell 命令的。在文件後追加以下行:
script 'install_tengine' do interpreter 'bash' user 'root' cwd '/usr/local/src' code <<-EOH wget 'http://tengine.taobao.org/download/tengine-2.2.1.tar.gz' tar -zxvf tengine-2.2.1.tar.gz -C /usr/local/src/ cd /usr/local/src/tengine-2.2.1/ ./configure make make install chkconfig nginx on EOH end
interpreter
參數指定了要以何種 shell 去運行,user
定義執行用戶,cwd
定義執行路徑。
隨後下載解壓,進行編譯安裝。
能夠看到咱們在定義的命令中啓用了 nginx 服務:
chkconfig nginx on
這裏的問題在於,tengine 編譯後並不會生成定義服務的文件,於是須要咱們手動添加服務,即:
建立 nginx 服務文件 -> 給定權限 -> 啓用服務
因此須要添加一個固定的文件,添加到節點中。在 cookbook 內,能夠定義文件,文件中的內容通常是固定不變的。
在 script 'install_tengine' do
塊以前添加:
cookbook_file "/etc/init.d/nginx" do source "nginx" mode '0755' owner 'root' group 'root' end
以本地文件 nginx 去添加到節點服務器的 /etc/init.d/nginx 內。其它參數顧名思義,cookbook 文件、權限、全部者及組。
新建一個 files/default 文件夾,在其中創建 nginx 文件,該文件定義了 nginx 服務,會被添加至 /etc/init.d/
文件夾。nginx 文件的內容能夠本身去定義,也能夠參考以下定義(來自 http://blog.51cto.com/benpaozhe/1760999):
#!/bin/bash #writer:gaolixu #chkconfig: 345 86 16 start(){ if [ -f /var/lock/subsys/tengine.lock ];then echo "Tengine is already running: [ FAILED ]" else if /usr/local/nginx/sbin/nginx ;then echo "Starting tengine: [ OK ]" touch /var/lock/subsys/tengine.lock else echo "Starting tengine: [ FAILED ]" fi fi } stop(){ if [ -f /var/lock/subsys/tengine.lock ];then if /usr/local/nginx/sbin/nginx -s quit ;then echo "Stopping tengine: [ OK ]" rm -rf /var/lock/subsys/tengine.lock else echo "Stopping tengine: [ FAILED ]" fi else echo "Tengine not runing: [ FAILED ]" fi } reload(){ if /usr/local/nginx/sbin/nginx -s reload ;then echo "Reload tengine: [ OK ]" else echo "Reload tengine: [ FAILED ]" fi } case $1 in "start") start ;; "stop") stop ;; "restart") stop sleep 1 start ;; "reload") reload ;; "status") s=`pidof -s nginx` [ "$s" ] && echo "Tengine(nginx) pid $s running!!" || echo "Tengine(nginx) not runging!" ;; *) echo "usage: $0 start|stop|restart|reload|status" esac
如今,目錄結構應該是這樣的:
. ├── Berksfile ├── chefignore ├── files │ └── default │ └── nginx ├── LICENSE ├── metadata.rb ├── README.md ├── recipes │ └── default.rb ├── spec │ ├── spec_helper.rb │ └── unit │ └── recipes │ └── default_spec.rb └── test └── smoke └── default └── default_test.rb
當安裝完添加服務後,固然但願它啓動:
service 'nginx' do supports [:enable, :start, :status, :restart, :reload] action :start end
定義了 nginx 服務支持的命令和要執行的操做,對 service 的管理,參見:https://docs.chef.io/resource_service.html
一樣地,使用 Chef 內置的語法來管理 service,能夠消除平臺差別,而且能夠支持更多的邏輯判斷操做,對服務的管理更加靈活。
如今就簡單的完成了一個 cookbook,如今來測試一下運行結果,在 chef-repo 文件夾下運行:
chef-client --local-mode --override-runlist first_cookbook
能夠看到一堆命令輸出,如有報錯會停止!
命令結束後,驗證:
service nginx status Tengine(nginx) pid 23776 running!!
能夠看到,已經成功使用 cookbook 部署運行了 nginx。
咱們簡單的建立了一個 nginx 的 cookbook,而且在部署後實現了服務的自動啓動。可是每每在現實中會有不一樣的配置,簡單的使用默認配置固然不能知足需求。這時,cookbook 中的 template
和 attributes
就派上用場了。下篇文章會使用模板變量結合必定的邏輯,來實現多樣化的配置管理需求。
-EOF-