

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 OpsWorks Stacks Linux 实例上运行配方
<a name="cookbooks-101-opsworks-opsworks-instance"></a>

**重要**  
该 AWS OpsWorks Stacks 服务于 2024 年 5 月 26 日终止，新客户和现有客户均已禁用。我们强烈建议客户尽快将其工作负载迁移到其他解决方案。如果您对迁移有疑问，请通过 re [AWS : Post 或通过 Pre](https://repost.aws/) mium Su [AWS pp](https://aws.amazon.com/support) ort 与 AWS 支持 团队联系。

Test Kitchen and Vagrant 提供了一种简单而有效的方法来实现食谱，但是要验证食谱的食谱能否在生产中正常运行，你必须在 Stacks 实例 OpsWorks 上运行它们。本主题介绍如何在 OpsWorks Stacks Linux 实例上安装自定义说明书并运行简单的配方。本主题还提供了一些高效修复配方错误的提示。

有关如何在 Windows 实例上运行配方的说明，请参阅[在 Windows 实例上运行配方](cookbooks-101-opsworks-opsworks-windows.md)。

**Topics**
+ [创建和运行配方](#opsworks-opsworks-instance-create)
+ [自动执行配方](#cookbooks-101-opsworks-opsworks-instance-events)
+ [排查并修复配方问题](#cookbooks-101-opsworks-opsworks-instance-bugs)

## 创建和运行配方
<a name="opsworks-opsworks-instance-create"></a>

首先，您需要创建一个堆栈。下面简要总结了如何为本示例创建堆栈。有关更多信息，请参阅 [创建新堆栈](workingstacks-creating.md)。

**创建堆栈**

1. 打开 [OpsWorks Stacks 控制台](https://console.aws.amazon.com/opsworks/)，然后单击 **Add Stack (添加堆栈)**。

1. 指定以下设置，接受其他设置的默认值，然后单击 **Add Stack**。
   + **姓名** — OpsTest
   + **默认 SSH 密钥** — Amazon EC2 密钥对

   如果您需要创建亚马逊 EC2 密钥对，请参阅[亚马逊 EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。请注意，该密钥对必须属于与实例相同的 Amazon Web Services Region。本示例使用了默认的美国西部（俄勒冈州）区域。

1. 单击 **Add a layer** 并将采用以下设置的[自定义层添加到](workinglayers-custom.md)堆栈。
   + **姓名** — OpsTest
   + **短名称 **- opstest

   实际上任何层类型均适用于 Linux 堆栈，但本示例不需要由其他层类型安装的任何程序包，因此自定义层是最简单的方法。

1. 向层[添加全天候实例](workinginstances-add.md) (采用默认设置) 并[启动该实例](workinginstances-starting.md)。

当实例正在启动时(通常需要几分钟)，您可以创建说明书。本示例将使用的配方是在[条件逻辑](cookbooks-101-basics-ruby.md#cookbooks-101-basics-ruby-conditional)中的配方的基础上稍作修改得来的，该配方将创建一个名称取决于平台的数据目录。

**设置说明书**

1. 在 `opsworks_cookbooks` 中创建一个名为 `opstest` 的目录并导航到该目录。

1. 创建一个包含以下内容的 `metadata.rb` 文件，并将该文件保存到 `opstest`。

   ```
   name "opstest"
   version "0.1.0"
   ```

1. 在 `recipes` 中创建 `opstest` 目录。

1. 创建包含以下配方的 `default.rb` 文件，并将该文件保存到 `recipes` 目录。

   ```
   Chef::Log.info("******Creating a data directory.******")
   
   data_dir = value_for_platform(
     "centos" => { "default" => "/srv/www/shared" },
     "ubuntu" => { "default" => "/srv/www/data" },
     "default" => "/srv/www/config"
   )
   
   directory data_dir do
     mode 0755
     owner 'root'
     group 'root'
     recursive true
     action :create
   end
   ```

   请注意，配方会记录消息，但它是通过调用 `Chef::Log.info` 来实现的。在这个例子中，你没有使用 Test Kitchen，所以这个`log`方法不是很有用。 `Chef::Log.info`将消息放入 Chef 日志，你可以在 Chef 运行完成后阅读该日志。 OpsWorks 如后面所述，Stacks 提供了一种查看这些日志的简便方法。
**注意**  
Chef 日志通常包含大量例程和相对无关的信息。“\$1”字符会将消息文本括起来，使其更容易被发现。

1. 创建 `opsworks_cookbooks` 的 `.zip` 存档。要在 OpsWorks Stacks 实例上安装您的食谱，您必须将其存储在存储库中，并向 OpsWorks Stacks 提供将食谱下载到该实例所需的信息。您可以将说明书存储在任一受支持的存储库类型中。本实例会将包含说明书的存档文件存储在 Amazon S3 存储桶中。有关说明书存储库的更多信息，请参阅[说明书存储库](workingcookbook-installingcustom-repo.md)。
**注意**  
为简单起见，本示例仅存档整个 `opsworks_cookbooks` 目录。但是，这意味着 OpsWorks Stacks 会将所有食谱下载`opsworks_cookbooks`到实例中，尽管你只会使用其中一本。要仅安装示例说明书，请创建另一个父目录并将 `opstest` 移动到该目录。然后创建该父目录的 `.zip` 存档，并用它代替 `opsworks_cookbooks.zip`。  
发送到 Amazon S3 存储桶的内容可能包含客户内容。有关删除敏感数据的更多信息，请参阅[如何清空 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/empty-bucket.html)或[如何删除 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html)。

1. [将存档上传到 Amazon S3 存储桶](https://docs.aws.amazon.com/AmazonS3/latest/UG/UploadingObjectsintoAmazonS3.html)，[公开存档](https://docs.aws.amazon.com/AmazonS3/latest/UG/EditingPermissionsonanObject.html)，然后记录存档的 URL。

您现在可以安装说明书并运行配方。

**运行配方**

1. [编辑堆栈以启用自定义说明书](workingcookbook-installingcustom-enable.md)，然后指定以下设置。
   + **存储库类型 **- **S3 存档**
   + **存储库 URL **-您之前记录的说明书存档 URL

   对其他设置使用默认值，然后单击 **Save** 更新堆栈配置。

1. [运行“Update Custom Cookbooks”堆栈命令](workingstacks-commands.md)，这会将当前版本的自定义说明书安装到堆栈的实例上。如果您的说明书存在早期版本，此命令会覆盖该版本。

1. 通过在 **Recipes to execute** 设置为 **opstest::default** 的情况下运行 **Execute Recipes** 堆栈命令来执行配方。此命令将使用一个包含 `opstest::default` 的运行列表来启动 Chef 运行。

配方成功运行后，您可以对其进行验证。

**验证 opstest**

1. 第一步是检查 [Chef 日志](troubleshoot-debug-log.md)。单击 opstest1 实例 **Log** 列中的 **show**，显示日志。向下滚动，您将在接近底部的位置看到您的日志。

   ```
   ...
   [2014-07-31T17:01:45+00:00] INFO: Storing updated cookbooks/opsworks_cleanup/attributes/customize.rb in the cache.
   [2014-07-31T17:01:45+00:00] INFO: Storing updated cookbooks/opsworks_cleanup/metadata.rb in the cache.
   [2014-07-31T17:01:46+00:00] INFO: ******Creating a data directory.******
   [2014-07-31T17:01:46+00:00] INFO: Processing template[/etc/hosts] action create (opsworks_stack_state_sync::hosts line 3)
   ...
   ```

1. [使用 SSH 登录实例](workinginstances-ssh.md)并列出 `/srv/www/` 的内容。

如果您执行了所有步骤，您将看到 `/srv/www/config` 而不是您需要的 `/srv/www/shared` 目录。以下部分提供了一些快速修复此类错误的指南。

## 自动执行配方
<a name="cookbooks-101-opsworks-opsworks-instance-events"></a>

**Execute Recipes** 命令是一种测试自定义配方的便捷方式，这正是大多数此类示例中都使用它的原因。但是，实际上，您通常会在实例生命周期的标准时刻运行配方，例如在实例完成启动后或部署应用程序时。 OpsWorks Stacks 支持每个层的一组[生命周期事件](workingcookbook-events.md)：设置、配置、部署、取消部署和关闭，从而简化实例上的运行配方。通过将配方分配给相应的生命周期事件，可以让 OpsWorks Stacks 在图层的实例上自动运行配方。

您通常会在实例完成启动后立即创建目录，与设置事件对应。下面展示了如何使用之前在示例中创建的同一堆栈在设置时运行示例配方。您可以对其他事件使用相同的过程。

**在设置时自动运行配方**

1. 在导航窗格中选择 “**图层**”，然后选择图 OpsTest 层的 “**食谱**” 链接旁边的铅笔图标。

1. 将 **opstest::default** 添加到层的 **Setup (设置)** 配方，单击 **\$1** 将前者添加到层，然后选择 **Save (保存)** 保存配置。

1. 选择 **Instances**，将另一个实例添加到层，然后启动该实例。

   该实例应名为 `opstest2`。启动完成后， OpsWorks Stacks 将运行。`opstest::default`

1. 在 `opstest2` 实例处于在线状态后，请验证 `/srv/www/shared` 是否存在。

**注意**  
如果您已将配方分配给设置、配置或部署事件，您也可以使用[堆栈命令](workingstacks-commands.md) (设置和配置) 或[部署命令](workingapps-deploying.md) (部署) 来触发事件，手动运行。请注意，如果您向某个事件分配了多个配方，那么这些命令将运行所有这些配方。

## 排查并修复配方问题
<a name="cookbooks-101-opsworks-opsworks-instance-bugs"></a>

如果您没有得到预期结果，或者您的配方甚至都没有成功运行，那么问题排查通常从检查 Chef 日志开始。它包含运行的详细说明，并包含来自您的配方的任何内联日志消息。如果您的配方只是失败了，日志就会特别有用。当出现这种情况时，Chef 会记录错误 (包括堆栈跟踪)。

如果配方像在本示例中一样成功了，则 Chef 日志通常不会有太大帮助。在这种情况下，您只需更仔细地观察配方即可找到问题所在，特别是前几行：

```
Chef::Log.info("******Creating a data directory.******")

data_dir = value_for_platform(
  "centos" => { "default" => "/srv/www/shared" },
  "ubuntu" => { "default" => "/srv/www/data" },
  "default" => "/srv/www/config"
)
...
```

当您在 Vagrant 上测试配方时，CentOS 是 Amazon Linux 的合理替代品，但现在您正在实际的 Amazon Linux 实例上运行。Amazon Linux 的平台值为 `amazon`，该值未包含在 `value_for_platform` 调用中，因此配方将默认创建 `/srv/www/config`。有关问题排查的更多信息，请参阅[调试和故障排除指南](troubleshoot.md)。

既然您已经确定问题，您需要更新配方并验证修复。您可以返回到原始的源文件，更新 `default.rb`，将新存档上传到 Amazon S3 或执行其他操作。但是，这个过程可能有点枯燥和费时。下面所介绍的这种方法在速度上要快得多，这种方法对类似于下例中错误的简单配方错误特别有用：在实例上编辑配方。

**在实例上编辑配方**

1. 使用 SSH 登录实例，然后运行 `sudo su` 以提升您的权限。您需要根权限才能访问说明书目录。

1. OpsWorks Stacks 会将你的食谱存储在里面`/opt/aws/opsworks/current/site-cookbooks`，所以请导航到。`/opt/aws/opsworks/current/site-cookbooks/opstest/recipes`
**注意**  
OpsWorks Stacks 还会将你的食谱副本存储在里面。`/opt/aws/opsworks/current/merged-cookbooks`请勿编辑该说明书。当你执行食谱时， OpsWorks Stacks 会将食谱从复制`.../site-cookbooks`到`.../merged-cookbooks`，因此你所做的任何更改都`.../merged-cookbooks`将被覆盖。

1. 在实例上使用文本编辑器编辑 `default.rb`，并将 `centos` 替换为 `amazon`。现在，您的配方应该类似于以下形式。

   ```
   Chef::Log.info("******Creating a data directory.******")
   
   data_dir = value_for_platform(
     "amazon" => { "default" => "/srv/www/shared" },
     "ubuntu" => { "default" => "/srv/www/data" },
     "default" => "/srv/www/config"
   )
   ...
   ```

要验证修复情况，请再次运行 **Execute Recipe** 堆栈命令来执行配方。现在，实例应该具有 `/srv/www/shared` 目录。如果您需要进一步更改配方，则可以按所需的频率运行 **Execute Recipe**；您不需要在每次运行命令时停止并重新启动实例。当您对配方正常工作感到满意后，请勿忘记更新您的源说明书中的代码。

**注意**  
如果您已将配方分配给生命周期事件，因此 OpsWorks Stacks 会自动运行该食谱，则可以随时使用 **Execute Recipe 来重新运行配**方。您还可以使用 OpsWorks Stacks 控制台手动触发相应的事件，在不重启实例的情况下根据需要多次重新运行配方。但是，这种方法会运行事件的所有配方。提醒一下：  
使用[堆栈命令](workingstacks-commands.md)可触发设置事件或配置事件。
使用[部署命令](workingapps-deploying.md)可触发部署事件或取消部署事件。