实现思路

AWS 上的 OpsWorks 可以管理管理主机实例的各个生命周期,可以在不同的生命周期执行不同的脚本,这些脚本可以使用内置的,也可以使用我们自定义的。

而我们的自动安装就是自定义各个周期的脚本,在主机启动完成之后执行安装脚本,并且启动应用程序,从而实现自动安装,并且自动启动应用。

OpsWorks 生命周期介绍

打开 AWS 控制台的 OpsWorks 控制台,然后新建一个 Stack,过程就省略了,大家可以随意创建,然后在这个 Stack 中创建一个 Layer,也随意创,创完之后,设置这个 Layer 的选项,设置页面应该如下:

图1: Layer Setting

切换到黑色虚框圈出来的选项,你将会看到如下的生命周期脚本列表:

图2: 内置脚本

这里有 5 个生命周期,分别是: Setup、Configure、Deploy、Undeploy、Shutdown

下面对这几个生命周期做一个简单的解释:

自动安装实现

看完 OpsWorks 生命周期介绍之后,你可能会认为应该在 Setup 阶段部署我们的安装脚本,但是,事实上我们是在 Deploy 阶段放置我们的安装脚本,下面是我们真正的安装配置:

图3: 自定义脚本

在 Deploy 阶段的虚线圈出来的部分你会发现,我们将安装脚本放在了那。

Why?不是说好的 Deploy 只会通过我们下发部署命令才会触发吗?难道还要我们每次都下发 Deploy 指令来安装吗?不是说好了要自动安装的吗?

问题就在这,在 AWS 的设计里, Setup 阶段是包含 Deploy 的!!!所以,当 Setup 脚本执行完之后,会自动执行 Deploy ,这样的话,我们就理解为什么可以将安装脚本放在 Deploy 阶段了。

总结一下,执行的步骤是这样的:

启动一台实例,实例内部启动完成之后

  1. AWS OpsWorks 执行内置的 Setup 脚本,执行完之后,再执行自定义 Setup 脚本
  2. AWS OpsWorks 执行内置的 Deploy 脚本,执行完之后,再执行自定义的 Deploy 脚本

此时,这个实例的状态变为 online 状态,这时

  1. AWS OpsWorks 运行这个栈上所有其他实例的 Configure 脚本,执行完之后,再执行自定义 Configure 脚本。

OK,就这样,我们的自动安装脚本就被执行到了,具体脚本里面怎么实现就超出了这里的讨论范围了。

额外问题点

问题1:看图3的时候,为什么自定义脚本和内置脚本重合了?

也许你心细得发现了,图 2 和图 3 的脚本配置里面,基本上都重合,图 3 中的脚本包含了图 2 中的所有脚本。这是为何?

这个就得从 OpsWorks 的内置脚本从哪里来说起。

当启动一台实例的时候,在这台实例上执行的 OpsWorks 内置脚本从哪里来?直接写死在启动这个实例的系统镜像里?不太实际吧?其实这些脚本默认都是从 github 来的,当启动一台实例的时候,这个新启动的实例会从指定的 Github 地址上把这些拷贝下来,然后执行。

这样就带来了一个安全隐患,那怎么办,万一 github 上的脚本被恶意修改了怎么办?所以我们就考虑到修改默认脚本,但是,这里有一个坑就是默认的内置脚本里不能删除!!!这意味着他们一定会被执行,那么怎么办?

好在他们是可以被覆盖的,当你自定义脚本和内置脚本重名的时候,内置脚本会被自定义脚本覆盖,其实,在 OpsWorks 里,它会将内置脚本和自定义脚本都拷下来合并,然后再执行的,你可以在任意一台 OpsWorks 主机里面看到这些脚本,脚本的位置在: /opt/aws/opsworks/current/site-cookbooks

问题2:自定义脚本放在哪?

正如上面没有提到的,我们虽然设置了自定义脚本的名字,但是,我们的自定义脚本放在哪了?这个就是 Stack 的设置了。打开该 Layer 对应的 Stack ,然后同样打开设置页面:

图4: Stack Setting

在这里你可以设置自定义脚本的位置,自定义脚本的Chef 版本,支持多种选择 Github/S3/SVN/Http 等方式都可以。

问题3:自定义脚本怎么写?

这个问题很好,OpsWorks 采用的是 Chef 脚本,这个脚本是通过 Ruby 和 Erlang 编写的,所以如果你熟悉这两种语言的话,简单参考一下内置脚本应该很容易编写,但是假如你不熟悉怎么办?有没有个简单的教程?这个我还真没有找到,不过 OpsWorks 官方指导文件的 Page 41 ~ Page 70 有几个简单的教程示例,你可以跟着学,基本上可以满足你的要求。

官方指导文档下载:点击下载