创建您的第一本Chef Cookbook

2018-09-21 14:49:23 浏览数 (1)

Cookbook是Chef框架的关键组成部分之一,其描述了相关节点的所需状态,并允许Chef推送需达到该状态的更改数据。由于需要进行配置的选项和区域数量众多,第一眼看上去,创建一本Cookbook是一项艰巨的任务,因此在本指南中我们将介绍通常人们在学习其配置的第一件事:设置LAMP(Linux Apache MySQL/MariaDB/Percona PHP)软件环境。

在使用本指南之前,请先参照“ 设置Chef服务器,workstation工作站和相关节点”这一指南来设置Chef。在遵循该指南时,请选择Ubuntu 16.04作为Chef节点的Linux映像。必须选择该版本的Ubuntu是因为将使用的MySQL Chef cookbook与Ubuntu 18.04尚不兼容。

如果觉得有必要的话,您也可以先查看Chef新手指南。

本教程中的示例需要root用户账户权限。选择使用普通用户帐户的读者在使用Chef客户端节点时,很可能会需要使用sudo前缀命令。如果您尚未创建普通用户帐户,请按照“ 保护服务器”  指南中的步骤进行操作。

创建Cookbook

  1. 在workstation工作站中,定位到chef-repo分支下的cookbooks目录: cd chef-repo/cookbooks
  2. 创建cookbook。在这个例子中,cookbook的标题是lamp_stackchef generate cookbook lamp_stack
  3. 定位到cookbook新创建的目录下: cd lamp_stack
  4. 对位于新创建的cookbook中的文件列表,以查看是否已创建了相关目录和文件: ls
代码语言:txt复制
Berksfile CHANGELOG.md chefignore LICENSE metadata.rb README.md recipes spec test

有关这些目录的更多配置方案,请参阅Chef框架初学者指南。

default.rb

recipes中的default.rb文件包含“默认”的recipe资源配置方案。

因为LAMP环境的每个部分(Apache、MySQL和PHP)都有属于自己的recipe配置方案,所以该default.rb文件也就是为服务器所准备的。

  • 1.在您的lamp_stack目录中,定位到recipes文件夹: cd recipes
  • 2.打开default.rb文件并添加下面可以实现系统更新的Ruby命令:
代码语言:txt复制
#
# Cookbook Name:: lamp_stack
# Recipe:: default
#
#

execute "update-upgrade" do
  command "sudo apt-get update && sudo apt-get upgrade -y"
  action :run
end

recipe配置方案是由一系列的资源组成。在该例中,使用的是执行资源,其会调用一个执行一次的命令。command部分定义了apt-get update && apt-get upgrade -y指令,action操作设置为:run执行命令。

这是一个比较容易编写的Chef recipe配置方案,也是一个好的初步实践文件。其他你认为比较重要的启动步骤也可以通过模仿上述代码模板来添加到文件中。

  • 3.假如需要测试recipe配置方案,请将LAMP环境中的cookbook添加到Chef服务器: knife cookbook upload lamp_stack
  • 4.测试recipe配置方案是否已添加到Chef服务器: knife cookbook list
  • 5.将recipe添加到所选节点的运行列表中,并将nodename替换为相应节点名称: knife node run_list add nodename "recipe[lamp_stack]" 因为这是默认recipe配置方案,所以不需要在上面的代码中的lamp_stackcookbook之后来定义recipe名称。
  • 6.访问您选择的节点并运行chef-clientchef-client 它应该输出Chef的成功运行配置方案。如果没有,请查看代码以查找错误,通常它们会在chef-client运行输出中定义。

Apache

安装并启用

  • 1.在Chef workstation工作站中,在~/chef-repo/cookbooks/lamp_stack/recipes目录下创建一个新文件apache.rb,该文件将包含所有Apache配置方案。
  • 2.打开文件,并定义用于安装Apache的资源:
代码语言:txt复制
package "apache2" do
  action :install
end

同样,这是一个非常基础的recipe配置方案。包资源会调用相应包(apache2)。包名称值必须是一个合法的包名称。操作设置为install是因为在此步骤中执行了Apache安装操作,这里无需附加操作就可与运行安装操作。

  • 3.允许Apache服务并设置重启时运行。在同一个文件中,添加附加代码:
代码语言:txt复制
service "apache2" do
  action [:enable, :start]
end

这使用服务资源,该服务资源将调用Apache服务。enable使能操作使得它在开机时可以使用,并在_启动_Apache时启动。

保存并关闭该apache.rb文件。

  • 4.如果需要测试Apache recipe配置方案,请更新服务器上的LAMP软件环境上的recipe配置方案: knife cookbook upload lamp_stack
  • 5.将recipe添加到所选节点的运行列表中,并将nodename替换为相应节点名称: knife node run_list add nodename "recipelamp_stack::apache" 因为这不是default.rb默认recipe配置方案,其名称apache必须附加到recipe值。
  • 6.从该节点运行chef-clientchef-client 如果由于语法错误导致配方失败,Chef将在输出期间标注它。
  • 7.chef-client运行成功后,请检查Apache是否正在运行: systemctl status apache2 它的配置方案输出应该表明apache2正在运行。

注意 重复5-7步来上传cookbook并根据本文剩余部分指引按需运行chef客户端来确保您的recipe配方能正常无错运行。在添加一个新的recipe时,请记得替换运行列表中的recipe名。

配置虚拟主机

此配置基于如何在Ubuntu 16.04上安装LAMP软件环境一文。

  • 1.因为可能会需要配置多个网站,因此请使用Chef的属性功能来定义虚拟主机文件的特定内容。ChefDK(chef软件工具包)中有一个内置命令,可以在cookbook中生成属性目录和default.rb文件。请将~/chef-repo/cookbooks/lamp_stack替换为你的cookbook路径: chef generate attribute ~/chef-repo/cookbooks/lamp_stack default
  • 2.在新的default.rb文件中,创建cookbook的默认值:
代码语言:txt复制
default["lamp_stack"]["sites"]["example.com"] = { "port" => 80, "servername" => "example.com", "serveradmin" => "webmaster@example.com" }

前缀default中内容定义了example.com网站将会在lamp_stack中进行调用的值。这也可以看作是一种层次结构:在cookbook下层的是基于URL地址定义的网站。

紧随之后的数组中的值(在大括号({})中定义的)就是用来设置虚拟主机文件的值。Apahce被设置为在80端口监听并使用列表中的值作为服务名和管理员权限邮箱。

假如有需要添加超过一个网站或URL地址(例如,example.org),第二个URL地址也应该模仿上例:

代码语言:txt复制
default["lamp_stack"]["sites"]["example.com"] = { "port" => 80, "servername" => "example.com", "serveradmin" => "webmaster@example.com" }
default["lamp_stack"]["sites"]["example.org"] = { "port" => 80, "servername" => "example.org", "serveradmin" => "webmaster@example.org" }
  • 3.返回recipes目录下的apach.rb文件调用之前定义的属性。使用node资源执行此操作:
代码语言:txt复制
# 安装并使能Apache

package "apache2" do
  action :install
end

service "apache2" do
  action [:enable, :start]
end


# 虚拟主机文件

node["lamp_stack"]["sites"].each do |sitename, data|
end

该文件会调用["lamp_stack"]["sites"]下的对应值。sitename定义的对应值将会生成对应的添加代码块。data值会调用每个sitename属性数组中列出的值。

  • 4.请在node资源中定义文档根路径。将会使用该根路径来定义公共HTML文件和一些自动生成的日志文件:
代码语言:txt复制
node["lamp_stack"]["sites"].each do |sitename, data|
  document_root = "/var/www/html/#{sitename}"
end
  • 5.这种操作并不会创建目录本身。为了创建目录,我们可以使用directory资源并结合true递归值来创建所有定向到sitename的目录。权限值0755表明允许文件所有者具有对目录的完全访问权限,而组和常规用户将仅具有读取和执行权限:
代码语言:txt复制
node["lamp_stack"]["sites"].each do |sitename, data|
  document_root = "/var/www/html/#{sitename}"

  directory document_root do
    mode "0755"
    recursive true
  end

end
  • 6.这里将会使用模板功能来自动生成所需的虚拟主机文件。在chef-repo目录下携带cookbook路径和定义的模板文件名来运行chef generate template命令: chef generate template ~/chef-repo/cookbooks/lamp_stack virtualhosts
  • 7.打开并编辑virtualhosts.erb文件。请以Ruby变量来写入虚拟主机参数而不是以直接写入实际值的方式,Ruby变量由<%= @variable_name %>语法标识,所使用的变量名称需要在recipe文件中定义过:
代码语言:txt复制
<VirtualHost *:<%= @port %>>
        ServerAdmin <%= @serveradmin %>
        ServerName <%= @servername %>
        ServerAlias www.<%= @servername %>
        DocumentRoot <%= @document_root %>/public_html
        ErrorLog <%= @document_root %>/logs/error.log
        <Directory <%= @document_root %>/public_html>
                Require all granted
        </Directory>
</VirtualHost>

你可能会觉得有些变量似曾相识,其实它们是在第二步中创建的默认变量。

  • 8.回到apache.rb recipe文件。在directory资源之后,使用template资源调用刚刚创建的模板文件:
代码语言:txt复制
# 虚拟主机文件

node["lamp_stack"]["sites"].each do |sitename, data|
  document_root = "/var/www/html/#{sitename}"

  directory document_root do
    mode "0755"
    recursive true
  end

  template "/etc/apache2/sites-available/#{sitename}.conf" do
    source "virtualhosts.erb"
    mode "0644"
    variables(
      :document_root => document_root,
      :port => data["port"],
      :serveradmin => data["serveradmin"],
      :servername => data["servername"]
    )
  end

end

模板资源的名称应该是虚拟主机文件放置在节点上的位置。source就是模板文件的名称。Mode 0644赋予文件所有者读写权限,其他人都仅有读取权限。variables部分中定义的值取自属性文件,它们与模板中调用的值相同。

  • 9.现在需要在Apache中启用站点,并重新启动服务器。只有在虚拟主机发生更改时,才可以将notifies值应将该值添加到template资源中。当事务发生变化时,notifies会告诉Chef,并在此情况下才会运行以下命令:
代码语言:txt复制
template "/etc/apache2/sites-available/#{sitename}.conf" do
  source "virtualhosts.erb"
  mode "0644"
  variables(
    :document_root => document_root,
    :port => data["port"],
    :serveradmin => data["serveradmin"],
    :servername => data["servername"]
  )
  notifies :restart, "service[apache2]"
end

notifies命令命名了要提交:action的操作,之后在对资源和方括号中的资源名进行操作。

  • 10.notifies也可以调用execute命令,execute命令可以运行a2ensite并启用我们为其创建的虚拟主机文件的站点。添加下面的execute命令到template资源代码中并创建a2ensite脚本
代码语言:txt复制
# [...]

directory document_root do
  mode "0755"
  recursive true
end

execute "enable-sites" do
  command "a2ensite #{sitename}"
  action :nothing
end

template "/etc/apache2/sites-available/#{sitename}.conf" do

# [...]

action :nothing指令表明相关资源将会等待已被调用。在之前template资源中的notifies代码段前添加新的notifies代码:

代码语言:txt复制
# [...]

template "/etc/apache2/sites-available/#{sitename}.conf" do
  # [...]
  notifies :run, "execute[enable-sites]"
  notifies :restart, "service[apache2]"
end

# [...]
  • 11.这里需要创建虚拟主机文件中所指向的路径。再强调一次,这里必须在directory资源下操作,并且必须在最后的end标签前添加完成。
代码语言:txt复制
# [...]

node["lamp_stack"]["sites"].each do |sitename, data|
  # [...]

  directory "/var/www/html/#{sitename}/public_html" do
    action :create
  end

  directory "/var/www/html/#{sitename}/logs" do
    action :create
  end
end

Apache配置

配置虚拟主机文件并启用网站后,请配置Apache以让其在服务器上高效运行,启用和配置多处理模块(MPM)并编辑apache2.conf

MPM都位于Apache的mods_available 目录中。在此示例中,将使用位于/etc/apache2/mods-available/mpm_event.conf下的eventMPM。如果我们计划部署到不同大小的节点,我们将创建一个模板文件来替换原始节点,这将允许更多自定义特定变量。在此例中,将使用cookbook文件来编辑模板文件。

Cookbook文件是对服务器上相同语言环境中的文档进行操作的静态文档。如果进行了任何更改,则cookbook文件会备份原始文件并将其替换为新文件。

  • 1.在您的cookbook主目录下定位到files/default来创建一个cookbook文件。如果目录尚不存在,请创建它们:
代码语言:txt复制
mkdir -p ~/chef-repo/cookbooks/lamp_stack/files/default/
cd ~/chef-repo/cookbooks/lamp_stack/files/default/
  • 2.创建一个名为mpm_event.conf的文件并将MPM事件配置复制到其中,更改所需的值:
代码语言:txt复制
<IfModule mpm_event_module>
        StartServers        2
        MinSpareThreads     6
        MaxSpareThreads     12
        ThreadLimit         64
        ThreadsPerChild     25
        MaxRequestWorkers   25
        MaxConnectionsPerChild  3000
</IfModule>
  • 3.返回到apache.rb文件,并使用该cookbook_file资源调用我们刚刚创建的文件。因为需要启用MPM,所以我们将再次使用notifies命令,这次执行a2enmod mpm_event。在end标记之前将executecookbook_file资源添加到apache.rb文件中:
代码语言:txt复制
# [...]

node["lamp_stack"]["sites"].each do |sitename, data|
  # [...]

  execute "enable-event" do
    command "a2enmod mpm_event"
    action :nothing
  end

  cookbook_file "/etc/apache2/mods-available/mpm_event.conf" do
    source "mpm_event.conf"
    mode "0644"
    notifies :run, "execute[enable-event]"
  end
end
  • 4.请将apache2.conf文件中的KeepAlive值设置为off,这也是文件中做出的唯一更改地方。这可以通过模板或cookbook文件进行更改,但在此例中可以使用一个简单的sed命令来与execute资源配对。使用新execute资源来对apache.rb更新:
代码语言:txt复制
# [...]

directory "/var/www/html/#{sitename}/logs" do
  action :create
end

execute "keepalive" do
  command "sed -i 's/KeepAlive On/KeepAlive Off/g' /etc/apache2/apache2.conf"
  action :run
end

execute "enable-event" do

# [...]

您的apache.rb文件现在完成了。最终的示例文件在此处。

MySQL

下载MySQL库

  • 1.Chef 市场有一个OpsCode维护的MySQL cookbook,其可以用于设置要使用的MySQL 轻量级资源/供应商(LWRP)。请从工作站下载并安装该cookbook:knife cookbook site install mysql此处还将安装使用cookbook所需的相关依赖项。这些依赖包括smfyum-mysql-communitycookbook,而它们又依赖于rbacyumcookbook。
  • 2.从LAMP环境中cookbook的主目录,打开metadata.rb文件并为MySQL cookbook添加依赖项:
代码语言:txt复制
depends          'mysql', '~> 8.5.1'

注意 请查看MySQL Cookbook的市场页面,确保这是该手册的最新版本。同时MySQL Cookbook还不支持Ubuntu 18.04。

  • 3.将这些cookbook上传到服务器: knife cookbook upload mysql --include-dependencies

创建并加密您的MySQL密码

Chef包含一个称为数据包的功能。数据包存储配置方案,并且可以加密相关配置方案以存储密码和其他敏感数据。

  • 1.在工作站上,生成一个密钥:openssl rand -base64 512 > ~/chef-repo/.chef/encrypted_data_bag_secret
  • 2.将此密钥上传到节点的/etc/chef目录,可以手动通过scp(可以在“ 设置Chef”指南中找到示例)来执行,也可以通过使用recipe和cookbook文件来更新。
  • 3.在工作站上,创建一个包含root密码的rtpass.json文件的mysql数据包:
代码语言:txt复制
knife data bag create mysql rtpass.json --secret-file ~/chef-repo/.chef/encrypted_data_bag_secret

注意 某些knife命令要求使用文本编辑器将配置方案编辑为JSON数据格式。您的knife.rb文件应包含用于此类命令的文本编辑器的配置。如果您的knife.rb文件尚未包含此配置,请添加knife[:editor] = "/usr/bin/vim"到文件底部以将vim设置为默认文本编辑器。

系统将要求您编辑rtpass.json文件:

代码语言:txt复制
{
  "id": "rtpass.json",
  "password": "password123"
}

请将password123替换为安全密码。

  • 4.确认rtpass.json文件已创建: knife data bag show mysql 它应该输出rtpass.json。如果需要确保它是加密的,请运行: knife data bag show mysql rtpass.json 由于加密,输出将无法读取有效配置方案,并且应类似于:
代码语言:txt复制
WARNING: Encrypted data bag detected, but no secret provided for decoding. Displaying encrypted data.
id: rtpass.json
password:
cipher: aes-256-cbc
encrypted_data: wpEAb7TGUqBmdB1TJA/5vyiAo2qaRSIF1dRAc vkBhQ=

iv: E5TbF 9thH9amU3QmGxWmw==

version: 1
user:
cipher: aes-256-cbc
encrypted_data: VLA00Wrnh9DrZqDcytvo0HQUG0oqI6 6BkQjHXp6c0c=

iv: 6V 3ROpW9RG /honbf/RUw==

version: 1

设置MySQL

下载MySQL库并准备好加密的root密码后,您现在可以设置下载和配置MySQL的recipe。

  • 1.在recipes中打开一个mysql.rb新文件并定义将要使用的数据包:
代码语言:txt复制
mysqlpass = data_bag_item("mysql", "rtpass.json")
  • 2.因为MySQL cookbook提供了LWRP,所以MySQL的初始安装和数据库创建可以在一个资源中完成:
代码语言:txt复制
mysqlpass = data_bag_item("mysql", "rtpass.json")

mysql_service "mysqldefault" do
  version '5.7'
  initial_root_password mysqlpass["password"]
  action [:create, :start]
end

mysqldefault是此容器的MySQL服务的名称。在创建数据库并启动MySQL服务的同时,inital_root_password会调用上文中定义的相关值。

注意 从节点运行MySQL时,您需要定义套接字: mysql -S /var/run/mysql-mysqldefault/mysqld.sock -p

PHP

  • 1.在recipes目录下,创建一个新文件php.rb。使用以下命令安装PHP以及Apache和MySQL所需的所有软件包:
代码语言:txt复制
package "php" do
  action :install
end

package "php-pear" do
  action :install
end

package "php-mysql" do
  action :install
end
  • 2.为了便于配置,创建php.ini文件并将其用作cookbook文件,就像上面的MPM模块一样。你可以:
    • 添加PHP recipe,从节点(位于/etc/php/7.0/cli/php.ini)中运行chef-client和复制文件,或者:
    • 从chef-php.ini示例中复制文件,该文件应移动到chef-repo/cookbooks/lamp_stack/files/default/目录下。如果需要更好适配您的配置,也可以将其转换为模板。
  • 3.php.ini是一个大型文件,搜索并编辑以下值来适配您的Linode主机。下面建议的值适用于2GB Linode主机:
代码语言:txt复制
max_execution_time = 30
memory_limit = 128M
error_reporting = E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
max_input_time = 30
  • 4.返回php.rb文件并将cookbook_file资源附加到recipe的末尾:
代码语言:txt复制
cookbook_file "/etc/php/7.0/cli/php.ini" do
  source "php.ini"
  mode "0644"
  notifies :restart, "service[apache2]"
end
  • 5.因为对php.ini文件进行了修改,所以需要创建/var/log/php目录并将其所有权设置为Apache用户。这是通过notifies命令和execute资源完成的,如前所述。将这些资源附加到以下php.rb末尾:
代码语言:txt复制
execute "chownlog" do
  command "chown www-data /var/log/php"
  action :nothing
end

directory "/var/log/php" do
  action :create
  notifies :run, "execute[chownlog]"
end

PHP recipe配置方案现已完成!在此处查看php.rb文件的示例。

  • 6.确保您的Chef服务器包含更新的cookbook,并且您的节点的运行列表是最新的。请将nodename替换为Chef节点的名称:
代码语言:txt复制
knife cookbook upload lamp_stack
knife node run_list add nodename "recipe[lamp_stack],recipe[lamp_stack::apache],recipe[lamp_stack::mysql],recipe[lamp_stack::php]"

您刚刚创建了LAMP 环境 cookbook。通过本指南,您应该已经学会使用recipe配方中的执行、

包、服务、节点、目录、模板、cookbook_file和mysql_service资源,以及下载和使用LWRP,创建加密数据包,上传/更新您的cookbook到服务器,还有使用属性、模板、cookbook文件。这些将为您在未来项目中创建Chef和cookbook奠定坚实的基础。

更多配置方案

有关此主题的其他配置方案,您可能需要参考以下资源。虽然我们希望提供的是有效资源,但请注意,我们无法保证外部托管材料的准确性或及时性。

  • Chef
lampapache云数据库 SQL Serverphplampapache云数据库 SQL Serverphp

0 人点赞