在正在运行的 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 卷关联的虚拟设备(如果有)。此值仅在启动时存在时才在元数据中可用。
此解决方案不会告诉您有关启动实例后安装的 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。
当然,亚马逊可能会随时更改上述所有规定,恕不另行通知。但目前看来,这一规定还算有效。