如何在正在运行的 EC2 实例上识别 EBS 卷与本地卷

如何在正在运行的 EC2 实例上识别 EBS 卷与本地卷

在正在运行的 EC2 实例上,如何识别 EBS 卷和本地磁盘?我想从 shell 中识别它们。

fdisk、lsblk 并不能帮助精确定位 EBS 卷。

假设我总共有 20 个磁盘,其中 20 个为标识 ebs 存储。

有什么建议么?

答案1

每个 EC2 实例都可以访问链接本地地址处的 REST 端点,http://169.254.169.254该端点可以访问有关该实例的元数据。

EBS 和实例存储卷的块设备映射是其中可用的几个属性之一,并且可以使用“curl”之类的工具从 shell 和脚本轻松访问数据。

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html

这可能是发现您正在寻找的内容的“最正确”的方法。


更新:我快速编写了一个非常粗略的单行代码来演示此功能。我并不想暗示这是生产质量代码,也没有特别详尽的文档,但它确实有效。

上面的端点似乎提供了其接口的几个“版本”,其中大多数使用版本发布日期,或者您可以使用“最新”版本。为了使此示例代码即使接口发生变化也能继续工作,我将选择版本“2012-01-12”。

我们将在 shell 变量 $METAURL 中存储一个链接,用它检索那里可用的映射列表,curl然后使用bash for/ do/done循环(再次使用curl)迭代每个映射以找到块设备……然后使用perl使其更整洁并将“sdX”重写为“xvdX”,因为我的特定实例使用它作为其设备名称,最后sort按词汇顺序排列它。

bash$ METAURL="http://169.254.169.254/2012-01-12/meta-data/block-device-mapping/"
bash$for bd in `curl -s $METAURL`; do curl -s $METAURL$bd | \
         perl -pe 'BEGIN { $d = shift } s/^(\/dev\/)?(sd)?(.*)$/\/dev\/xvd$3 is $d\n/' $bd; \
         done | sort

示例输出:

/dev/xvda1 is ami
/dev/xvda1 is root
/dev/xvdb is ephemeral0
/dev/xvdf is ebs2
/dev/xvdg is ebs1
/dev/xvdh is ebs5

这非常巧妙并且相对轻松。

但是,有一个小问题我的回答。

块设备映射/ebsN

与 Amazon EBS 卷关联的虚拟设备(如果有)。此值仅在启动时存在时才在元数据中可用。

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html#instancedata-data-categories

此解决方案不会告诉您有关启动实例后安装的 EBS 卷的信息。这可能没问题,因为临时卷信息始终可用,因为临时磁盘只能在启动时添加,而不能在之后添加……因此,如果卷是临时的,您应该始终能够通过此方法发现它。如果它不在这里,则它不是临时磁盘。

鉴于此,EC2 API或者aws 命令行如果您确实需要了解与实例相关的所有信息,则需要使用实用程序(调用 EC2 API)。那里有更多的数据,但在脚本中使用会有些棘手。我想,这是典型的权衡。

答案2

Michael 的回答表明,似乎没有办法区分 AWS 实例中的实例磁盘和 EBS 卷。事实上,您可以与 进行比较的实例和 EBS 磁盘的内核信息diff -r /sys/block/xvd{f,g}除了写入统计信息和设备名称外是相同的。而且磁盘不响应smartctl

然而,我注意到:

  • 新的 EBS 卷似乎完全没有任何分区表。

  • 新的临时磁盘似乎是 ext 格式的,并且“安装计数”超级块参数设置为 0,以反映它们从未在任何地方安装的事实。

使用它,一种方法是在机器第一次启动时运行一个脚本,该脚本会查找 ext 格式的设备,并

tune2fs -l $dev | grep "Mount count"

返回 0。在实例的某处保存此类磁盘的列表,并将所有其他磁盘视为 EBS。

当然,亚马逊可能会随时更改上述所有规定,恕不另行通知。但目前看来,这一规定还算有效。

相关内容