- Chef 教程
- Chef - 首页
- Chef - 概述
- Chef - 架构
- Chef - 版本控制系统设置
- Chef - 工作站设置
- Chef - 客户端设置
- Chef - 测试厨房设置
- Chef - Knife 设置
- Chef - Solo 设置
- Chef - 菜谱(Cookbooks)
- Chef - 菜谱依赖关系
- Chef - 角色
- Chef - 环境
- Chef - Chef-Client 作为守护进程
- Chef - Chef-Shell
- Chef - 测试菜谱
- Chef - Foodcritic
- Chef - ChefSpec
- 使用测试厨房测试菜谱
- Chef - 节点
- Chef - Chef-Client 运行
- 高级 Chef
- 动态配置菜谱
- Chef - 模板
- Chef - Chef DSL 中的纯 Ruby
- Chef - 菜谱中的 Ruby Gems
- Chef - 库
- Chef - 定义
- Chef - 环境变量
- Chef - 数据包
- Chef - 数据包脚本
- Chef - 跨平台菜谱
- Chef - 资源
- 轻量级资源提供程序
- Chef - 蓝图
- Chef - 文件和包
- Chef - 社区菜谱
- Chef 有用资源
- Chef 快速指南
- Chef - 有用资源
- Chef - 讨论
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 基础设施正常工作,我们需要按顺序设置多项内容。
在上述设置中,我们有以下组件。
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 [email protected]: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 - 按照安装步骤,将其安装到目标位置。
安装程序将如下面的屏幕截图所示。
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 工作流中涉及的步骤。
使用 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 结构。
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 [email protected]: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 结构将在目录中创建,并且以下将是其结构。
使用 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 的结构。
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 的配置
以下是元数据文件的默认内容。
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 和普通更高的属性优先级。覆盖属性最常在菜谱中定义,但也可以在角色或环境的属性文件中指定。
应用属性的顺序
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.cn' gem 'foodcritic', '~>2.2.0'
步骤 2 − 安装 gem。
vipin@laptop:~/chef-repo $ bundle install Fetching gem metadata from https://rubygems.org.cn/ ...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.cn' gem 'chefspec'
步骤 2 − 安装 gem。
vipin@laptop:~/chef-repo $ bundler install Fetching gem metadata from https://rubygems.org.cn/ ...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.cn' gem 'knife-preflight'
步骤 2 − 运行 bundler 以安装 knife-preflight gem。
vipin@laptop:~/chef-repo $ bundle install Fetching gem metadata from https://rubygems.org.cn/ ...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、python 或 ruby)评估字符串命令。 |
通知 | notifies 和 subscribes 通知可以与任何资源一起使用。 |
相对路径 | #{ENV['HOME']} 相对路径可以与任何资源一起使用。 |
Windows 文件安全 | template、file、remote_file、cookbook_file、directory 和 remote_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_if 和 only_if 来保护此资源以实现幂等性。
bff_package
使用 bff_package 资源使用 installp 实用程序管理 AIX 平台的软件包。当从本地文件安装软件包时,必须使用 remote_file 或 cookbook_file 资源将其添加到节点。
chef_gem
使用 chef_gem 资源仅为专用于 Chef 客户端的 Ruby 实例安装 gem。当从本地文件安装 gem 时,必须使用 remote_file 或 cookbook_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_file 或 cookbook_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_if 和 only_if 来保护此资源以实现幂等性。
文件
使用 file 资源直接管理节点上的文件。
freebsd_package
使用 freebsd_package 资源管理 FreeBSD 平台的软件包。
gem_package
使用 gem_package 资源管理仅包含在配方中的 gem 软件包。当从本地文件安装软件包时,必须使用 remote_file 或 cookbook_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_rules 和apt_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 https://nginxserver.cn/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