Chef 快速指南



Chef - 概述

Chef 是一款由 Opscode 開發的開源技術。Opscode 的聯合創始人 Adam Jacob 被稱為 Chef 的創始人。這項技術使用 Ruby 編碼來開發基本構建塊,如菜譜和 cookbook。Chef 用於基礎設施自動化,有助於減少基礎設施管理的手動和重複性任務。

Chef 為不同的構建塊制定了自己的約定,這些構建塊是管理和自動化基礎設施所必需的。

為什麼選擇 Chef?

Chef 是一種配置管理技術,用於自動化基礎設施供應。它基於 Ruby DSL 語言開發。它用於簡化配置和管理公司伺服器的任務。它能夠與任何雲技術整合。

在 DevOps 中,我們使用 Chef 在內部和雲端部署和管理伺服器和應用程式。

Chef 的特性

以下是 Chef 最突出的特性:

  • Chef 使用流行的 Ruby 語言來建立領域特定語言。

  • Chef 不會對節點的當前狀態做出假設。它使用其機制來獲取機器的當前狀態。

  • Chef 非常適合部署和管理雲伺服器、儲存和軟體。

Chef 的優勢

Chef 提供以下優勢:

  • 較低的入門門檻 - 由於 Chef 使用原生 Ruby 語言進行配置,這是一種標準的配置語言,因此任何具有一定開發經驗的人都可以輕鬆上手。

  • 與雲的出色整合 - 使用 knife 實用程式,它可以輕鬆地與任何雲技術整合。對於希望在其多雲環境中分發其基礎設施的組織來說,它是最佳工具。

Chef 的劣勢

Chef 的一些主要缺點如下:

  • Chef 的一個巨大缺點是 cookbook 的控制方式。它需要持續的維護,以便正在工作的人不會弄亂其他人的 cookbook。

  • 只有 Chef solo 可用。

  • 在當前情況下,它僅適合 AWS 雲。

  • 如果使用者不熟悉 Ruby,那麼學習起來並不容易。

  • 文件仍然不足。

Chef 的關鍵構建塊

菜譜(Recipe)

它可以定義為用於管理基礎設施的一組屬性。菜譜中存在的這些屬性用於更改現有狀態或設定特定基礎設施節點。它們在 Chef 客戶端執行期間載入,並與節點(機器)的現有屬性進行比較。然後它進入菜譜的節點資源中定義的狀態。它是 cookbook 的主要工作負載。

Cookbook

Cookbook 是菜譜的集合。它們是上傳到 Chef 伺服器的基本構建塊。當 Chef 執行時,它確保其中存在的菜譜將給定的基礎設施設定為菜譜中列出的所需狀態。

資源

它是菜譜的基本組成部分,用於使用不同型別的狀態管理基礎設施。一個菜譜中可以有多個資源,這將有助於配置和管理基礎設施。例如:

  • package - 管理節點上的包

  • service - 管理節點上的服務

  • user - 管理節點上的使用者

  • group - 管理組

  • template - 使用嵌入式 Ruby 模板管理檔案

  • cookbook_file - 將檔案從 cookbook 中的 files 子目錄傳輸到節點上的某個位置

  • file - 管理節點上檔案的內容

  • directory - 管理節點上的目錄

  • execute - 在節點上執行命令

  • cron - 編輯節點上現有的 cron 檔案

屬性

它們基本上是設定。可以將它們視為任何想要在 cookbook 中使用的鍵值對。可以應用幾種不同型別的屬性,並在節點執行的最終設定上具有不同的優先順序。

檔案

它是 cookbook 中的一個子目錄,包含將放置在使用 cookbook 的節點上的任何靜態檔案。然後,可以將菜譜宣告為將檔案從該目錄移動到最終節點的資源。

模板

它們類似於檔案,但不是靜態的。模板檔案以 .ebr 副檔名結尾,這意味著它們包含嵌入式 Ruby。它們主要用於將屬性值替換到檔案中,以建立將放置在節點上的最終檔案版本。

Metadata.rb

它用於管理有關包的元資料。這包括包的名稱和詳細資訊等細節。它還包括依賴資訊等內容,這些資訊告訴此 cookbook 需要哪些 cookbook 才能執行。這允許 Chef 伺服器正確構建節點的執行列表,並確保所有部分都正確傳輸。

預設 Cookbook 結構

C:\chef\cookbooks\nginx>tree 
Folder PATH listing for volume Local Disk 
Volume serial number is BE8B-6427 
C: ├───attributes 
├───definitions 
├───files 
│   └───default 
├───libraries 
├───providers 
├───recipes 
├───resources 
└───templates 
    └───default 

Chef - 相關技術

以下是 Chef 相關技術的列表。

Puppet

Puppet 提供了一種標準的方式來交付和操作軟體,無論它在哪裡執行。它是一個用於 Linux、Unix 和 Windows 系統的自動化管理引擎,它根據集中式規範執行管理任務。

Puppet 的主要特性如下:

  • 使用統一的配置實現新系統。
  • 更新系統並升級安全性和軟體包。
  • 整合新功能並新增靈巧的功能。
  • 自定義配置以確保資料來源的可用性。
  • 最佳化可用資源並最大程度地降低成本。
  • 簡化角色並使團隊能夠專注於核心和生產性問題。
  • 全面瞭解可用基礎設施。

Ansible

Ansible 是一個非常簡單的 IT 自動化平臺,使您的應用程式和系統更容易部署。避免編寫指令碼來部署和更新您的應用程式 - 使用接近純英語的語言進行自動化,使用 SSH,無需在遠端系統上安裝代理。

Ansible 的主要特性如下:

  • 簡單易學
  • 用 Python 編寫
  • 無代理
  • 基於 YAML 的 Playbook
  • Ansible galaxy

SaltStack

SaltStack 用於資料驅動的配置。它是一種基於動態通訊匯流排構建的基礎設施管理新方法。它用於資料驅動的編排、任何基礎設施的遠端執行以及任何應用程式堆疊的配置管理。

Fabric

Fabric 是一種基於 Python 的程式語言,它被開發為 Python 的 API,需要在 Python 程式碼中匯入才能配置和管理基礎設施。

Chef - 架構

Chef 採用三層客戶端伺服器模型,其中工作單元(如 cookbook)在 Chef 工作站上開發。從命令列實用程式(如 knife)將它們上傳到 Chef 伺服器,並且架構中存在的所有節點都註冊到 Chef 伺服器。

Chef Server

為了使 Chef 基礎設施正常工作,我們需要按順序設定多項內容。

在上述設定中,我們有以下元件。

Chef 工作站

這是開發所有配置的位置。Chef 工作站安裝在本地機器上。詳細的配置結構將在本教程的後續章節中討論。

Chef 伺服器

它充當 Chef 設定的集中式工作單元,開發後所有配置檔案都上傳到此處。Chef 伺服器有多種型別,一些是託管的 Chef 伺服器,而另一些是內部部署的。

Chef 節點

它們是要由 Chef 伺服器管理的實際機器。根據需要,所有節點都可以具有不同型別的設定。Chef 客戶端是所有節點的關鍵元件,它有助於建立 Chef 伺服器和 Chef 節點之間的通訊。Chef 節點的另一個元件是 Ohai,它有助於在給定時間點獲取任何節點的當前狀態。

Chef - 版本控制系統設定

使用版本控制系統是基礎設施自動化的基本部分。有多種型別的版本控制系統,例如 SVN、CVS 和 GIT。由於 GIT 在 Chef 社群中很受歡迎,因此我們將使用 GIT 設定。

注意 - 不要在沒有版本控制系統的情況下考慮將基礎設施構建為程式碼。

在 Windows 上

步驟 1 - 從www.git-scm.org下載 Windows 安裝程式,並按照安裝步驟進行操作。

步驟 2 - 在 GitHub 上註冊一箇中央儲存庫。

步驟 3 - 將 ssh 金鑰上傳到 GitHub 帳戶,以便可以輕鬆地與之互動。有關 ssh 金鑰的詳細資訊,請訪問以下連結https://help.github.com/articles/generatingssh-keys

步驟 4 - 最後,透過訪問https://github.com/new並使用 chef-repo 作為名稱,在 github 帳戶上建立一個儲存庫。

在實際開始編寫 cookbook 之前,可以在開發盒上設定一個初始 GIT 儲存庫,並克隆 Opscode 提供的空儲存庫。

步驟 1 - 下載 Opscode Chef 儲存庫的空結構。

$ wget https://github.com/opscode/chef-repo/tarball/master

步驟 2 - 解壓縮 tar 包。

$ tar –xvf master

步驟 3 - 重新命名目錄。

$ mv opscode-chef-repo-2c42c6a/ chef-repo

步驟 4 - 將當前工作目錄更改為 chef 儲存庫。

$ cd chef-repo 

步驟 5 - 初始化一個新的 get 儲存庫。

$ git init. 

步驟 6 - 連線到 GitHub 上的儲存庫。

$ git remote add origin git@github.com:vipin022/chef- 

步驟 7 - 將本地儲存庫推送到 GitHub。

$ git add. 
$ git commit –m “empty repo structure added” 
$ git push –u origin maste

透過上述過程,您將獲得一個就緒的空 chef 儲存庫。然後,您可以開始開發菜譜和 cookbook。完成後,您可以將更改推送到 GitHub。

Chef - 工作站設定

Chef 遵循客戶端-伺服器架構的概念,因此為了開始使用 Chef,需要在工作站上設定 Chef 並本地開發配置。稍後可以將其上傳到 Chef 伺服器,以使其在需要配置的 Chef 節點上執行。

Opscode 提供了一個完全打包的版本,該版本沒有任何外部先決條件。這個完全打包的 Chef 稱為omnibus 安裝程式

在 Windows 機器上

步驟 1 - 在機器上下載 chefDK 的安裝程式 .msi 檔案。

步驟 2 - 按照安裝步驟,將其安裝到目標位置。

安裝程式將如下面的螢幕截圖所示。

Window Setup

ChefDK 路徑變數

$ echo $PATH 
/c/opscode/chef/bin:/c/opscode/chefdk/bin: 

在 Linux 機器上

為了在 Linux 機器上進行設定,我們需要首先在機器上安裝 curl。

步驟 1 − 一旦 curl 安裝到機器上,我們需要使用 Opscode 的 omnibus Chef 安裝程式在工作站上安裝 Chef。

$ curl –L https://www.opscode.com/chef/install.sh | sudo bash 

步驟 2 − 在機器上安裝 Ruby。

步驟 3 − 將 Ruby 新增到路徑變數中。

$ echo ‘export PATH = ”/opt/chef/embedded/bin:$PATH”’ ≫ ~/.bash_profile && 
source ~/.bash_profile 

Omnibus Chef 會將 Ruby 和所有必需的 Ruby gem 安裝到 /opt/chef/embedded 中,方法是將 /opt/chef/embedded/bin 目錄新增到 .bash_profile 檔案中。

如果 Ruby 已經安裝,則透過執行以下命令在機器上安裝 Chef Ruby gem。

$ gem install chef 

Chef - 客戶端設定

為了使 Chef 節點與 Chef 伺服器通訊,您需要在節點上設定 Chef 客戶端。

Chef 客戶端

這是 Chef 節點的重要組成部分之一,它從 Chef 伺服器檢索 cookbook 並將其在節點上執行。它也稱為 Chef 預配置器。

這裡,我們將使用 Vagrant 來管理虛擬機器。Vagrant 也可以配置為使用預配置器(如 Shell 指令碼、Chef 和 Puppet)將虛擬機器置於所需狀態。在我們的例子中,我們將使用 Vagrant 透過 VirtualBox 管理虛擬機器,並使用 Chef 客戶端作為預配置器。

步驟 1 − 從 https://www.virtualbox.org/wiki/downlod 下載並安裝 VirtualBox

步驟 2 − 從 http://downloads.vagrantup.com 下載並安裝 Vagrant

步驟 3 − 安裝 Vagrant Omnibus 外掛以使 Vagrant 能夠在虛擬機器上安裝 Chef 客戶端。

$ vagrant plugin install vagrant-omnibus 

建立和啟動虛擬機器

步驟 1 − 我們可以從 Opscode vagrant 倉庫下載所需的 Vagrant box。從以下 URL 下載 opscode-ubuntu-12.04 box:https://opscode-vmbento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box

步驟 2 − 獲取 Vagrant 檔案後,下載路徑需要編輯 Vagrant 檔案。

vipin@laptop:~/chef-repo $ subl Vagrantfile 
Vagrant.configure("2") do |config| 
   config.vm.box = "opscode-ubuntu-12.04" 
   config.vm.box_url = https://opscode-vm-bento.s3.amazonaws.com/ 
   vagrant/opscode_ubuntu-12.04_provisionerless.box 
   config.omnibus.chef_version = :latest  
   config.vm.provision :chef_client do |chef| 
      chef.provisioning_path = "/etc/chef" 
      chef.chef_server_url = "https://api.opscode.com/ 
      organizations/<YOUR_ORG>" 
      chef.validation_key_path = "/.chef/<YOUR_ORG>-validator.pem"
      chef.validation_client_name = "<YOUR_ORG>-validator" 
      chef.node_name = "server" 
   end 
end 

在上述程式中,您需要將 <YOUR_ORG> 名稱更新為正確的或所需的組織名稱。

步驟 3 − 配置後的下一步是啟動 vagrant box。為此,您需要移動到 Vagrant box 所在的位置並執行以下命令。

$ vagrant up

步驟 4 − 機器啟動後,您可以使用以下命令登入機器。

$ vagrant ssh

在上述命令中,vagrantfile 使用 Ruby 領域特定語言 (DSL) 編寫,用於配置 vagrant 虛擬機器。

在 vagrant 檔案中,我們有 config 物件。Vagrant 將使用此 config 物件來配置虛擬機器。

Vagrant.configure("2") do |config| 
……. 
End

在 config 塊內,您將告訴 vagrant 使用哪個虛擬機器映像來啟動節點。

config.vm.box = "opscode-ubuntu-12.04" 
config.vm.box_url = https://opscode-vm-bento.s3.amazonaws.com/ 
   vagrant/opscode_ubuntu-12.04_provisionerless.box

在下一步中,您將告訴 Vagrant 下載 omnibus 外掛。

config.omnibus.chef_version = :latest

選擇要啟動的虛擬機器 box 後,配置如何使用 Chef 預配置 box。

config.vm.provision :chef_client do |chef| 
….. 
End 

在其中,您需要設定有關如何將虛擬節點連線到 Chef 伺服器的說明。您需要告訴 Vagrant 在節點上儲存所有 Chef 內容的位置。

chef.provisioning_path = "/etc/chef" 

Chef - 測試廚房設定

Test Kitchen 是 Chef 整合的測試框架。它允許編寫測試配方,這些配方將在虛擬機器例項化並使用 cookbook 收斂後在虛擬機器上執行。測試配方在該虛擬機器上執行,並可以驗證所有內容是否按預期工作。

ChefSpec 只模擬 Chef 執行。Test Kitchen 啟動真實的節點並在其上執行 Chef。

步驟 1 − 安裝 test kitchen Ruby gem 和 test kitchen vagrant gem 以使 test kitchen 能夠使用 vagrant 啟動測試。

$ gem install kitchen 
$ gem install kitchen-vagrant 

步驟 2 − 設定 test kitchen。這可以透過在 cookbook 目錄中建立 .kitchen.yml 來完成。

driver_plugin: vagrant 
driver_config: 
   require_chef_omnibus: true 
platforms: 
   - name: ubuntu-12.04 
   driver_config: 
      box: opscode-ubuntu-12.04 
      box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ 
      ubuntu-12.04_provisionerless.box 
suites: 
   - name: default 
run_list: 
   - recipe[minitest-handler] 
   - recipe[my_cookbook_test] 
attributes: { my_cookbook: { greeting: 'Ohai, Minitest!'} } 

在上述程式碼中,一部分定義了 vagrant 需要啟動虛擬機器,並定義了希望 Omnibus 在目標節點上安裝 Chef。

第二部分定義了要測試 cookbook 的平臺。Vagrant 將始終建立和銷燬新例項。您無需擔心使用 Vagrantfile 啟動的 vagrant 虛擬機器的副作用。

Test Kitchen 可以被認為是一個臨時環境,有助於在類似於生產的臨時環境中執行和測試 cookbook。使用 test kitchen,可以在將程式碼實際部署到測試、預生產和生產環境之前確保給定程式碼段正常工作。許多組織在將 cookbook 放入實際工作環境之前都會遵循 test kitchen 的此功能。

Test Kitchen 工作流

以下是 Test Kitchen 工作流中涉及的步驟。

Kitchen Workflow

使用 Chef 建立 Cookbook

使用以下程式碼建立 cookbook。

$ chef generate cookbook motd_rhel 
Installing Cookbook Gems: 

Compiling Cookbooks... 
Recipe: code_generator::cookbook
   * directory[C:/chef/cookbooks/motd_rhel] action create
      - create new directory C:/chef/cookbooks/motd_rhel
   
   * template[C:/chef/cookbooks/motd_rhel/metadata.rb] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/metadata.rb
      - update content in file C:/chef/cookbooks/motd_rhel/metadata.rb from none to 
      d6fcc2 (diff output suppressed by config)
   
   * template[C:/chef/cookbooks/motd_rhel/README.md] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/README.md
      - update content in file C:/chef/cookbooks/motd_rhel/README.md from none to 50deab
         (diff output suppressed by config)
   
   * cookbook_file[C:/chef/cookbooks/motd_rhel/chefignore] action create
      - create new file C:/chef/cookbooks/motd_rhel/chefignore
      - update content in file C:/chef/cookbooks/motd_rhel/chefignore from none to 15fac5
         (diff output suppressed by config)
   
   * cookbook_file[C:/chef/cookbooks/motd_rhel/Berksfile] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/Berksfile
      - update content in file C:/chef/cookbooks/motd_rhel/Berksfile from none to 9f08dc
         (diff output suppressed by config)
   
   * template[C:/chef/cookbooks/motd_rhel/.kitchen.yml] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/.kitchen.yml
      - update content in file C:/chef/cookbooks/motd_rhel/.kitchen.yml
         from none to 49b92b (diff output suppressed by config)
   
   * directory[C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec]
      action create 
      - create new directory 
         C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec
   
   * directory[C:/chef/cookbooks/motd_rhel/test/integration/helpers/serverspec]
      action create 
      - create new directory 
         C:/chef/cookbooks/motd_rhel/test/integration/helpers/serverspec
   
   * cookbook_file
      [C:/chef/cookbooks/motd_rhel/test/integration/helpers/serverspec/spec_helper.rb]
      action create_if_missing
      - create new file 
         C:/chef/cookbooks/motd_rhel/test/integration/helpers/serverspec/spec_helper.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/test/integration/helpers/serverspec/spec_helper.rb
            from none to d85df4 (diff output suppressed by config)
   
   * template
      [C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec/defaul t_spec.rb]
      action create_if_missing
      - create new file
         C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec/default_spec.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec/default_spec.rb
            from none to 3fbdbd (diff output suppressed by config)
   
   * directory[C:/chef/cookbooks/motd_rhel/spec/unit/recipes] action create
      - create new directory C:/chef/cookbooks/motd_rhel/spec/unit/recipes
   
   * cookbook_file
      [C:/chef/cookbooks/motd_rhel/spec/spec_helper.rb] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/spec/spec_helper.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/spec/spec_helper.rb from none to 587075
            (diff output suppressed by config)
   
   * template
      [C:/chef/cookbooks/motd_rhel/spec/unit/recipes/default_spec.rb]
      action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/spec/unit/recipes/default_spec.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/spec/unit/recipes/default_spec.rb
            from none to ff3b17 (diff output suppressed by config)
   
   * directory[C:/chef/cookbooks/motd_rhel/recipes] action create
      - create new directory C:/chef/cookbooks/motd_rhel/recipes
   
   * template[C:/chef/cookbooks/motd_rhel/recipes/default.rb] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/recipes/default.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/recipes/default.rb from none to c4b029
            (diff output suppressed by config) 
   
   * execute[initialize-git] action run 
      - execute git init . 
   
   * cookbook_file[C:/chef/cookbooks/motd_rhel/.gitignore] action create
      - create new file C:/chef/cookbooks/motd_rhel/.gitignore
      - update content in file C:/chef/cookbooks/motd_rhel/.gitignore from none to 33d469
         (diff output suppressed by config)
   
   * execute[git-add-new-files] action run
      - execute git add .
   
   * execute[git-commit-new-files] action run 
      - execute git commit -m "Add generated cookbook content" 

以下是上述程式碼輸出的已建立 Cookbook 結構。

Structure

Test Kitchen 配置檔案

.kitchen.yaml 檔案

driver: 
   name: vagrant 
provisioner: 
   name: chef_zero 
# verifier: 
# name: inspec 
# format: doc 
platforms: 
   - name: ubuntu-14.04 
suites: 
   - name: default 
   run_list: 
      - recipe[motd_rhel::default] 
   attributes: 

驅動程式 − 指定管理機器的軟體。

預配置器 − 提供有關 Chef 如何執行的規範。我們使用 chef_zero,因為它允許在本地機器上模擬 Chef 伺服器環境。這允許使用節點屬性和 Chef 伺服器規範。

平臺 − 指定目標作業系統。

套件 − 定義想要在虛擬環境中應用的內容。在這裡,您定義多個定義。它是在您定義執行列表的位置,該執行列表指定要執行哪個配方以及需要按什麼順序執行。

按順序執行命令

Kitchen List

$ kitchen list 
Instance  Driver  Provisioner Verifier   Transport Last Action 
ubuntu-1404 Vagrant ChefZero   Busser       Ssh   <Not Created> 

Kitchen Create

$ kitchen create
-----> Starting Kitchen (v1.4.2)
-----> Creating <default-centos-72>...
      Bringing machine 'default' up with 'virtualbox' provider...
      ==> default: Box 'opscode-centos-7.2' could not be found.
         Attempting to find and install...
      default: Box Provider: virtualbox
      default: Box Version: >= 0
      ==> default: Box file was not detected as metadata. Adding it directly...
         ==> default: Adding box 'opscode-centos-7.2' (v0) for provider: virtualbox
         default: Downloading:
            https://opscode-vmbento.s3.amazonaws.com/vagrant/virtualbox/
            opscode_centos-7.1_chefprovisionerless.box[...]
         Vagrant instance <default-centos-72> created.
         Finished creating <default-centos-72> (3m12.01s).
         -----> Kitchen is finished. (3m12.60s)

Kitchen Converge

$ kitchen converge 
-----> Converging <default-centos-72>...        
      Preparing files for transfer        
      Preparing dna.json        
      Resolving cookbook dependencies with Berkshelf 4.0.1...
      Removing non-cookbook files before transfer       
      Preparing validation.pem        
      Preparing client.rb 
-----> Chef Omnibus   installation detected (install only if missing)        
      Transferring files to <default-centos-72>       
      Starting Chef Client, version 12.6.0        
      resolving cookbooks for run list: ["motd_rhel::default"]
      Synchronizing Cookbooks: - motd_rhel (0.1.0)       
      Compiling Cookbooks...       Converging 1 resources        
      Recipe: motd_rhel::default        (up to date)         
      Running handlers:       Running handlers complete       
      Chef Client finished, 0/1 resources updated in 01 seconds        
      Finished converging <default-centos-72> (0m3.57s). 
      -----> Kitchen is finished. (0m4.55s) 

測試設定

Kitchen login 用於測試測試虛擬機器是否已正確預配置。

$ kitchen login 
Last login: Thu Jan 30 19:02:14 2017 from 10.0.2.2 
hostname:  default-centos-72 
fqdn:      default-centos-72 
memory:    244180kBcpu count: 1 

最後退出

$ exit 
Logout 
Connection to 127.0.0.1 closed. 

銷燬設定

$ Kitchen destroy 
-----> Starting Kitchen (v1.4.2) 
-----> Destroying <default-centos-72>...       
   ==> default: Forcing shutdown of VM...        
   ==> default: Destroying VM and associated drives...        
   Vagrant instance <default-centos-72> destroyed.        
   Finished destroying <default-centos-72> (0m4.94s). 
-----> Kitchen is finished. (0m5.93s) 

Chef - Knife 設定

Knife 是 Chef 的命令列工具,用於與 Chef 伺服器互動。它用於上傳 cookbook 和管理 Chef 的其他方面。它提供了本地機器上的 chefDK(倉庫)與 Chef 伺服器之間的介面。它有助於管理:

  • Chef 節點
  • Cookbook
  • 菜譜(Recipe)
  • 環境
  • 雲資源
  • 雲預配置
  • 在 Chef 節點上安裝 Chef 客戶端

Knife 提供了一組命令來管理 Chef 基礎設施。

引導命令

  • knife bootstrap [SSH_USER@]FQDN (options)

客戶端命令

  • knife client bulk delete REGEX (options)
  • knife client create CLIENTNAME (options)
  • knife client delete CLIENT (options)
  • knife client edit CLIENT (options)
  • 用法:C:/opscode/chef/bin/knife (options)
  • knife client key delete CLIENT KEYNAME (options)
  • knife client key edit CLIENT KEYNAME (options)
  • knife client key list CLIENT (options)
  • knife client key show CLIENT KEYNAME (options)
  • knife client list (options)
  • knife client reregister CLIENT (options)
  • knife client show CLIENT (options)

配置命令

  • knife configure (options)
  • knife configure client DIRECTORY

Cookbook 命令

  • knife cookbook bulk delete REGEX (options)
  • knife cookbook create COOKBOOK (options)
  • knife cookbook delete COOKBOOK VERSION (options)
  • knife cookbook download COOKBOOK [VERSION] (options)
  • knife cookbook list (options)
  • knife cookbook metadata COOKBOOK (options)
  • knife cookbook metadata from FILE (options)
  • knife cookbook show COOKBOOK [VERSION] [PART] [FILENAME] (options)
  • knife cookbook test [COOKBOOKS...] (options)
  • knife cookbook upload [COOKBOOKS...] (options)

Cookbook 站點命令

  • knife cookbook site download COOKBOOK [VERSION] (options)
  • knife cookbook site install COOKBOOK [VERSION] (options)
  • knife cookbook site list (options)
  • knife cookbook site search QUERY (options)
  • knife cookbook site share COOKBOOK [CATEGORY] (options)
  • knife cookbook site show COOKBOOK [VERSION] (options)
  • knife cookbook site unshare COOKBOOK

資料包命令

  • knife data bag create BAG [ITEM] (options)
  • knife data bag delete BAG [ITEM] (options)
  • knife data bag edit BAG ITEM (options)
  • knife data bag from file BAG FILE|FOLDER [FILE|FOLDER..] (options)
  • knife data bag list (options)
  • knife data bag show BAG [ITEM] (options)

環境命令

  • knife environment compare [ENVIRONMENT..] (options)
  • knife environment create ENVIRONMENT (options)
  • knife environment delete ENVIRONMENT (options)
  • knife environment edit ENVIRONMENT (options)
  • knife environment from file FILE [FILE..] (options)
  • knife environment list (options)
  • knife environment show ENVIRONMENT (options)

執行命令

  • knife exec [SCRIPT] (options)

幫助命令

  • knife help [list|TOPIC]

索引命令

  • knife index rebuild (options)

節點命令

  • knife node bulk delete REGEX (options)
  • knife node create NODE (options)
  • knife node delete NODE (options)
  • knife node edit NODE (options)
  • knife node environment set NODE ENVIRONMENT
  • knife node from file FILE (options)
  • knife node list (options)
  • knife node run_list add [NODE] [ENTRY[,ENTRY]] (options)
  • knife node run_list remove [NODE] [ENTRY[,ENTRY]] (options)
  • knife node run_list set NODE ENTRIES (options)
  • knife node show NODE (options)

OSC 命令

  • knife osc_user create USER (options)
  • knife osc_user delete USER (options)
  • knife osc_user edit USER (options)
  • knife osc_user list (options)
  • knife osc_user reregister USER (options)
  • knife osc_user show USER (options)

基於路徑的命令

  • knife delete [PATTERN1 ... PATTERNn]
  • knife deps PATTERN1 [PATTERNn]
  • knife diff PATTERNS
  • knife download PATTERNS
  • knife edit [PATTERN1 ... PATTERNn]
  • knife list [-dfR1p] [PATTERN1 ... PATTERNn]
  • knife show [PATTERN1 ... PATTERNn]
  • knife upload PATTERNS
  • knife xargs [COMMAND]

原始命令

  • knife raw REQUEST_PATH

配方命令

  • knife recipe list [PATTERN]

角色命令

  • knife role bulk delete REGEX (options)
  • knife role create ROLE (options)
  • knife role delete ROLE (options)
  • knife role edit ROLE (options)
  • knife role env_run_list add [ROLE] [ENVIRONMENT] [ENTRY[,ENTRY]] (options)
  • knife role env_run_list clear [ROLE] [ENVIRONMENT]
  • knife role env_run_list remove [ROLE] [ENVIRONMENT] [ENTRIES]
  • knife role env_run_list replace [ROLE] [ENVIRONMENT] [OLD_ENTRY] [NEW_ENTRY]
  • knife role env_run_list set [ROLE] [ENVIRONMENT] [ENTRIES]
  • knife role from file FILE [FILE..] (options)
  • knife role list (options)
  • knife role run_list add [ROLE] [ENTRY[,ENTRY]] (options)
  • knife role run_list clear [ROLE]
  • knife role run_list remove [ROLE] [ENTRY]
  • knife role run_list replace [ROLE] [OLD_ENTRY] [NEW_ENTRY]
  • knife role run_list set [ROLE] [ENTRIES]
  • knife role show ROLE (options)

服務命令

  • knife serve (options)

SSH 命令

  • knife ssh QUERY COMMAND (options)

SSL 命令

  • knife ssl check [URL] (options)
  • knife ssl fetch [URL] (options)

狀態命令

  • knife status QUERY (options)

標籤命令

  • knife tag create NODE TAG ...
  • knife tag delete NODE TAG ...
  • knife tag list NODE

使用者命令

  • knife user create USERNAME DISPLAY_NAME FIRST_NAME LAST_NAME EMAIL PASSWORD (options)
  • knife user delete USER (options)
  • knife user edit USER (options)

  • knife 使用者金鑰建立 USER (選項)
  • knife 使用者金鑰刪除 USER KEYNAME (選項)
  • knife 使用者金鑰編輯 USER KEYNAME (選項)
  • knife 使用者金鑰列表 USER (選項)
  • knife 使用者金鑰顯示 USER KEYNAME (選項)
  • knife 使用者列表 (選項)
  • knife 使用者重新註冊 USER (選項)
  • knife 使用者顯示 USER (選項)

Knife 設定

為了設定 knife,需要切換到 **.chef** 目錄並在 Chef 程式碼庫中建立一個 **knife.rb** 檔案,該檔案告訴 knife 配置細節。這將包含一些詳細資訊。

current_dir = File.dirname(__FILE__) 
log_level                :info 
log_location             STDOUT 
node_name                'node_name' 
client_key               "#{current_dir}/USER.pem" 
validation_client_name   'ORG_NAME-validator' 
validation_key           "#{current_dir}/ORGANIZATION-validator.pem" 
chef_server_url          'https://api.chef.io/organizations/ORG_NAME' 
cache_type               'BasicFile' 
cache_options( :path =>  "#{ENV['HOME']}/.chef/checksums" ) 
cookbook_path            ["#{current_dir}/../cookbooks"] 

在上面的程式碼中,我們使用託管的 Chef 伺服器,它使用以下兩個金鑰。

validation_client_name   'ORG_NAME-validator' 
validation_key           "#{current_dir}/ORGANIZATION-validator.pem" 

在這裡,knife.rb 告訴 knife 使用哪個組織以及在哪裡找到私鑰。它告訴 knife 在哪裡找到使用者的私鑰。

client_key               "#{current_dir}/USER.pem" 

以下程式碼行告訴 knife 我們正在使用託管伺服器。

chef_server_url        'https://api.chef.io/organizations/ORG_NAME' 

使用 knife.rb 檔案,驗證器 knife 現在可以連線到您組織的託管 Opscode。

Chef - Solo 設定

Chef-Solo 是一個開源工具,它在本地執行,並允許使用 Chef cookbook 配置虛擬機器,而無需任何 Chef 客戶端和伺服器配置的複雜性。它有助於在自建伺服器上執行 cookbook。

在本地機器上執行 Chef-Solo 之前,需要在本地機器上安裝以下兩個檔案。

  • **Solo.rb** - 該檔案告訴 Chef 在哪裡找到 cookbook、角色和資料包。

  • **Node.json** - 該檔案設定執行列表和任何節點特定的屬性(如果需要)。

solo.rb 配置

以下是配置 solo.rb 的步驟。

**步驟 1** - 在 Chef 程式碼庫中建立 solo.rb 檔案。

current_dir       = File.expand_path(File.dirname(__FILE__)) 
file_cache_path   "#{current_dir}" 
cookbook_path     "#{current_dir}/cookbooks" 
role_path         "#{current_dir}/roles" 
data_bag_path     "#{current_dir}/data_bags" 

**步驟 2** - 將檔案新增到 Git 程式碼庫。

$ git add solo.rb 

**步驟 3** - 在 Chef 程式碼庫中建立具有以下內容的 node.json 檔案。

{ 
   "run_list": [ "recipe[ntp]" ] 
} 

**步驟 4** - 使用 knife 將 ntp cookbook 獲取到 Chef 程式碼庫中。

vipin@laptop:~/chef-repo $ knife cookbook site install ntp 
Installing ntp to /Users/mma/work/chef-repo/cookbooks 
…TRUNCATED OUTPUT… 
Cookbook ntp version 1.3.0 successfully installed 

**步驟 5** - 將 node.json 檔案新增到 Git。

$ git add node.json 

**步驟 6** - 提交併將檔案推送到 Git 程式碼庫。

vipin@laptop:~/chef-repo $ git commit -m "initial setup for Chef Solo" 
vipin@laptop:~/chef-repo $ git push 
Counting objects: 4, done. 
Delta compression using up to 4 threads. 
...TRUNCATED OUTPUT... 
To git@github.com:mmarschall/chef-repo.git 
b930647..5bcfab6 master -> master 

在節點上執行 Cookbook

**步驟 1** - 登入到要配置 Chef-Solo 的節點。

**步驟 2** - 在機器上克隆 Chef 程式碼庫。

$ git clone $URL_PATH 

**步驟 3** - cd 到 Chef 程式碼庫。

$ cd chef-repo 

最後,執行 Chef-Solo 以使節點收斂 -

$ sudo chef-solo -c solo.rb -j node.json 
[2017-20-08T22:54:13+01:00] INFO: *** Chef 11.0.0 *** 
[2017-20-08T22:54:13+01:00] INFO: Setting the run_list to 
["recipe[ntp]"] from JSON 
...TRUNCATED OUTPUT... 
[2012-12-08T22:54:16+01:00] INFO: Chef Run complete in 2.388374 
seconds 
[2012-12-08T22:54:16+01:00] INFO: Running report handlers 

**solo.rb** 將 Chef-Solo 配置為在其當前目錄(Chef 程式碼庫)中查詢其 cookbook、角色和資料包。

**Chef-Solo** 從 JSON 檔案中獲取其節點配置。在我們的示例中,我們將其稱為 node.json。如果您要管理多臺伺服器,則需要為每個節點建立一個單獨的檔案。然後,Chef-Solo 僅根據在 solo.rb 和 node.json 中找到的配置資料執行 Chef 執行。

Chef - 菜譜(Cookbooks)

Cookbook 是 Chef 的基本工作單元,其中包含與工作單元相關的所有詳細資訊,能夠修改 Chef 基礎架構上配置為節點的任何系統的配置和狀態。Cookbook 可以執行多個任務。Cookbook 包含關於節點所需狀態的值。這是透過在 Chef 中使用所需的外部庫來實現的。

Cookbook 的關鍵元件

  • 菜譜(Recipes)
  • 元資料(Metadata)
  • 屬性(Attributes)
  • 資源(Resources)
  • 模板
  • 庫(Libraries)
  • 任何其他有助於建立系統的元件

建立 Cookbook

有兩種方法可以動態建立 cookbook。

  • 使用 chef 命令
  • 使用 knife 工具

使用 Chef 命令

要使用 Chef 命令建立空 cookbook,請執行以下命令。

C:\Users\vipinkumarm>chef generate cookbook <Cookbook Name> 
C:\Users\vipinkumarm>chef generate cookbook VTest
Installing Cookbook Gems:

Compiling Cookbooks...
Recipe: code_generator::cookbook
   * directory[C:/Users/vipinkumarm/VTest] action create
      - create new directory C:/Users/vipinkumarm/VTest
   
   * template[C:/Users/vipinkumarm/VTest/metadata.rb] action create_if_missing
      - create new file C:/Users/vipinkumarm/VTest/metadata.rb
      - update content in file C:/Users/vipinkumarm/VTest/metadata.rb 
         from none to 4b9435 (diff output suppressed by config)

   * template[C:/Users/vipinkumarm/VTest/README.md] action create_if_missing
      - create new file C:/Users/vipinkumarm/VTest/README.md
      - update content in file C:/Users/vipinkumarm/VTest/README.md 
         from none to 482077 (diff output suppressed by config)

   * cookbook_file[C:/Users/vipinkumarm/VTest/chefignore] action create
      - create new file C:/Users/vipinkumarm/VTest/chefignore
      - update content in file C:/Users/vipinkumarm/VTest/chefignore 
         from none to 15fac5 (diff output suppressed by config)
   
   * cookbook_file[C:/Users/vipinkumarm/VTest/Berksfile] action create_if_missing
      - create new file C:/Users/vipinkumarm/VTest/Berksfile
      - update content in file C:/Users/vipinkumarm/VTest/Berksfile 
         from none to 9f08dc (diff output suppressed by config)

   * template[C:/Users/vipinkumarm/VTest/.kitchen.yml] action create_if_missing
      - create new file C:/Users/vipinkumarm/VTest/.kitchen.yml
      - update content in file C:/Users/vipinkumarm/VTest/.kitchen.yml 
         from none to 93c5bd (diff output suppressed by config)

   * directory[C:/Users/vipinkumarm/VTest/test/integration/default/serverspec]
      action create
      - create new directory
         C:/Users/vipinkumarm/VTest/test/integration/default/serverspec
   
   * directory[C:/Users/vipinkumarm/VTest/test/integration/helpers/serverspec]
      action create
      - create new directory
         C:/Users/vipinkumarm/VTest/test/integration/helpers/serverspec
   
   * cookbook_file
      [C:/Users/vipinkumarm/VTest/test/integration/helpers/serverspec/sp ec_helper.rb]
      action create_if_missing
      - create new file
         C:/Users/vipinkumarm/VTest/test/integration/helpers/serverspec/spec_helper.rb
      - update content in file
         C:/Users/vipinkumarm/VTest/test/integration/helpers/serverspec/spec_helper.rb
         from none to d85df4 (diff output suppressed by config)
   
   * template
      [C:/Users/vipinkumarm/VTest/test/integration/default/serverspec/default _spec.rb]
      action create_if_missing
      - create new file
         C:/Users/vipinkumarm/VTest/test/integration/default/serverspec/default_spec.rb
      - update content in file
         C:/Users/vipinkumarm/VTest/test/integration/default/serverspec/default_spec.rb
         from none to 758b94 (diff output suppressed by config)
   
   * directory[C:/Users/vipinkumarm/VTest/spec/unit/recipes] action create
      - create new directory C:/Users/vipinkumarm/VTest/spec/unit/recipes
   
   * cookbook_file[C:/Users/vipinkumarm/VTest/spec/spec_helper.rb]
      action create_if_missing
      - create new file C:/Users/vipinkumarm/VTest/spec/spec_helper.rb
      - update content in file C:/Users/vipinkumarm/VTest/spec/spec_helper.rb
         from none to 587075 (diff output suppressed by config)

   * template[C:/Users/vipinkumarm/VTest/spec/unit/recipes/default_spec.rb]
      action create_if_missing
      - create new file C:/Users/vipinkumarm/VTest/spec/unit/recipes/default_spec.rb
      - update content in file 
         C:/Users/vipinkumarm/VTest/spec/unit/recipes/default_spec.rb
         from none to 779503 (diff output suppressed by config)
      - create new file C:/Users/vipinkumarm/VTest/recipes/default.rb
      - update content in file C:/Users/vipinkumarm/VTest/recipes/default.rb
         from none to 8cc381 (diff output suppressed by config)

   * cookbook_file[C:/Users/vipinkumarm/VTest/.gitignore] action create
      - create new file C:/Users/vipinkumarm/VTest/.gitignore
      - update content in file C:/Users/vipinkumarm/VTest/.gitignore from none to 33d469
         (diff output suppressed by config)

名為 VTest 的 cookbook 結構將在目錄中建立,並且以下將是其結構。

VTest

使用 Knife 工具

使用以下命令使用 knife 工具建立 cookbook。

C:\Users\vipinkumarm\VTest>knife cookbook create VTest2 
WARNING: No knife configuration file found 
** Creating cookbook VTest2 in C:/chef/cookbooks 
** Creating README for cookbook: VTest2 
** Creating CHANGELOG for cookbook: VTest2 
** Creating metadata for cookbook: VTest2 

以下將是 cookbook 的結構。

Cookbook

Chef - 菜譜依賴關係

定義 cookbook 依賴項的功能有助於管理 cookbook。當我們想要在其他 cookbook 中使用一個 cookbook 的功能時,會使用此功能。

例如,如果要編譯 C 程式碼,則需要確保安裝編譯所需的所有依賴項。為此,可能存在可以執行此類功能的單獨 cookbook。

當我們使用 chef-server 時,我們需要知道 cookbook 中的這些依賴項,這些依賴項應該在 cookbook 元資料檔案中宣告。此檔案位於 cookbook 目錄結構的頂部。它為 Chef 伺服器提供提示,有助於將 cookbook 部署到正確的節點。

metadata.rb 檔案的功能

  • 位於 cookbook 目錄結構的頂部。

  • 使用 knife 命令將 cookbook 上傳到 Chef 伺服器時編譯。

  • 使用 knife cookbook metadata 子命令編譯。

  • 執行 knife cookbook create 命令時自動建立。

metadata.rb 的配置

以下是元資料檔案的預設內容。

Metadata

Default Content

Chef - 角色

Chef 中的角色是將節點分組的邏輯方式。典型案例是為 Web 伺服器、資料庫伺服器等設定角色。可以為所有節點設定自定義執行列表,並在角色中覆蓋屬性值。

建立角色

vipin@laptop:~/chef-repo $ subl roles/web_servers.rb 
name "web_servers" 
description "This role contains nodes, which act as web servers" 
run_list "recipe[ntp]" 
default_attributes 'ntp' => { 
   'ntpdate' => { 
      'disable' => true 
   } 
}

建立角色後,需要將其上傳到 Chef 伺服器。

將角色上傳到 Chef 伺服器

vipin@laptop:~/chef-repo $ knife role from file web_servers.rb 

現在,我們需要將角色分配給名為 server 的節點。

將角色分配給節點

vipin@laptop:~/chef-repo $ knife node edit server 
"run_list": [ 
   "role[web_servers]" 
] 
Saving updated run_list on node server 

執行 Chef-Client

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-07-25T13:28:24+00:00] INFO: Run List is [role[web_servers]] 
[2013-07-25T13:28:24+00:00] INFO: Run List expands to [ntp] 
...TRUNCATED OUTPUT... 

工作原理

  • 在 Chef 程式碼庫的 roles 資料夾中,使用 Ruby 檔案定義角色。

  • 角色包含名稱和描述屬性。

  • 角色包含特定於角色的執行列表和特定於角色的屬性設定。

  • 每個在執行列表中具有角色的節點都將擁有該角色的執行列表提取到自身中。

  • 角色執行列表中的所有菜譜都將在節點上執行。

  • 角色將使用 knife role from file 命令上傳到 Chef 伺服器。

  • 角色將新增到節點執行列表。

  • 在執行列表中具有角色的節點上執行 Chef 客戶端將執行角色中列出的所有菜譜。

Chef - 環境

Chef 有助於執行特定於環境的配置。最好為開發、測試和生產設定單獨的環境。

Chef 支援將節點分組到不同的環境中,以支援有序的開發流程。

建立環境

可以使用 knife 工具動態建立環境。以下命令將開啟 Shell 的預設編輯器,以便可以修改環境定義。

vipin@laptop:~/chef-repo $ knife environment create book { 
   "name": "book", 
   "description": "", 
   "cookbook_versions": { 
   }, 
   "json_class": "Chef::Environment", 
   "chef_type": "environment", 
   "default_attributes": { 
   }, 
   "override_attributes": { 
   } 
} 
Created book 

測試已建立的環境

vipin@laptop:~/chef-repo $ knife environment list 
_default 
book 

列出所有環境的節點

vipin@laptop:~/chef-repo $ knife node list 
my_server 

_default 環境

每個組織始終至少以一個名為 default 環境的環境開始,該環境始終可用於 Chef 伺服器。default 環境無法以任何方式修改。任何更改只能在我們建立的自定義環境中進行。

環境屬性

可以在環境中定義屬性,然後用於覆蓋節點中的預設設定。當 Chef 客戶端執行時,這些屬性將與節點中已存在的預設屬性進行比較。當環境屬性優先於預設屬性時,Chef 客戶端將在每個節點上執行 Chef 客戶端時應用這些設定和值。

環境屬性只能是 default_attribute 或 override_attribute。它不能是普通屬性。可以使用 default_attribute 或 override_attribute 方法。

屬性型別

**預設(Default)** - 預設屬性在每次 Chef 客戶端執行開始時始終重置,並且具有最低的屬性優先順序。

**覆蓋(Override)** - 覆蓋屬性在每次 Chef 客戶端執行開始時始終重置,並且具有比預設、force_default 和普通更高的屬性優先順序。覆蓋屬性最常在菜譜中定義,但也可以在角色或環境的屬性檔案中指定。

應用屬性的順序

Order Attribute

Chef - Chef-Client 作為守護程序

將 Chef-Client 作為守護程序執行有助於隨時瞭解所有節點的狀態。這有助於隨時執行 Chef-Client。

先決條件

節點應已註冊到 Chef 伺服器,並且應在沒有錯誤的情況下執行 Chef-Client。

守護程序模式下的 Chef-Client

以守護程序模式啟動 Chef-Client,每 30 分鐘執行一次。

user@server:~$ sudo chef-client -i 1800 

在上面的程式碼中,- **i** 啟用在所需節點上以守護程序模式執行 Chef-Client,並且 1800 秒定義 Chef-Client 守護程序應每 30 分鐘執行一次。

驗證守護程序執行

驗證 Chef-Client 是否正在作為守護程序執行。

user@server:~$ ps auxw | grep chef-client 

以上命令將 grep Chef-Client 的正在執行的守護程序。

其他方法

除了將 Chef-Client 作為守護程序執行之外,我們還可以將其作為 **cron 作業** 執行。

user@server:~$ subl /etc/cron.d/chef_client 
PATH=/usr/local/bin:/usr/bin:/bin 
# m h dom mon dow user command 
*/15 * * * * root chef-client -l warn | grep -v 'retrying [1234]/5 in' 

上面的 cron 作業將在每 15 分鐘後執行。

Chef - Chef-Shell

編寫 Chef cookbook 總是很困難。由於將它們上傳到 Chef 伺服器、配置 Vagrant 虛擬機器、檢查它們在那裡如何失敗以及重複此過程的長時間反饋迴圈,它使它變得更加困難。如果我們能夠在執行所有這些繁重工作之前嘗試測試一些片段或菜譜,那將更容易。

Chef 附帶 Chef-Shell,它本質上是 Chef 的互動式 Ruby 會話。在 Chef-Shell 中,我們可以建立 -

  • 屬性(Attributes)
  • 編寫菜譜(Recipes)
  • 初始化 Chef 執行

它用於在將菜譜上傳到 Chef 伺服器並在節點上執行完整 cookbook 之前,動態評估菜譜的各個部分。

執行 Shell

**步驟 1** - 以獨立模式執行 Chef-Shell。

mma@laptop:~/chef-repo $ chef-shell 
loading configuration: none (standalone chef-shell session) 
Session type: standalone 
Loading...[2017-01-12T20:48:01+01:00] INFO: Run List is [] 
[2017-01-12T20:48:01+01:00] INFO: Run List expands to [] 
done. 
This is chef-shell, the Chef Shell. 
Chef Version: 11.0.0 
http://www.opscode.com/chef 
http://wiki.opscode.com/display/chef/Home 
run `help' for help, `exit' or ^D to quit. 
Ohai2u mma@laptop!  
chef > 

**步驟 2** - 在 Chef-Shell 中切換到屬性模式

  • chef > attributes_mode

**步驟 3** - 設定屬性值。

  • chef:attributes > set[:title] = "Chef Cookbook"

    • "Chef Cookbook"

  • chef:attributes > quit

    • :attributes

  • chef >

**步驟 4** - 切換到菜譜模式。

  • chef > recipe_mode

**步驟 5** - 建立檔案資源。

chef:recipe > file "/tmp/book.txt" do 
chef:recipe > content node.title 
chef:recipe ?> end  

=> <file[/tmp/book.txt] @name: "/tmp/book.txt" @noop: nil @ 
before: nil @params: {} @provider: Chef::Provider::File @allowed_ 
actions: [:nothing, :create, :delete, :touch, :create_if_missing] 
@action: "create" @updated: false @updated_by_last_action: false 
@supports: {} @ignore_failure: false @retries: 0 @retry_delay: 
2 @source_line: "(irb#1):1:in `irb_binding'" @elapsed_time: 0 @ 
resource_name: :file @path: "/tmp/book.txt" @backup: 5 @diff: nil 
@cookbook_name: nil @recipe_name: nil @content: "Chef Cookbook">   

chef:recipe > 

**步驟 6** - 開始 Chef 執行以建立具有給定內容的檔案。

  • chef:recipe > run_chef

[2017-01-12T21:07:49+01:00] INFO: Processing file[/tmp/book.txt] 
action create ((irb#1) line 1) 
--- /var/folders/1r/_35fx24d0y5g08qs131c33nw0000gn/T/cheftempfile20121212- 
11348-dwp1zs 2012-12-12 21:07:49.000000000 
+0100 
+++ /var/folders/1r/_35fx24d0y5g08qs131c33nw0000gn/T/chefdiff20121212- 
11348-hdzcp1 2012-12-12 21:07:49.000000000 +0100 
@@ -0,0 +1 @@ 
+Chef Cookbook 
\ No newline at end of file 
[2017-01-12T21:07:49+01:00] INFO: entered create 
[2017-01-12T21:07:49+01:00] INFO: file[/tmp/book.txt] created file 
/tmp/book.txt 

工作原理

  • Chef-Shell 以互動式 Ruby (IRB) 會話開始,並增強了一些特定功能。

  • 它提供屬性模式(attributes_mode)和互動模式(interactive_mode)等模式。

  • 它有助於編寫在菜譜或 cookbook 中編寫的命令。

  • 它以互動模式執行所有內容。

我們可以以三種不同的模式執行 Chef-Shell:**獨立模式、客戶端模式**和**獨立模式**。

  • **獨立模式** - 這是預設模式。沒有載入 cookbook,並且執行列表為空。

  • **客戶端模式** - 在這裡,chef-shell 充當 chef-client。

  • **獨立模式** - 在這裡,chef-shell 充當 chef-solo 客戶端。

Chef - 測試菜譜

如果 cookbook 直接部署並在生產伺服器上執行,則 cookbook 很可能在生產環境中崩潰。防止這種情況發生的最佳方法是在設定環境中測試 cookbook。

以下是測試步驟。

步驟 1 − 使用以下命令安裝 cookbook。

vipin@laptop:~/chef-repo $ knife cookbook site install <cookbook name> 

步驟 2 − 在工作 cookbook 上執行 knife cookbook test 命令。

vipin@laptop:~/chef-repo $ knife cookbook test VTest  
checking ntp 
Running syntax check on ntp 
Validating ruby files 
Validating templates

步驟 3 − 破壞 cookbook 中的內容並再次測試。

vipin@laptop:~/chef-repo $ subl cookbooks/VTest/recipes/default.rb 
... 
[ node['ntp']['varlibdir'] 
node['ntp']['statsdir'] ].each do |ntpdir| 
   directory ntpdir do 
      owner node['ntp']['var_owner'] 
      group node['ntp']['var_group'] 
      mode 0755 
   end 
end

步驟 4 − 再次執行 knife test 命令。

vipin@laptop:~/chef-repo $ knife cookbook test ntp 
checking ntp 
Running syntax check on ntp 
Validating ruby files 
FATAL: Cookbook file recipes/default.rb has a ruby syntax error: 
FATAL: cookbooks/ntp/recipes/default.rb:25: syntax error, 
unexpected tIDENTIFIER, expecting ']' 
FATAL: node['ntp']['statsdir'] ].each do |ntpdir| 
FATAL: ^ 
FATAL: cookbooks/ntp/recipes/default.rb:25: syntax error, 
unexpected ']', expecting $end 
FATAL: node['ntp']['statsdir'] ].each do |ntpdir| 
FATAL: 

工作方法

Knife cookbook test 會對 cookbook 中的所有 Ruby 檔案以及所有 ERB 模板執行 Ruby 語法檢查。它迴圈遍歷 Ruby 檔案,並對每個檔案執行 Ruby –c。Ruby –c 檢查指令碼的語法,並在不執行指令碼的情況下退出。

在遍歷完所有 Ruby 檔案後,knife cookbook test 會遍歷所有 ERB 模板,並將 –x 生成的冗餘版本透過管道傳遞到 Ruby –c

限制

Knife cookbook test 僅對 Ruby 檔案和 ERB 模板進行簡單的語法檢查。我們可以使用 ChefSpec 和 test kitchen 進行完全測試驅動。

Chef - Foodcritic

編寫沒有任何問題的良好 cookbook 是一項相當困難的任務。但是,有一些方法可以幫助識別潛在的缺陷。可以在 Chef Cookbook 中進行標記。Foodcritic 是實現此目的的最佳方法之一,它試圖識別 cookbook 邏輯和風格中可能存在的問題。

Foodcritic 設定

步驟 1 − 新增 Foodcritic gem。

vipin@laptop:~/chef-repo $ subl Gemfile 
source 'https://rubygems.org' 
gem 'foodcritic', '~>2.2.0'

步驟 2 − 安裝 gem。

vipin@laptop:~/chef-repo $ bundle install 
Fetching gem metadata from https://rubygems.org/ 
...TRUNCATED OUTPUT... 
Installing foodcritic (2.2.0) 

Foodcritic Gem

步驟 1 − 在 cookbook 上執行 Foodcritic。

vipin@laptop:~/chef-repo $ foodcritic ./cookbooks/<Cookbook Name> 
FC002: Avoid string interpolation where not required: ./cookbooks/ 
mysql/attributes/server.rb:220 
...TRUNCATED OUTPUT... 
FC024: Consider adding platform equivalents: ./cookbooks/<Cookbook Name>/ 
recipes/server.rb:132 

步驟 2 − 生成詳細報告。

vipin@laptop:~/chef-repo $ foodcritic -C ./cookbooks/mysql 
cookbooks/<cookbook Name>/attributes/server.rb 
FC002: Avoid string interpolation where not required 
[...] 
85| default['<Cookbook Name>']['conf_dir'] = "#{mysql['basedir']}" 
[...] 
cookbooks/<Cookbook Name>/recipes/client.rb 
FC007: Ensure recipe dependencies are reflected in cookbook 
metadata 
40| end 
41|when "mac_os_x" 
42| include_recipe 'homebrew' 
43|end 
44|

工作方法

Foodcritic 定義了一組規則並檢查了每個 recipe 代理。它包含多個關於各個領域的規則:樣式、連線性、屬性、字串、機率、搜尋、服務、檔案、元資料等等。

Chef - ChefSpec

測試驅動開發 (TDD) 是一種在編寫任何實際 recipe 程式碼之前編寫單元測試的方法。測試應該真實有效,並驗證 recipe 的功能。它應該確實會失敗,因為還沒有開發 recipe。一旦 recipe 開發完成,測試應該透過。

ChefSpec 基於流行的 RSpec 框架構建,並提供了一種針對 Chef recipe 進行測試的定製語法。

建立 ChefSpec

步驟 1 − 建立包含 chefSpec gem 的 gem 檔案。

vipin@laptop:~/chef-repo $ subl Gemfile 
source 'https://rubygems.org' 
gem 'chefspec' 

步驟 2 − 安裝 gem。

vipin@laptop:~/chef-repo $ bundler install 
Fetching gem metadata from https://rubygems.org/ 
...TRUNCATED OUTPUT... 
Installing chefspec (1.3.1) 
Using bundler (1.3.5) 
Your bundle is complete! 

步驟 3 − 建立 spec 目錄。

vipin@laptop:~/chef-repo $ mkdir cookbooks/<Cookbook Name>/spec 

步驟 4 − 建立 Spec

vipin@laptop:~/chef-repo $ subl  
cookbooks/my_cookbook/spec/default_spec.rb  
require 'chefspec'  
describe 'my_cookbook::default' do  
   let(:chef_run) {  
      ChefSpec::ChefRunner.new(  
         platform:'ubuntu', version:'12.04'  
      ).converge(described_recipe)  
   }  

   it 'creates a greetings file, containing the platform  
   name' do  
      expect(chef_run).to  
      create_file_with_content('/tmp/greeting.txt','Hello! ubuntu!')  
   end  
end 

步驟 5 − 驗證 ChefSpec。

vipin@laptop:~/chef-repo $ rspec cookbooks/<Cookbook Name>/spec/default_spec.rb 
F 
Failures: 
1) <CookBook Name> ::default creates a greetings file, containing the platform name 
Failure/Error: expect(chef_run.converge(described_recipe)).to 
create_file_with_content('/tmp/greeting.txt','Hello! ubuntu!') 
File content: 
does not match expected: 
Hello! ubuntu! 
# ./cookbooks/my_cookbook/spec/default_spec.rb:11:in `block 
(2 levels) in <top (required)>' 
Finished in 0.11152 seconds 
1 example, 1 failure  

Failed examples: 
rspec ./cookbooks/my_cookbook/spec/default_spec.rb:10 # my_ 
cookbook::default creates a greetings file, containing the 
platform name 

步驟 6 − 編輯 Cookbook 的預設 recipe。

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/recipes/default.rb 
template '/tmp/greeting.txt' do 
   variables greeting: 'Hello!' 
end 

步驟 7 − 建立模板檔案。

vipin@laptop:~/chef-repo $ subl cookbooks/< Cookbook Name>/recipes/default.rb 
<%= @greeting %> <%= node['platform'] %>! 

步驟 8 − 再次執行 rspec。

vipin@laptop:~/chef-repo $ rspec cookbooks/<Cookbook Name>/spec/default_spec.rb 
. 
Finished in 0.10142 seconds 
1 example, 0 failures 

工作原理

為了使其正常工作,我們需要首先設定使用 RSpec 與 Chef 的基本基礎架構。然後我們需要 ChefSpec Ruby gem,並且 cookbook 需要一個名為 spec 的目錄,所有測試都將儲存在該目錄中。

Chef - 使用 Test Kitchen 測試 Cookbook

Test Kitchen 是 Chef 的整合測試框架。它能夠編寫測試,這些測試在使用 cookbook 例項化和收斂 VM 後執行。測試在 VM 上執行,可以驗證一切按預期工作。

這是與僅模擬 Chef 執行的 ChefSpec 的節點契約。Test Kitchen 啟動一個真實的節點並在其上執行 Chef。

設定

為此,我們需要在機器上安裝 Vagrant,它有助於管理虛擬機器。然後我們需要安裝 bookshelf 並將其與 Vagrant 關聯以管理 cookbook 依賴項。

步驟 1 − 編輯 cookbook 中的預設 recipe。

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/recipes/default.rb 
file "/tmp/greeting.txt" do 
   content node['my_cookbook']['greeting'] 
end

步驟 2 − 編輯 cookbook 屬性。

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/attributes/default.rb 
default['my_cookbook']['greeting'] = "Ohai, Chefs!"

步驟 3 − 編輯 gem 檔案以安裝必要的 Ruby gem。

vipin@laptop:~/chef-repo $ subl Gemfile 
gem 'test-kitchen', '~> 2.0.0.alpha.7' 
gem 'kitchen-vagrant' 

步驟 4 − 安裝必要的 Ruby gem。

vipin@laptop:~/chef-repo $ bundle install 
...TRUNCATED OUTPUT... 
Installing test-kitchen (1.0.0.alpha.7) 
Installing kitchen-vagrant (0.10.0) ...TRUNCATED OUTPUT... 

步驟 5 − 在 cookbook 中建立 .kitchen.yml 檔案。

vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl .kitchen.yml 
--- 
driver_plugin: vagrant 
driver_config: 
   require_chef_omnibus: true  
platforms: 
   - name: ubuntu-12.04 
  driver_config: 
      box: opscode-ubuntu-12.04 
      box_url: 
         https://opscode-vm.s3.amazonaws.com/vagrant/
            opscode_ubuntu12.04_provisionerless.box  
suites: 
   - name: default 
   run_list: 
      - recipe[minitest-handler] 
      - recipe[my_cookbook_test] 
attributes: { my_cookbook: { greeting: 'Ohai, Minitest!'} } 

步驟 6 − 在 cookbook 中建立測試目錄。

vipin@laptop:~/chef-repo/cookbooks/<Cookbook Name>$ mkdir test 

步驟 7 − 建立用於整合測試的測試 cookbook。

vipin@laptop:~/chef-repo/cookbooks/<Cookbook Name>/test $ knife 
cookbook create my_cookbook_test 
** Creating cookbook my_cookbook_test 
** Creating README for cookbook: my_cookbook_test 
** Creating CHANGELOG for cookbook: my_cookbook_test 
** Creating metadata for cookbook: my_cookbook_test 

步驟 8 − 編輯測試 cookbook 的預設 recipe。

vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl 
test/cookbooks/my_cookbook_test/recipes/default.rb 
include_recipe 'my_cookbook::default'

步驟 9 − 在 cookbook 中建立 Minitest Spec。

vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ mkdir -p 
   test/cookbooks/my_cookbook_test/files/default/tests/minitest  

vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl 
   test/cookbooks/my_cookbook_test/files/default/tests/minitest/default_test.rb  

require 'minitest/spec'  
describe_recipe 'my_cookbook::default' do 
   describe "greeting file" do 
      it "creates the greeting file" do 
         file("/tmp/greeting.txt").must_exist 
      end 
       
      it "contains what's stored in the 'greeting' node 
         attribute" do 
         file('/tmp/greeting.txt').must_include 'Ohai, Minitest!' 
      end 
end

步驟 10 − 編輯主 cookbook 的 Berksfile。

vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl Berksfile 
site :opscode 
metadata 
cookbook "apt" 
cookbook "minitest-handler" 
cookbook "my_cookbook_test", path: 
"./test/cookbooks/my_cookbook_test" 

測試設定

vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ kitchen test 
-----> Starting Kitchen (v1.0.0.alpha.7) 
...TRUNCATED OUTPUT... 
-----> Converging <default-ubuntu-1204> 
-----> Installing Chef Omnibus (true) 
...TRUNCATED OUTPUT... 
Starting Chef Client, version 11.4.4 
[2013-06-29T18:33:57+00:00] INFO: *** Chef 11.4.4 *** 
[2013-06-29T18:33:58+00:00] INFO: Setting the run_list to 
["recipe[minitest-handler]", "recipe[my_cookbook_test]"] 
from JSON 
...TRUNCATED OUTPUT... 
# Running tests: 
recipe::my_cookbook::default::greeting 
file#test_0001_creates the greeting file = 0.00 s = . 
recipe::my_cookbook::default::greeting 
file#test_0002_contains what's stored in the 'greeting' 
node attribute = 0.00 s = . 
Finished tests in 0.011190s, 178.7277 tests/s, 178.7277 
assertions/s. 
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips 
...TRUNCATED OUTPUT...  
-----> Kitchen is finished. (2m5.69s) 

Chef - 節點

Knife preflight 在將 cookbook 上傳到 Chef 伺服器之前,顯示有關使用特定 cookbook 的所有節點的詳細資訊。

入門

為了入門,我們需要安裝 knife-preflight gem。

步驟 1 − 在 gem 檔案中定義路徑。

vipin@laptop:~/chef-repo $ subl Gemfile 
source 'https://rubygems.org' 
gem 'knife-preflight' 

步驟 2 − 執行 bundler 以安裝 knife-preflight gem。

vipin@laptop:~/chef-repo $ bundle install 
Fetching gem metadata from https://rubygems.org/ 
...TRUNCATED OUTPUT... 
Installing knife-preflight (0.1.6)

工作方法

在給定的 cookbook 上執行 knife-preflight。

我們可以執行 preflight 命令來找出哪些節點和角色在其擴充套件的執行列表中包含給定的 cookbook。

vipin@laptop:~/chef-repo $ knife preflight ntp 
Searching for nodes containing ntp OR ntp::default in their 
expanded run_list... 
2 Nodes found 
www-staging.example.com 
cms-staging.example.com 
Searching for roles containing ntp OR ntp::default in their 
expanded run_list... 
3 Roles found 
your_cms_role 
your_www_role 
your_app_role 
Found 6 nodes and 3 roles using the specified search 
criteria 

cookbook 在節點上執行有多種方法。

  • 您可以透過將其新增到節點的執行列表中來將 cookbook 直接分配給節點。

  • 您可以將 cookbook 新增到角色,並將角色新增到節點的執行列表中。

  • 您可以將角色新增到另一個角色的執行列表中,並將另一個角色新增到節點的執行列表中。

  • cookbook 可以是另一個已用 cookbook 的依賴項。

無論 cookbook 如何最終進入節點的執行列表,knife preflight 命令都會捕獲它,因為 Chef 將角色和 recipe 的所有擴充套件列表儲存在節點屬性中。knife preflight 命令會精確搜尋這些節點屬性。

Chef - Chef-Client 執行

為了測試 Chef-Client 執行,我們需要將 Chef-Client 配置為使用託管 Chef 或自己的託管伺服器。

在除錯模式下執行 Chef-Client

vipin@server:~$ sudo chef-client -l debug 
…TRUNCATED OUTPUT… 
Hashed Path:A+WOcvvGu160cBO7IFKLYPhh9fI= 
X-Ops-Content-Hash:2jmj7l5rSw0yVb/vlWAYkK/YBwk= 
X-Ops-Timestamp:2012-12-27T11:14:07Z 
X-Ops-UserId:vagrant' 
Header hash: {"X-Ops-Sign"=>"algorithm=sha1;version=1.0;", 
"X-Ops-Userid"=>"vagrant", "X-Ops-Timestamp"=>"2012-12- 
27T11:14:07Z", "X-Ops-Content- 
Hash"=>"2jmj7l5rSw0yVb/vlWAYkK/YBwk=", "X-Ops- 
Authorization- 
1"=>"HQmTt9U/ 
LJJVAJXWtyOu3GW8FbybxAIKp4rhiw9O9O3wtGYVHyVGuoilWDao", 
"X-Ops-Authorization- 
2"=>"2/uUBPWX+YAN0g1/ 
fD2854QAU2aUcnSaVM0cPNNrldoOocmA0U5HXkBJTKok", 
"X-Ops-Authorization- 
3"=>"6EXPrEJg5T+ 
ddWd5qHAN6zMqYc3untb41t+eBpigGHPhtn1LLInMkPeIYwBm", 
"X-Ops-Authorization- 
4"=>"B0Fwbwz2HVP3wEsYdBGu7yOatq7fZBXHfIpeOi0kn/ 
Vn0P7HrucnOpONmMgU", "X-Ops-Authorization- 
5"=>"RBmmbetFSKCYsdg2v2mW/ 
ifLIVemhsHyOQjffPYPpNIB3U2n7vji37NxRnBY", 
"X-Ops-Authorization- 
6"=>"Pb3VM7FmY60xKvWfZyahM8y8WVV9xPWsD1vngihjFw=="} 
[2012-12-27T11:14:07+00:00] DEBUG: Sending HTTP Request via 
GET to api.opscode.com:443/organizations/agilewebops/ 
nodes/vagrant
[2012-12-27T11:14:09+00:00] DEBUG: ---- HTTP Status and 
Header Data: ---- 
[2012-12-27T11:14:09+00:00] DEBUG: HTTP 1.1 200 OK 
[2012-12-27T11:14:09+00:00] DEBUG: server: nginx/1.0.5 
[2012-12-27T11:14:09+00:00] DEBUG: date: Thu, 27 Dec 2012 

檢查上次 Chef-Client 執行的結果

為了檢查上次 Chef-Client 執行,尤其是在我們開發新的 cookbook 時出現的故障問題,我們需要了解到底出了什麼問題。即使 Chef 在 stdout 中列印所有內容,也可能需要再次檢視除錯日誌。

如果要測試,我們需要一個在編譯時失敗的損壞 cookbook。

user@server:~$ sudo chef-client 
================================================================== 
============== 
Recipe Compile Error in /srv/chef/file_store/cookbooks/my_ 
cookbook/recipes/default.rb 
================================================================== 
============== 
NoMethodError 
------------- 
undefined method `each' for nil:NilClass 
Cookbook Trace: 
--------------- 
/srv/chef/file_store/cookbooks/my_cookbook/recipes/default. 
rb:9:in `from_file' 
Relevant File Content: 
---------------------- 
/srv/chef/file_store/cookbooks/my_cookbook/recipes/default.rb: 
2: # Cookbook Name:: my_cookbook 
3: # Recipe:: default 
4: # 
5: # Copyright 2013, YOUR_COMPANY_NAME 
6: # 
7: # All rights reserved - Do Not Redistribute 
8: # 
9≫ nil.each {}  
10: 

有關更多詳細資訊,我們可以檢視堆疊跟蹤。

user@server:~$ less /srv/chef/file_store/chef-stacktrace.out 
Generated at 2013-07-21 18:34:05 +0000 
NoMethodError: undefined method `each' for nil:NilClass 
/srv/chef/file_store/cookbooks/my_cookbook/recipes/default.rb:9:in 
`from_file' 
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.4/lib/chef/ 
mixin/from_file.rb:30:in `instance_eval' 
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.4/lib/chef/ 
mixin/from_file.rb:30:in `from_file' 
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.4/lib/chef/ 
cookbook_version.rb:346:in `load_recipe' 

Chef - 動態配置 Recipe

屬性是動態配置 cookbook 的關鍵元件。屬性使作者能夠使 cookbook 可配置。透過覆蓋 cookbook 中設定的預設值,使用者可以注入自己的值。

步驟 1 − 為 cookbook 屬性建立預設檔案,並向其中新增預設屬性。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/attributes/default.rb 
default['my_cookbook']['message'] = 'hello world!'

步驟 2 − 在 recipe 中定義屬性。

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/recipes/default.rb 
message = node['my_cookbook']['message'] 
Chef::Log.info("** Saying what I was told to say: #{message}") 

步驟 3 − 上傳修改後的 cookbook。

vipin@laptop:~/chef-repo $ knife cookbook upload my_cookbook 
Uploading my_cookbook [0.1.0]

步驟 4 − 執行已定義節點的 Chef-Client。

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-01-13T20:48:21+00:00] INFO: ** Saying what I was told to 
say: hello world! 
...TRUNCATED OUTPUT... 

工作方法

Chef 在執行屬性之前會從屬性檔案中載入所有屬性。屬性與節點物件一起儲存。可以在 recipe 中訪問與節點物件一起儲存的所有屬性,並檢索其當前值。

Chef 具有一個受限的結構,從預設值最低開始,然後是正常值(與 set 具有別名),然後是覆蓋。在 recipe 中設定的屬性級別優先於屬性檔案中設定的相同級別。

在節點和環境級別覆蓋屬性

在角色或環境中定義的屬性具有最高優先順序。

步驟 1 − 建立角色。

vipin@laptop:~/chef-repo $ subl roles/german_hosts.rb 
name "german_hosts" 
description "This Role contains hosts, which should print out 
their messages in German" 
run_list "recipe[my_cookbook]" 
default_attributes "my_cookbook" => { "message" => "Hallo Welt!" } 

步驟 2 − 將角色上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife role from file german_hosts.rb 
Updated Role german_hosts! 

步驟 3 − 將角色分配給節點。

vipin@laptop:~/chef-repo $ knife node edit server 
"run_list": [ 
   "role[german_hosts]" 
] 
Saving updated run_list on node server 

步驟 4 − 執行 Chef-Client。

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-01-13T20:49:49+00:00] INFO: ** Saying what I was told to 
say: Hallo Welt! 
...TRUNCATED OUTPUT...

Chef - 模板

在基礎設施中,配置管理完全取決於配置主機的程度。通常,所有配置都是使用配置檔案完成的。Chef 使用模板能夠使用動態值填充配置檔案。

Chef 提供模板作為可在 recipe 中使用的資源。配置檔案的動態值可以從資料包、屬性中檢索,甚至可以透過將它們傳遞到模板中來計算它們。

如何使用?

步驟 1 − 將模板新增到 recipe。

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/recipes/default.rb  
template '/tmp/message' do 
   source 'Test.erb' 
   variables( 
      hi: 'Tesing', 
      world: 'Welt', 
      from: node['fqdn'] 
   ) 
end 

步驟 2 − 新增ERB模板檔案。

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/templates/default/test.erb 
<%- 4.times do %> 
<%= @hi %>, <%= @world %> from <%= @from %>! 
<%- end %>

步驟 3 − 將修改後的 cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload <Cookbook Name> 
Uploading my_cookbook [0.1.0] 
Run Chef Client on your node: 
user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2017-01-14T20:41:21+00:00] INFO: Processing template[/tmp/ 
message] action create (my_cookbook::default line 9) 
[2017-01-14T20:41:22+00:00] INFO: template[/tmp/message] updated 
content

步驟 4 − 驗證上傳檔案的內容。

user@server:~$ sudo cat /tmp/message 
Hallo, Welt from vagrant.vm! 
Hallo, Welt from vagrant.vm! 
Hallo, Welt from vagrant.vm! 
Hallo, Welt from vagrant.vm! 

工作流程

Chef 使用 Erubis 作為其模板語言。它允許在模板中的特殊符號內嵌入純 Ruby 程式碼。

  • <%= %> 用於將變數或 Ruby 表示式的值列印到生成的檔案中。

  • <%- %> 用於將 Ruby 邏輯嵌入到模板檔案中。我們使用它將表示式迴圈四次。

Chef - Chef DSL 中的純 Ruby

在 Chef 中,如果需要建立簡單的 recipe,可以使用 Chef 中提供的資源,例如模板、remote_file 和服務。但是,隨著 recipe 變得複雜,需要高階技術,例如條件語句來根據條件執行 recipe 的部分內容。這就是將純 Ruby 與 Chef 領域特定語言 (DSL) 混合使用的強大功能。

如何使用?

在客戶端模式下,在任何節點上啟動 Chef Shell 以能夠訪問 Chef 伺服器。

user@server:~$ sudo chef-shell --client 
loading configuration: /etc/chef/client.rb 
Session type: client 
...TRUNCATED OUTPUT... 
run `help' for help, `exit' or ^D to quit. 
Ohai2u user@server! 
Chef> 

Chef DSL 的基本條件

使用純 Ruby 按名稱對節點進行排序。

chef > nodes.sort! {|a,b| a.name <=> b.name } 
=> [node[alice],node[server]] 

迴圈遍歷節點,列印其作業系統。

chef > nodes.each do |n| 
   chef > puts n['os'] 
   chef ?> 
end  
linux 
windows 
=> [node[server], node[alice]] 

使用陣列、迴圈和字串擴充套件來構造 gem 名稱,從而安裝多個 Ruby gem。

chef > %w{ec2 essentials}.each do |gem| 
   chef > gem_package "knife-#{gem}" 
   chef ?> end   => ["ec2", "essentials"] 

工作方法

Chef recipe 是 Ruby 檔案,在 Chef 執行的上下文中進行評估。它們可以包含純 Ruby 程式碼(例如 if 語句和迴圈)以及 Chef DSL 元素(例如資源)。

在 recipe 內部,可以簡單地宣告 Ruby 變數併為其賦值。

Chef - 菜譜中的 Ruby Gems

Recipe 是 cookbook 的關鍵構建塊,它基本上是 Ruby 程式碼。可以在 Chef recipe 內部使用所有 Ruby 語言功能。大多數情況下,Ruby 內建功能就足夠了,但有時可能需要使用其他 Ruby gem。例如,如果需要從 recipe 本身訪問 MySQL 資料庫。

Chef recipe 能夠獲取所需的 Ruby gem 以便在同一個 recipe 中使用它們。

在給定 Recipe 中使用 iptable Gem

步驟 1 − 編輯 cookbook 的預設 recipe,並在 recipe 內部安裝要使用的 gem。

vipin@laptop:~/chef-repo $ subl 
cookbooks/my_cookbook/recipes/default.rb 
chef_gem 'ipaddress' 
require 'ipaddress' 
ip = IPAddress("192.168.0.1/24") 
Chef::Log.info("Netmask of #{ip}: #{ip.netmask}")

步驟 2 − 將修改後的 cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload my_cookbook 
Uploading my_cookbook [0.1.0] 

步驟 3 − 執行 Chef 客戶端以檢視輸出。

user@server $ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-01-18T14:02:02+00:00] INFO: Netmask of 192.168.0.1: 
255.255.255.0 
...TRUNCATED OUTPUT...

工作方法

Chef 執行步驟包括編譯階段(在其中編譯所有資源)和執行階段(在其中 Chef 執行資源提供程式以使節點收斂到所需狀態)。如果在 cookbook 內部需要任何特定的 Ruby gem,則需要在編譯階段安裝該 gem。

chef_gem 資源將執行完全相同的操作,在 Chef 中,Omnibus 是唯一可行的方法。其主要功能是使 gem 可供 Chef 本身使用。

Chef - 庫

Chef 中的庫提供了一個封裝編譯邏輯的位置,以便 cookbook recipe 保持整潔。

建立庫

步驟 1 − 在 cookbook 的庫中建立輔助方法。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/libraries/ipaddress.rb 
class Chef::Recipe 
def netmask(ipaddress) 
IPAddress(ipaddress).netmask 
end 
end

步驟 2 − 使用輔助方法。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/recipes/default.rb 
ip = '10.10.0.0/24' 
mask = netmask(ip) # here we use the library method 
Chef::Log.info("Netmask of #{ip}: #{mask}") 

步驟 3 − 將修改後的 cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload my_cookbook 
Uploading my_cookbook [0.1.0] 

測試庫

user@server $ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-01-18T14:38:26+00:00] INFO: Netmask of 10.10.0.0/24: 
255.255.255.0 
...TRUNCATED OUTPUT... 

工作方法

Chef 庫程式碼可以開啟 chef::Recipe 類並新增新的方法(如步驟 1 中所做的那樣)。此步驟不是最乾淨的,但卻是最簡單的方法。

class Chef::Recipe 
def netmask(ipaddress) 
... 
end 
end

最佳實踐

一旦我們開啟 chef::recipe 類,就會發生汙染。作為最佳實踐,始終以更好的方式在庫中引入一個新的子類,並將方法定義為類方法。這避免了拉取 chef::recipe 名稱空間。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/libraries/ipaddress.rb 
class Chef::Recipe::IPAddress 
def self.netmask(ipaddress) 
IPAddress(ipaddress).netmask 
end 
end 

我們可以在 recipe 中像這樣使用該方法

IPAddress.netmask(ip) 

Chef - 定義

定義可以定義為對資源進行邏輯分組的方法,這些資源被反覆使用。在此流程中,我們將資源分組併為其命名以恢復已定義 cookbook 的可讀性。

為了做到這一點,我們需要一個菜譜。在本例中,我們使用 test_cookbook 和一個節點執行列表,其中包含該 cookbook。

建立定義

步驟 1 − 在 cookbook 的定義資料夾中建立一個新的定義檔案。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/definitions/ 
capistrano_deploy_dirs.rb 
define :capistrano_deploy_dirs, :deploy_to => '' do 
   directory "#{params[:deploy_to]}/releases" 
   directory "#{params[:deploy_to]}/shared" 
   directory "#{params[:deploy_to]}/shared/system" 
end

步驟 2 − 在 cookbook 的預設菜譜中使用定義。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb 
capistrano_deploy_dirs do 
   deploy_to "/srv" 
end 

步驟 3 − 將 cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload test_cookbook 
Uploading test_cookbook [0.1.0] 

步驟 4 − 在目標節點上執行 Chef 客戶端。

vipin@laptop:~/chef-repuser@server $ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-01-18T16:31:11+00:00] INFO: Processing directory[/srv/ 
releases] action create (my_cookbook::default line 2) 
[2013-01-18T16:31:11+00:00] INFO: directory[/srv/releases] created 
directory /srv/releases 
[2013-01-18T16:31:11+00:00] INFO: Processing directory[/srv/ 
shared] action create (my_cookbook::default line 3) 
[2013-01-18T16:31:11+00:00] INFO: directory[/srv/shared] created 
directory /srv/shared 
[2013-01-18T16:31:11+00:00] INFO: Processing directory[/srv/ 
shared/system] action create (my_cookbook::default line 4) 
[2013-01-18T16:31:11+00:00] INFO: directory[/srv/shared/system] 

cookbook 中的定義就像微服務一樣,將資源分組併為它們命名。定義有一個名稱,可以透過它來識別,可以在菜譜中呼叫它,並且它還有一個引數列表。

在定義中,我們有引數,在我們的程式碼中看起來如下所示。

….. 
directory "#{params[:deploy_to]}/releases" 
directory "#{params[:deploy_to]}/shared" 
directory "#{params[:deploy_to]}/shared/system” 
…… 

它可以在預設菜譜中按如下方式使用。

capistrano_deploy_dirs do 
   deploy_to "/srv"` 
end 

Chef - 環境變數

環境變數是使 Chef 菜譜在任何特定節點上成功執行的關鍵方法。有多種方法可以做到這一點,要麼手動設定它們,要麼使用 Shell 指令碼。我們這裡需要執行的是透過菜譜設定它們。

要做到這一點,我們需要一個 cookbook,在這裡我們將使用 test_cookbook 和一個包含 test_cookbook 的執行列表。

使用 Chef 菜譜設定環境變數

步驟 1 − 使用環境變數更新 cookbook 的預設菜譜。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb  
ENV['MESSAGE'] = 'Testing environment variable update with chef !'  
execute 'print value of environment variable $MESSAGE' do 
   command 'echo $MESSAGE > /tmp/message' 
end

步驟 2 − 將更新後的 cookbook 上傳到伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload test_cookbook 
Uploading my_cookbook [0.1.0] 

步驟 3 − 執行 Chef 客戶端以建立臨時檔案。

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-01-25T15:01:57+00:00] INFO: Processing execute[print 
value of environment variable $MESSAGE] action run 
(my_cookbook::default line 11) 
[2013-01-25T15:01:57+00:00] INFO: execute[print value of 
environment variable $MESSAGE] ran successfully 
...TRUNCATED OUTPUT... 

驗證變數

user@server:~$ cat /tmp/message 
Hello from Chef

工作方法

Ruby 透過 ENV(一個雜湊表)公開當前的環境變數,以讀取和修改環境變數。

執行資源

我們可以在 cookbook 的 Chef 預設菜譜中使用 execute 資源來執行相同操作。

mma@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb  
execute 'print value of environment variable $MESSAGE' do 
   command 'echo $MESSAGE > /tmp/message' 
   environment 'MESSAGE' => 'Hello from the execute resource' 
end 

注意 − 使用 ENV 設定環境變數將使該變數在整個 Chef 執行過程中可用。相反,將其傳遞給 execute 資源只會使其對該資源執行的單個命令可用。

Chef - 資料包

Chef 資料包可以定義為任意資料集合,可以與 cookbook 一起使用。當不想在菜譜中硬編碼屬性或將屬性儲存在 cookbook 中時,使用資料包非常有用。

工作方法

在以下設定中,我們嘗試與 http 端點 URL 通訊。為此,我們需要建立一個數據包,它將儲存端點 URL 的詳細資訊並在我們的菜譜中使用它。

步驟 1 − 為我們的資料包建立一個目錄。

mma@laptop:~/chef-repo $ mkdir data_bags/hooks

步驟 2 − 為 request bin 建立一個數據包項。需要確保使用定義的 requestBin URL。

vipi@laptop:~/chef-repo $ subl data_bags/hooks/request_bin.json { 
   "id": "request_bin", 
   "url": "http://requestb.in/1abd0kf1" 
}

步驟 3 − 在 Chef 伺服器上建立資料包

vipin@laptop:~/chef-repo $ knife data bag create hooks 
Created data_bag[hooks] 

步驟 4 − 將資料包上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife data bag from file hooks requestbin.json 
Updated data_bag_item[hooks::RequestBin]

步驟 5 − 更新 cookbook 的預設菜譜以從資料包中接收所需的 cookbook。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/recipes/default.rb 
hook = data_bag_item('hooks', 'request_bin') 
http_request 'callback' do 
   url hook['url'] 
end 

步驟 6 − 將修改後的 cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload my_cookbook 
Uploading my_cookbook [0.1.0] 

步驟 7 − 在節點上執行 Chef 客戶端以檢查 http request bin 是否已執行。

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-02-22T20:37:35+00:00] INFO: http_request[callback] 
GET to http://requestb.in/1abd0kf1 successful 
...TRUNCATED OUTPUT...

工作原理

資料包是結構化資料條目的命名集合。需要定義資料條目並在 JSON 檔案中呼叫資料包項。還可以從菜譜中搜索資料包項以使用儲存在資料包中的資料。

我們建立了一個名為 hooks 的資料包。資料包是 Chef 儲存庫中的一個目錄。我們使用 knife 在伺服器上建立它。

Chef - 資料包指令碼

在某些情況下,無法將伺服器完全置於 Chef 的控制之下。在這種情況下,可能需要從指令碼中訪問 Chef 資料包中的值。為此,需要將資料包值儲存在 JSON 檔案中,並讓新增的指令碼訪問這些值。

為此,需要一個 cookbook。在我們的例子中,我們將像之前一樣使用 test_cookbook,並且節點的執行列表中應該包含 test_cookbook 定義。

工作方法

步驟 1 − 建立資料包。

vipin@laptop:~/chef-repo $ mkdir data_bags/servers 
vipin@laptop:~/chef-repo $ knife data bag create servers 
Created data_bag[servers] 

步驟 2 − 建立資料包項。

vipin@laptop:~/chef-repo $ subl data_bags/servers/Storage.json { 
   "id": "storage", 
   "host": "10.0.0.12" 
} 

步驟 3 − 更新資料包項。

vipin@laptop:~/chef-repo $ subl data_bags/servers/Storage.json { 
   "id": "storage", 
   "host": "10.0.0.12" 
} 

在 Cookbook 中使用

步驟 1 − 需要使用上述 cookbook 建立一個包含資料包值的 JSON 檔案,以便外部指令碼可以訪問這些值。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb 
file "/etc/backup_config.json" do 
   owner "root"
   group "root" 
   mode 0644 
   content data_bag_item('servers', 'backup')['host'].to_json 
end

步驟 2 − 將 test_cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload test_cookbook 
Uploading my_cookbook [0.1.0] 

步驟 3 − 在節點上執行 Chef 客戶端。

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-03-14T20:30:33+00:00] INFO: Processing 
file[/etc/backup_config.json] action create 
(my_cookbook::default line 9) 
[2013-03-14T20:30:34+00:00] INFO: entered create 
[2013-03-14T20:30:34+00:00] INFO: 
file[/etc/backup_config.json] owner changed to 0 
[2013-03-14T20:30:34+00:00] INFO: 
file[/etc/backup_config.json] group changed to 0 
[2013-03-14T20:30:34+00:00] INFO: 
file[/etc/backup_config.json] mode changed to 644 
[2013-03-14T20:30:34+00:00] INFO: 
file[/etc/backup_config.json] created file 
/etc/backup_config.json 
...TRUNCATED OUTPUT... 

步驟 4 − 驗證生成的 JSON 檔案的內容。

user@server:~$ cat /etc/backup_config.json 
"10.0.0.12" 

指令碼的工作流程

在上述命令中,我們使用的檔案資源在預設 cookbook 中定義,該資源在 /etc 目錄中建立 JSON 檔案。它使用 data_bag_item 方法直接從資料包獲取檔案內容。我們從資料包項訪問主機值並將其轉換為 JSON。檔案資源使用 JSON 轉換後的值作為其內容並將其寫入磁碟。

Chef - Cookbook 的跨平臺

跨平臺 cookbook 是那些採用其將要執行的基礎環境的 cookbook。Chef 提供了許多功能,有助於編寫能夠在任何將要部署的作業系統上執行的跨平臺 cookbook。這有助於開發人員編寫一個完全可操作的 cookbook。

為了做到這一點,我們需要一個 cookbook。在本例中,它將是 test_cookbook 和一個包含 cookbook 定義的執行列表。

工作方法

檢索節點平臺詳細資訊並在我們的 cookbook 中執行條件邏輯取決於平臺。在本例中,我們將對 Ubuntu 進行測試。

步驟 1 − 如果節點是 Ubuntu,則記錄一條訊息。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb 
Log.info("Running on ubuntu") if node.platform['ubuntu'] 

步驟 2 − 將 cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb 
Uploading my_cookbook [0.1.0] 
Uploaded 1 cookbook. 

步驟 3 − 在節點上執行 Chef 客戶端。

user@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
[2013-03-03T20:07:39+00:00] INFO: Running on Ubuntu 
...TRUNCATED OUTPUT...

或者,如果對特定平臺不感興趣,而只需要知道正在使用哪個宣告式平臺,則可以使用以下語句。

Log.info("Running on a debian derivative") if 
platform_family?('debian')

上傳修改後的 cookbook 並在 Ubuntu 節點上執行 Chef 客戶端將顯示以下結果。

[2013-03-03T20:16:14+00:00] INFO: Running on a debian 
derivative 

指令碼的工作流程

在上述命令中,Ohai 將發現節點作業系統的當前狀態,並將其作為平臺屬性與節點物件一起儲存。

node['platform'] 

或者,您可以使用方法樣式語法 −

node.platform 

設定特定於平臺的值

為了設定特定於平臺的值,chef 提供了便利方法 value_for_platform 和 value_for_platform_family。它們可以用來避免複雜的 case 語句,而是使用簡單的雜湊表。

示例 cookbook

execute "start-runsvdir" do 
   command value_for_platform( 
      "debian" => { "default" => "runsvdir-start" }, 
      "ubuntu" => { "default" => "start runsvdir" }, 
      "gentoo" => { "default" => "/etc/init.d/runit-start start" } 
   ) 
   action :nothing 
end 

在上面的示例中,命令是根據定義特定於作業系統的。

  • 對於 Debian,"runsvdir-start" 將起作用
  • 對於 Ubuntu,"start runsvdir" 將起作用
  • 對於 Gentoo,"/etc/init.d/runit-start" 將起作用

Chef - 資源

Chef 資源表示其期望狀態下的作業系統的一部分。它是一個配置策略的陳述,描述了節點的期望狀態,開發人員希望使用資源提供程式將當前配置遷移到該狀態。它有助於使用 Chef 的 Ohai 機制瞭解目標機器的當前狀態。它還有助於定義需要執行的步驟以使目標機器達到該狀態。資源分組在菜譜中,描述了工作配置。

在 Chef 的情況下,chef::Platform 對映每個節點的提供程式和平臺版本。在每次 Chef 客戶端執行開始時,Chef 伺服器都會收集任何機器當前狀態的詳細資訊。稍後,Chef 伺服器將使用這些值來識別正確的提供程式。

資源語法

type 'name' do 
   attribute 'value' 
   action :type_of_action 
end

在上述語法中,“type”是資源型別,“name”是我們將要使用的名稱。在“do”和“end”塊中,我們有該資源的屬性以及我們需要對該特定資源執行的操作。

我們在菜譜中使用的每個資源都有自己的一組操作,這些操作定義在“do”和“end”塊中。

示例

type 'name' do 
   attribute 'value' 
   action :type_of_action 
end 

所有資源共享一組通用的功能、操作、屬性、條件執行、通知和相關操作路徑。

操作 :nothing 操作可以與任何資源或自定義資源一起使用。
屬性 ignore_failure、provider、retries、retry_delay 和 supports 屬性可以與任何資源或自定義資源一起使用。
保護 not_if 和 only_if 條件執行可用於在某些資源周圍設定額外的保護,以便僅在滿足條件時才執行它們。
保護直譯器 使用基於指令碼的資源(bash、csh、perl、powershell_script、pythonruby)評估字串命令。
通知 notifies 和 subscribes 通知可以與任何資源一起使用。
相對路徑 #{ENV['HOME']} 相對路徑可以與任何資源一起使用。
Windows 檔案安全 template、file、remote_file、cookbook_file、directoryremote_directory 資源支援在菜譜中使用繼承和訪問控制列表 (ACL)。
在編譯階段執行 有時需要在每個其他資源之前或在將所有資源新增到資源集合之後執行資源。

可用資源

apt_package

使用 apt_package 資源來管理 Debian 和 Ubuntu 平臺的軟體包。

Bash

使用 bash 資源使用 Bash 直譯器執行指令碼。此資源還可以使用可用於 execute 資源的任何操作和屬性。使用此資源執行的命令(本質上)不是冪等的,因為它們通常對於執行它們的每個環境都是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

Batch

使用 batch 資源使用 cmd.exe 直譯器執行批處理指令碼。batch 資源建立並執行一個臨時檔案(類似於 script 資源的行為),而不是內聯執行命令。

此資源從 execute 資源繼承操作(:run 和 :nothing)和屬性(creates、cwd、environment、group、path、timeout 和 user)。使用此資源執行的命令(本質上)不是冪等的,因為它們通常對於執行它們的每個環境都是唯一的。使用 not_ifonly_if 來保護此資源以實現冪等性。

bff_package

使用 bff_package 資源使用 installp 實用程式管理 AIX 平臺的軟體包。當從本地檔案安裝軟體包時,必須使用 remote_filecookbook_file 資源將其新增到節點。

chef_gem

使用 chef_gem 資源僅為專用於 Chef 客戶端的 Ruby 例項安裝 gem。當從本地檔案安裝 gem 時,必須使用 remote_filecookbook_file 資源將其新增到節點。

chef_gem 資源與 gem_package 資源具有相同的屬性和選項,但它不接受 gem_binary 屬性,因為它始終使用 Chef-Client 執行所在的 CurrentGemEnvironment。除了執行類似於 gem_package 資源的操作外,chef_gem 資源還執行上述操作。

cookbook_file

使用 cookbook_file 資源將檔案從 COOKBOOK_NAME/files/ 的子目錄傳輸到執行 ChefClient 的主機上的指定路徑。

檔案根據檔案特異性進行選擇,這允許根據主機名、主機平臺(作業系統、發行版或適用情況)或平臺版本使用不同的原始檔。位於 COOKBOOK_NAME/files/default 子目錄中的檔案可以在任何平臺上使用。

Cron

使用 cron 資源管理用於基於時間的作業排程的 cron 條目。如果未提供計劃的屬性,則預設為 *。cron 資源需要訪問 crontab 程式,通常為 cron。

Csh

使用 csh 資源使用 csh 直譯器執行指令碼。此資源還可以使用 execute 資源可用的任何操作和屬性。

使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

Deploy

使用 deploy 資源管理和控制部署。這是一個很受歡迎的資源,但也很複雜,擁有最多的屬性、多個提供程式、回撥的額外複雜性,以及四個支援在配方中修改佈局的屬性。

Directory

使用 directory 資源管理目錄,目錄是包含儲存在計算機上的所有資訊的資料夾層次結構。根目錄是最高級別,其下組織了其餘的目錄。

directory 資源使用 name 屬性指定目錄中位置的路徑。通常,需要訪問目錄中該位置的許可權。

dpkg_package

使用 dpkg_package 資源管理 dpkg 平臺的軟體包。當從本地檔案安裝軟體包時,必須使用 remote_filecookbook_file 資源將其新增到節點。

easy_install_package

使用 easy_install_package 資源管理 Python 平臺的軟體包。

Env

使用 env 資源管理 Microsoft Windows 中的環境鍵。設定環境鍵後,必須重新啟動 Microsoft Windows 才能使任務計劃程式可以使用該環境鍵。

erl_call

使用 erl_call 資源連線到分散式 Erlang 系統中位於節點的節點。使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

Execute

使用 execute 資源執行單個命令。使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_ifonly_if 來保護此資源以實現冪等性。

檔案

使用 file 資源直接管理節點上的檔案。

freebsd_package

使用 freebsd_package 資源管理 FreeBSD 平臺的軟體包。

gem_package

使用 gem_package 資源管理僅包含在配方中的 gem 軟體包。當從本地檔案安裝軟體包時,必須使用 remote_filecookbook_file 資源將其新增到節點。

Git

使用 git 資源管理存在於 git 儲存庫中的原始碼控制資源。使用 git 資源的所有功能需要 git 1.6.5(或更高版本)。

Group

使用 group 資源管理本地組。

homebrew_package

使用 homebrew_package 資源管理 Mac OS X 平臺的軟體包。

http_request

使用 http_request 資源傳送帶有任意訊息的 HTTP 請求(GET、PUT、POST、DELETE、HEAD 或 OPTIONS)。當需要自定義回撥時,此資源通常很有用。

Ifconfig

使用 ifconfig 資源管理介面。

ips_package

使用 ips_package 資源管理 Solaris 11 平臺上(使用 Image Packaging System (IPS))的軟體包。

Ksh

使用 ksh 資源使用 Korn shell (ksh) 直譯器執行指令碼。此資源還可以使用 execute 資源可用的任何操作和屬性。

使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

Link

使用 link 資源建立符號連結或硬連結。

Log

使用 log 資源建立日誌條目。log 資源的行為與任何其他資源相同:在編譯階段構建到資源集合中,然後在執行階段執行。(要建立未構建到資源集合中的日誌條目,請使用 Chef::Log 而不是 log 資源)

macports_package

使用 macports_package 資源管理 Mac OS X 平臺的軟體包。

Mdadm

使用 mdadm 資源使用 mdadm 實用程式在 Linux 環境中管理 RAID 裝置。mdadm 提供程式將建立和組裝陣列,但它不會建立用於在重新引導時持久化陣列的配置檔案。

如果需要配置檔案,則必須透過使用具有正確陣列布局的模板指定它,然後使用 mount 提供程式建立檔案系統表 (fstab) 條目來完成。

Mount

使用 mount 資源管理已掛載的檔案系統。

Ohai

使用 ohai 資源重新載入節點上的 Ohai 配置。這允許更改系統屬性(例如新增使用者的配方)的配方在 chef-client 執行期間稍後引用這些屬性。

Package

使用 package 資源管理軟體包。當軟體包從本地檔案安裝(例如使用 RubyGems、dpkg 或 RPM 軟體包管理器)時,必須使用 remote_file 或 cookbook_file 資源將該檔案新增到節點。

pacman_package

使用 pacman_package 資源管理 Arch Linux 平臺上(使用 pacman)的軟體包。

powershell_script

使用 powershell_script 資源使用 Windows PowerShell 直譯器執行指令碼,這與使用指令碼和基於指令碼的資源(bash、csh、perl、python 和 ruby)的方式非常相似。powershell_script 特定於 Microsoft Windows 平臺和 Windows PowerShell 直譯器。

Python

使用 python 資源使用 Python 直譯器執行指令碼。此資源還可以使用 execute 資源可用的任何操作和屬性。

使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

Reboot

使用 reboot 資源重新引導節點,這是某些平臺上某些安裝的必要步驟。此資源支援在 Microsoft Windows、Mac OS X 和 Linux 平臺上使用。

registry_key

使用 registry_key 資源建立和刪除 Microsoft Windows 中的登錄檔項。

remote_directory

使用 remote_directory 資源將目錄從 cookbook 增量傳輸到節點。從 cookbook 複製的目錄應位於 COOKBOOK_NAME/files/default/REMOTE_DIRECTORY 下。

remote_directory 資源將遵循檔案特異性。

remote_file

使用 remote_file 資源使用檔案特異性從遠端位置傳輸檔案。此資源類似於 file 資源。

Route

使用 route 資源管理 Linux 環境中的系統路由表。

rpm_package

使用 rpm_package 資源管理 RPM 軟體包管理器平臺的軟體包。

Ruby

使用 ruby 資源使用 Ruby 直譯器執行指令碼。此資源還可以使用 execute 資源可用的任何操作和屬性。

使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

ruby_block

使用 ruby_block 資源在 Chef-Client 執行期間執行 Ruby 程式碼。ruby_block 資源中的 Ruby 程式碼在收斂期間與其他資源一起評估,而 ruby_block 資源外部的 Ruby 程式碼在其他資源之前進行評估,因為配方是在編譯時編寫的。

Script

使用 script 資源使用指定的直譯器(如 Bash、csh、Perl、Python 或 Ruby)執行指令碼。此資源還可以使用 execute 資源可用的任何操作和屬性。

使用此資源執行的命令(本質上)不是冪等的,因為它們通常對執行它們的特定環境是唯一的。使用 not_if 和 only_if 來保護此資源以實現冪等性。

Service

使用 service 資源管理服務。

smart_os_package

使用 smartos_package 資源管理 SmartOS 平臺的軟體包。

solaris_package

solaris_package 資源用於管理 Solaris 平臺的軟體包。

Subversion

使用 subversion 資源管理存在於 Subversion 儲存庫中的原始碼控制資源。

Template

使用 template 資源透過將檔案從 COOKBOOK_NAME/templates/ 的子目錄傳輸到執行 Chef-Client 的主機上的指定路徑,使用嵌入式 Ruby (ERB) 模板管理檔案的內容。此資源包含來自 file 資源的操作和屬性。由 template 資源管理的模板檔案遵循與 remote_file 和 file 資源相同的檔案特異性規則。

User

使用 user 資源新增使用者、更新現有使用者、刪除使用者以及鎖定/解鎖使用者密碼。

windows_package

使用 windows_package 資源管理 Microsoft Windows 平臺的 Microsoft Installer Package (MSI) 軟體包。

windows_service

使用 windows_service 資源管理 Microsoft Windows 平臺上的服務。

yum_package

使用 yum_package 資源使用 Yum 為 Red Hat 和 CentOS 平臺安裝、升級和刪除軟體包。yum_package 資源能夠解析軟體包的提供資料,就像從命令列執行 Yum 時一樣。這允許各種安裝軟體包的選項,例如最低版本、虛擬提供和庫名稱。

Chef - 輕量級資源提供程式

輕量級資源提供程式 (LWRP) 提供了一種擴充套件可用資源列表的選項,透過擴充套件其功能,並允許 Chef 使用者建立自定義資源。

透過建立自定義資源,可以更簡單地編寫 Cookbook,因為可以使用 Chef DSL 擁有豐富的自定義資源,這有助於使 Recipe 程式碼更具表現力。

在 Chef 社群中,許多自定義資源都是使用 LWRP 實現的。有許多 LWRP 的工作示例,例如iptables_rulesapt_repository

工作方法

確保您擁有名為 Testing_resource 的 Cookbook,以及包含 Testing_resource Cookbook 的節點的 run_list。

構建 LWRP

步驟 1 - 在 Testing_resource Cookbook 中建立自定義資源。

vipin@laptop:~/chef-repo $ subl cookbooks/Testing_resource/resources/default.rb 
actions :create, :remove 
attribute :title, kind_of: String, default: "World" 
attribute :path, kind_of: String, default: "/tmp/greeting.txt" 

步驟 2 - 為 Tesing_resource Cookbook 中的資源建立提供程式。

vipin@laptop:~/chef-repo $ subl cookbooks/Testing_resource/provider/default.rb 
action :create do 
   log "Adding '#{new_resource.name}' greeting as #{new_resource. 
      path}" 
   file new_resource.path do 
      content "#{new_resource.name}, #{new_resource.title}!" 
      action :create 
end  
action :remove do 
   Chef::Log.info "Removing '#{new_resource.name}' greeting #{new_resource.path}" 
   file new_resource.path do 
      action :delete 
   end 
end 

步驟 3 - 透過編輯 Testing_resource 預設 Recipe 來使用新的資源。

vipin@laptop:~/chef-repo $ subl cookbooks/Tesing_resource/recipes/default.rb 
greeting "Ohai" do 
   title "Chef" 
   action :create 
end 

步驟 4 - 將修改後的 Cookbook 上傳到 Chef 伺服器。

vipin@laptop:~/chef-repo $ knife cookbook upload greeting 
Uploading greeting [0.1.0] 

步驟 5 - 在節點上執行 Chef-Client。

vipin@server:~$ sudo chef-client 
...TRUNCATED OUTPUT... 
2013-06-28T21:32:54+00:00] INFO: Processing greeting[Ohai] action 
create (greeting::default line 9) 
[2013-06-28T21:32:54+00:00] INFO: Adding 'Ohai' greeting as /tmp/ 
greeting.txt 
[2013-06-28T21:32:54+00:00] INFO: Processing file[/tmp/greeting. 
txt] action create (/srv/chef/file_store/cookbooks/greeting/ 
providers/default.rb line 7) 
[2013-06-28T21:32:54+00:00] INFO: entered create 
[2013-06-28T21:32:54+00:00] INFO: file[/tmp/greeting.txt] created 
file /tmp/greeting.txt 
...TRUNCATED OUTPUT... 

步驟 6 - 驗證生成的檔案內容。

user@server:~$ cat /tmp/greeting.txt 
Ohai, Chef! 

工作流指令碼

LWRP 存在於 Cookbook 中。自定義資源位於 Cookbook 內部,並在 Cookbook 名稱下可用。在工作流中,我們首先定義定義,然後將屬性傳遞給將在 Cookbook 中使用的資源。最後,我們在 Recipe 中使用這些操作和屬性。

Chef - 藍圖

在 Chef 中,藍圖是查詢和記錄伺服器上究竟存在什麼的工具。藍圖記錄所有必需的事物,例如目錄、軟體包、配置檔案等。藍圖能夠以各種格式拆分伺服器資訊。其中之一是 Chef Recipe。這有助於使用 Chef 配置唯一的伺服器。

工作方法

我們需要在需要執行藍圖的節點上安裝 Python 和 Git。

步驟 1 - 安裝藍圖。

vipin@server:~$ pip install blueprint 

步驟 2 - 建立藍圖。

user@server:~$ sudo blueprint create internal-cookbook 
# [blueprint] using cached blueprintignore(5) rules 
# [blueprint] searching for Python packages 
# [blueprint] searching for PEAR/PECL packages 
# [blueprint] searching for Yum packages 
# [blueprint] searching for Ruby gems 
# [blueprint] searching for npm packages 
# [blueprint] searching for software built from source 
# [blueprint] searching for configuration files 
# [blueprint] /etc/ssl/certs/AC_Ra\xc3\xadz_Certic\xc3\ 
xa1mara_S.A..pem not UTF-8 - skipping it 
# [blueprint] /etc/ssl/certs/NetLock_Arany_=Class_Gold=_F\xc5\ 
x91tan\xc3\xbas\xc3\xadtv\xc3\xa1ny.pem not UTF-8 - skipping it 
# [blueprint] /etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sa\ 
xc4\x9flay\xc4\xb1c\xc4\xb1s\xc4\xb1.pem not UTF-8 - skipping it 
# [blueprint] /etc/ssl/certs/Certinomis_-_Autorit\xc3\xa9_Racine. 
pem not UTF-8 - skipping it 
# [blueprint] /etc/ssl/certs/T\xc3\x9cB\xc4\xb0TAK_UEKAE_K\xc3\ 
xb6k_Sertifika_Hizmet_Sa\xc4\x9flay\xc4\xb1c\xc4\xb1s\xc4\xb1_-_S\ 
xc3\xbcr\xc3\xbcm_3.pem not UTF-8 - skipping it 
# [blueprint] searching for APT packages 
# [blueprint] searching for service dependencies

步驟 3 - 從藍圖建立 Cookbook。

user@server:~$ blueprint show -C internal-cookbook my-server/recipes/default.rb

步驟 4 - 驗證生成的檔案內容。

user@server:~$ cat internal-cookbook /recipes/default.rb 
# 
# Automatically generated by blueprint(7). Edit at your own risk. 
# 
cookbook_file('/tmp/96468fd1cc36927a027045b223c61065de6bc575.tar') 
do 
   backup false 
   group 'root' 
   mode '0644' 
   owner 'root' 
   source 'tmp/96468fd1cc36927a027045b223c61065de6bc575.tar' 
end 
execute('/tmp/96468fd1cc36927a027045b223c61065de6bc575.tar') do 
   command 'tar xf "/tmp/96468fd1cc36927a027045b223c61065de6bc575.tar"' 
   cwd '/usr/local' 
end 
directory('/etc/apt/apt.conf.d') do 
...TRUNCATED OUTPUT... 
service('ssh') do 
   action [:enable, :start] 
   subscribes :restart, resources('cookbook_file[/etc/default/ 
      keyboard]', 'cookbook_file[/etc/default/console-setup]', 
      'cookbook_file[/etc/default/ntfs-3g]', 'package[openssh-server]', 
      'execute[96468fd1cc36927a027045b223c61065de6bc575.tar]') 
end

工作流指令碼

藍圖是一個 Python 包,它查詢伺服器的所有相關配置資料並將其儲存在 Git 倉庫中。每個藍圖都有自己的名稱。

您可以要求藍圖以各種格式顯示其 Git 倉庫的內容。

user@server:~$ ls -l internal-cookbook / 
total 8 
drwxrwxr-x 3 vagrant vagrant 4096 Jun 28 06:01 files 
-rw-rw-r-- 1 vagrant vagrant 0 Jun 28 06:01 metadata.rb 
drwxrwxr-x 2 vagrant vagrant 4096 Jun 28 06:01 recipes 

藍圖顯示命令

user@server:~$ blueprint show-packages my-server 
...TRUNCATED OUTPUT... 
apt wireless-regdb 2011.04.28-1ubuntu3 
apt zlib1g-dev 1:1.2.3.4.dfsg-3ubuntu4 
python2.7 distribute 0.6.45 
python2.7 pip 1.3.1 
pip blueprint 3.4.2 
pip virtualenv 1.9.1 

前面的命令顯示所有已安裝的軟體包。其他顯示命令如下:

  • show-files
  • show-services
  • show-sources

Chef - 檔案和包

在 Chef 中,建立配置檔案和移動軟體包是關鍵元件。Chef 管理相同內容的方式有多種。Chef 支援處理檔案和軟體包的方式有多種。

從第三方倉庫安裝軟體包

步驟 1 - 編輯 Cookbook 的預設 Recipe。

vipin@laptop:~/chef-repo $ subl cookbooks/test_cookbook/recipes/default.rb 
include_recipe "apt" 
apt_repository "s3tools" do 
   uri "http://s3tools.org/repo/deb-all" 
   components ["stable/"] 
   key "http://s3tools.org/repo/deb-all/stable/s3tools.key" 
   action :add 
end 
package "s3cmd"

步驟 2 - 編輯元資料以新增對 apt Cookbook 的依賴項。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/metadata.rb 
... 
depends "apt"

步驟 3 - 將修改後的 Cookbook 上傳到 Chef 伺服器。

步驟 4 - 驗證您嘗試安裝的軟體包是否尚未安裝。

步驟 5 - 驗證預設倉庫。

步驟 6 - 在節點上執行 Chef-Client。

步驟 7 - 驗證所需的軟體包是否已安裝。

從原始碼安裝軟體

如果需要安裝某個特定平臺上沒有作為軟體包提供的軟體,則需要自行編譯。在 Chef 中,我們可以使用 script 資源來做到這一點。

步驟 1 - 編輯預設 Recipe。

vipin@laptop:~/chef-repo $ subl cookbooks/my_cookbook/recipes/ 
default.rb 
version = "1.3.9" 
bash "install_nginx_from_source" do 
   cwd Chef::Config['file_cache_path'] 
   code ≪-EOH 
      wget http://nginx.org/download/nginx-#{version}.tar.gz 
      tar zxf nginx-#{version}.tar.gz && 
      cd nginx-#{version} && 
      ./configure && make && make install 
   EOH 

步驟 2 − 將修改後的 cookbook 上傳到 Chef 伺服器。

步驟 3 - 在節點上執行 Chef-Client。

步驟 4 - 驗證 nginx 是否已安裝。

Chef - 社群菜譜

社群 Cookbook 與任何其他 Cookbook 類似。之所以稱為社群 Cookbook,僅僅是因為任何知道如何編寫 Cookbook 的人都可以加入這個社群並將他們的 Cookbook 上傳到集中式中心。這些 Cookbook 可免費使用,任何人都可以下載和使用。為了使用這些社群 Cookbook,您需要下載它們,根據需要修改它們,然後將它們上傳到各自的 Chef 伺服器。

您需要在系統上配置 knife 才能更新、上傳和下載 Cookbook。使用 knife cookbook 命令與 Cookbook 互動。使用 knife cookbook,您可以建立、刪除、顯示、列出、下載和上傳 Cookbook。請閱讀第 7 章中有關 knife cookbook 命令的更多資訊。

以下是社群 Cookbook 的連結:https://supermarket.chef.io/cookbooksdirectory

Community
廣告