AWS用户数据与Packer

14
我正在尝试使用Packer创建AWS镜像,并通过user_data_file指定一些用户数据。每次启动实例时,都需要运行此文件的内容,因为它将是唯一的。我不能将其烘焙到AMI中。
使用Packer,我有以下内容:
{
  "variables": {
  "ami_name": ""
  },
  "builders": [
  {
    "type": "amazon-ebs",
    "region": "us-east-1",
    "source_ami": "ami-c8580bdf",
    "instance_type": "t2.micro",
    "ssh_username": "ubuntu",
    "ami_name": "{{ user `ami_name` }}-{{ isotime | clean_ami_name }}",
    "user_data_file": "user_data.sh",
    "tags": {
      "os_version": "ubuntu",
      "built_by": "packer",
      "build_on": "{{ isotime | clean_ami_name }}",
      "Name": "{{ user `ami_name` }}"
    }
  }],
  "provisioners": [
  {
    "type": "ansible",
    "playbook_file": "playbook.yml",
    "user": "ubuntu"
  }]
}

我的user_data shell脚本内容只是一些基本的配置行,用于安装通过provisioners步骤运行的ansible脚本安装的软件包。通过观察Packer的输出,我可以确认所有的ansible脚本都已经运行完毕。
Packer完成并创建了AMI,但user data部分从未被执行。在生成的镜像中没有记录它的存在。没有/userdata.log文件,而/var/lib/cloud/instance/user-data.txt则为空。我感觉我漏掉了一些基本的东西,因为使用Packer应该是一件非常简单的事情。

请您添加user_data.sh文件。 - Rickard von Essen
日志将被记录在/var/log/cloud-init-output.log/var/log/cloud-init.log中。 - Rickard von Essen
Richard von Essen 在下面的回答中为我解开了迷惑。它只有在启动基于打包程序的实例时才会执行。当我尝试从此 AMI 启动实例时,它将不存在。 - David Ficociello
如何使使用Packer构建的AMI启动的实例每次运行用户数据,以便每个实例都是唯一的?将脚本放到路径中不起作用,只适用于packer实例。@DavidFicociello - Brooke
所以你的意思是你把一个非常简单的脚本放在这个路径下:/var/lib/cloud/scripts/per-instance,但它没有运行?为了测试,你应该在那里放置一些非常基本的东西,并证明它可以工作。根据我在这个问题上得到的指示,我能够让我的实例启动并执行该目录中的脚本。 - David Ficociello
3个回答

14

我重新阅读了一下,也许你误解了Packer如何使用用户数据脚本。

user_data 是当 EC2 实例由 Packer 启动时提供的。最终,该实例在快照和保存为 AMI 之后进行配置。

当您从创建的 AMI 启动新实例时,它不会有相同的用户数据,它会获取您在启动此新实例时指定的用户数据。

初始用户数据(在您的模板中定义)的影响可能存在于新实例中,也可能不存在,这取决于更改是否已在 AMI 中持久化。


3
好的,看起来我完全误解了 Packer 的 user_data 部分的意义。我假设它会将 user_data 编入镜像中,以便每次启动时都会执行它。我需要找到另一种解决方案。谢谢。 - David Ficociello
3
只需将脚本(在 Packer 中进行配置时)上传到 /var/lib/cloud/scripts/per-boot/per-instance 目录,并使其可执行。这样,cloud-init 将在每次启动或每个实例中执行该脚本。有关更多信息,请参阅 cloud-init 文档。 - Rickard von Essen
Rickard von Essen做到了!谢谢。我不知道那些脚本目录。 - David Ficociello

14

如Rickard von Essen所指出的那样,答案是将我的脚本复制到/var/lib/cloud/scripts/per-instance,这将会在从该AMI启动的每个实例上执行我的脚本。

或者,如果您需要每次实例启动时都要执行此操作,则可以将脚本放置在/var/lib/cloud/scripts/per-boot中。

在我的情况下,由于我想要将实例注册到第三方服务,因此我只需要在每次创建实例时执行一次。


它对我不起作用。还有其他尝试的方法吗? - Brooke
看起来路径仍然是相同的。https://cloudinit.readthedocs.io/en/latest/topics/dir_layout.html - David Ficociello
将userdata sh脚本放置到该目录后,cloud-init是否会自动运行该脚本?还是我应该在packer provision期间运行它? - Brooke
我使用了 file 供应者并遇到了权限问题。您如何将脚本复制到此位置? - 170730350

1
上传到/var/lib/cloud/scripts/*可以起作用,但这取决于您希望如何构建您的镜像。您需要能够快速启动实例吗?
最好的解决方案是使用Packer provisioners。Provisioners用于在启动后通过使用ansible/salt/puppet/cheff/shell脚本等安装和配置机器映像,您可以使用所需的任何内容来提供您的映像。这样,您就不必绑定到每个实例启动时都要提供deps,这可能会导致一些问题(考虑间歇性网络问题/故障,这可能会导致某些deps未被安装)。
Packer的provisioners是第三方的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接