在 EBS 卷上创建文件系统,将其挂载到 EC2 实例并在实例被 CDK 替换时持久化数据

Creating a file system on EBS volume, mounting it to EC2 instance and persisting data when instance is replaced with CDK

我正在使用 CDK 部署一个 EC2 实例,该实例将 运行 单个节点 docker swarm 集群中的应用程序。这不适用于关键的生产工作负载,主要用于 运行 副项目和试验。在大多数情况下,它运行良好,我可以通过互联网访问我的应用程序。

这是我的问题:当我重新部署应用程序时,它替换了 EC2 实例并且所有数据都丢失了,因为它使用实例的根卷来存储数据。我现在正在尝试将 EBS 卷挂载到实例并在该挂载的 EBS 卷上挂载 docker 卷,以便在堆栈更新之间保留数据。以下是有关我正在开发的应用程序的一些信息,以获取更多上下文:

我在 docker swarm 中部署的堆栈具有以下服务:

我想在 traefik、postgres 和 redis 上挂载一个 EBS 卷,并且可能只对所有三个服务使用相同的卷以保持简单。

我一直在这里查看 EBS 的文档:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-using-volumes.html

我想我需要在我的 UserData 脚本中做这样的事情:

# mount the EBS volume
sudo mkdir /data  # make a directory on the EC2 machine
sudo mkfs -t xfs /dev/sda1  # create an xfs file system on /dev/sda1
sudo mount /dev/sda1 /data  # mount the volume on the directory that was created

我认为这接近我的需要,但它会在我每次启动或更换 EC2 实例时格式化卷的数据。

我应该使用 fstab 吗?我正在尝试将其添加到我的 UserData 脚本中:

sudo mkdir /data
echo "/dev/sda1    /data   xfs    defaults    0 0" >> /etc/fstab

这仍然不是持久化数据。我正在通过向 /data 添加一个文件来测试这一点,重新部署并检查文件是否存在,一旦 EC2 实例被替换。

我正在使用我的 CDK 堆栈中定义的 CloudFormationInit 脚本来安装 docker、初始化 swarm 集群、下载 stack.yml 文件并将其部署到 swarm 集群。然后我创建一个指向 EC2 实例的 public IP 的 Route 53 记录。

这是我正在为 运行在 EC2 上的 docker swarm 中为我的 Django 应用程序开发的 CDK 构造的 link:https://github.com/briancaffey/django-cdk/blob/main/src/docker-ec2.ts

你几乎明白了 - 你只需安装它就可以了。格式化确实会擦除数据,解决办法就是跳过这一步。

您 link 解决此问题的文档:

(Conditional) If you discovered that there is a file system on the device in the previous step, skip this step. If you have an empty volume, use the mkfs -t command to create a file system on the volume.

Warning. Do not use this command if you're mounting a volume that already has data on it (for example, a volume that was created from a snapshot). Otherwise, you'll format the volume and delete the existing data.

所以以下应该有效:

# mount the EBS volume
sudo mkdir /data  # make a directory on the EC2 machine
sudo mount /dev/sda1 /data  # mount the volume on the directory that was created