答案1
没有简单的回答这个问题。
使用围绕图像设计的架构(通常称为“不可变基础设施”)对于无状态服务(例如应用程序服务器)非常有效。
使用正确的工具、故障转移系统和升级路径绝对可以将其扩展到有状态服务,但对于简单的系统(如您所描述的)来说,这些通常是过度的。
使用这些工具时要记住的一件事是,您不必“全力以赴”。Packer 和 Terraform 的设计非常巧妙,只适合在您需要的地方工作。它们不会故意在您的所有系统中强制执行一种模式。
实际上,处理此问题的最佳方法是以不同的方式维护您的数据库服务器,在 Packer 之外(构建初始映像,是的!但不一定以与无状态 Web 服务器相同的方式升级它们)或将状态管理外包给其他人。值得注意的选项包括 Heroku Postgres 或 AWS RDS。
总而言之,是的,这是可能的,但是使用我们当前的工具,在小规模或简单架构下,它可能会带来更多的麻烦。
Packer 和 Terraform 仍可在同一基础设施的其他方面发挥巨大作用 - 例如,Terraform 可以非常直接地配置 Heroku 数据库供您的 DigitalOcean 应用服务器使用。Packer 可以处理升级和发布您的应用服务器映像,同样适用于开发。
答案2
我认为 Terraform 现在具备了这里所需的功能。基本模式是单独定义数据卷并将其附加到实例,这样当实例被销毁并创建新实例时(例如从 Packer 构建的新 AMI),现有卷可以附加到新实例。
因此,使用 Terraform 的详细步骤如下:
- 定义
aws_ebs_volume
资源 - 将这些附加到您的实例
aws_volume_attachment
(这里我使用了device_name = "/dev/xvdh"
) - 确保您的
aws_ebs_volume
资源包括生命周期规则prevent_destroy = true
(所以他们会绝不被 terraform 删除) - 确保您的
aws_volume_attachment
资源包括skip_destroy = true
(在升级时,terraform 无法在卷已安装时销毁这些,并且停止实例无论如何都会销毁附件,因此 terraform 无需尝试这样做)
最后一步是确保实例在启动时挂载卷。这可以通过在资源中执行以下操作来user_data
实现aws_instance
:
#!/bin/bash
mkdir /data #create mount point
mount /dev/xvdh /data #mount it
为了使上述操作有效,您需要通过创建文件系统来准备卷,但这只需要一次:
mkfs -t ext4 /dev/xvdh
更多详细信息请参阅Terraform 问题 #2740。