从实例元数据端点检索正确的Amazon连接的EBS设备 [英] Retrieve correct Amazon attached EBS device from instance metadata endpoint

查看:89
本文介绍了从实例元数据端点检索正确的Amazon连接的EBS设备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

EDIT和TL; DR:

ubuntu@ip-172-31-19-77:~/.aws$ aws ec2 describe-instances | jq . | grep -i device
          "BlockDeviceMappings": [],
          "RootDeviceType": "ebs",
          "RootDeviceName": "/dev/sda1",
                "DeviceIndex": 0,
          "BlockDeviceMappings": [
              "DeviceName": "/dev/sda1",
              "DeviceName": "/dev/xvdb",
          "RootDeviceType": "ebs",
          "RootDeviceName": "/dev/sda1",
                "DeviceIndex": 0,
          "BlockDeviceMappings": [
              "DeviceName": "/dev/sda1",
          "RootDeviceType": "ebs",
          "RootDeviceName": "/dev/sda1",
                "DeviceIndex": 0,
          "BlockDeviceMappings": [
              "DeviceName": "/dev/xvda",
          "RootDeviceType": "ebs",
          "RootDeviceName": "/dev/xvda",
                "DeviceIndex": 0,
          "BlockDeviceMappings": [
              "DeviceName": "/dev/sda1",
              "DeviceName": "/dev/sdf",
          "RootDeviceType": "ebs",
          "RootDeviceName": "/dev/sda1",
ubuntu@ip-172-31-19-77:~/.aws$ aws ec2 describe-volumes | jq . | grep -i device
          "Device": "/dev/sda1"
          "Device": "/dev/sdf"
          "Device": "/dev/xvda"
          "Device": "/dev/sda1"
          "Device": "/dev/xvdb"
          "Device": "/dev/sda1"
ubuntu@ip-172-31-19-77:~/.aws$ ls /dev/sd*
ls: cannot access '/dev/sd*': No such file or directory
ubuntu@ip-172-31-19-77:~/.aws$ ls /dev/xv*
ls: cannot access '/dev/xv*': No such file or directory
ubuntu@ip-172-31-19-77:~/.aws$ lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0   1G  0 disk
nvme1n1     259:1    0   8G  0 disk
└─nvme1n1p1 259:2    0   8G  0 part /

说明:

我想提前知道特定AWS实例应该在附加设备后使用哪个块设备.

I would like to know in advance which block device a particular AWS instance is supposed to have post-attachment.

不幸的是,实例早在2007年推出的块设备的元数据终结点似乎不再可靠运行?

Unfortunately, the instance metadata endpoint for block devices introduced back in 2007 does not seem to work reliably anymore?

这是我正在t2.medium实例撰写本文时(不是Amazon Linux ):

Here's an example t2.medium instance I'm running with latest Ubuntu (17.10) AMI at the time of writing this (not Amazon Linux):

不仅EBS模块显示在控制台中,而且似乎已正确连接:

Not only the EBS modules show up in the console, but seem to be properly attached:

根据官方块设备映射上的AWS文档:

block-device-mapping/ebsN:与Amazon EBS卷关联的虚拟设备(如果有).如果Amazon EBS卷在启动时或上次启动实例时存在,则仅在元数据中可用. N表示Amazon EBS卷的索引(例如ebs1或ebs2). 2007-12-15

block-device-mapping/ebsN: The virtual devices associated with Amazon EBS volumes, if any are present. Amazon EBS volumes are only available in metadata if they were present at launch time or when the instance was last started. The N indicates the index of the Amazon EBS volume (such as ebs1 or ebs2). 2007-12-15

但是不幸的是,在实例完全启动并运行后,没有这样的端点.并且所有EBS卷都已连接:

But unfortunately there are no such endpoints present after the instance is fully up and running and all EBS volumes are attached:

$ curl http://169.254.169.254/latest/meta-data/block-device-mapping/
ami
ephemeral0
ephemeral1
$ curl http://169.254.169.254/latest/meta-data/block-device-mapping/ami
/dev/sda1
$ curl http://169.254.169.254/latest/meta-data/block-device-mapping/ebs1
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>404 - Not Found</title>
 </head>
 <body>
  <h1>404 - Not Found</h1>
 </body>
</html>
$ curl http://169.254.169.254/latest/meta-data/block-device-mapping/ebs2
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>404 - Not Found</title>
 </head>
 <body>
  <h1>404 - Not Found</h1>
 </body>
</html>

另一方面,操作系统(在XEN设备方案下)通过xvdXX设备公开卷:

On the other hand, the operating system (under XEN device scheme), exposes the volumes via xvdXX devices:

$ ls /dev/xvd*
/dev/xvda  /dev/xvda1  /dev/xvdf  /dev/xvdg

因此,这给了我一个假设哪个块设备将取决于我正在运行的实例,那么该实例可能会中断一次,例如,

So this leaves me with a poor solution of just assuming which block device is going to be depending on which instance I'm running, which predictably breaks once, for instance, Amazon introduces new iron with completely different underlying block device naming schemes such as /dev/nvme0n1p1:

https://twitter.com/braincode/status/968005482102190080

这是在带有EBS卷的新实例化的M5实例上发生的事情:

Here's what happens on freshly instantiated M5 instance with an EBS volume attached:

$ curl http://169.254.169.254/latest/meta-data/block-device-mapping/
ami
ebs2
root

$ curl http://169.254.169.254/latest/meta-data/block-device-mapping/ebs2
sdf

  1. 为什么只列出ebs2而没有列出ebs1?
  2. sdf?
  1. Why is only ebs2 listed and not ebs1?
  2. sdf?

在m5实例的操作系统上没有一个sd*:

There's not a single sd* on m5 instance's operating system:

$ ls /dev/sd*
ls: cannot access '/dev/sd*': No such file or directory

我做错了什么?这是一个已知的错误? people/boto/cloudinit模块如何处理?

What am I doing wrong? Is this a known bug? How do people/boto/cloudinit modules handle that?

推荐答案

通过运行EC2instance获取并标记EBS RootVolume : 这是实现它的方法:

Getting and tagging the EBS RootVolume from running EC2instance: this is how you can achieve it:

Instance_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
Instance_Name=$(aws ec2 describe-instances --instance-ids ${Instance_ID} --query 'Reservations[0].Instances[0].Tags[?Key==`Name`].Value' --output text)
RootDeviceName=$(aws ec2 describe-instances --instance-ids ${Instance_ID} --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
RootVolumeId=$(aws ec2 describe-instances --instance-ids ${Instance_ID} --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`${RootDeviceName}\`].Ebs.VolumeId" --output text)

如果要设置RootVolume标记(CloudFormation尚不支持(2019-03-14)):

if you want to set a RootVolume Tag (which isn't supported by CloudFormation yet (2019-03-14)):

aws ec2 create-tags --resources ${RootVolumeId} --tags Key=Name,Value=RootVolume-${Instance_Name}

您需要以下IAM权限:

You need the following IAM Permissions for that:

"ec2:DescribeInstances"
"ec2:CreateTags"


这是它的工作方式:


This is how it works:

只看(缩短的)ec2 json响应:

just look at the (shortened) ec2 json response:

aws ec2 describe-instances --instance-ids ${Instance_ID}

{
    "Reservations": [
        {
            "Instances": [
                {
                    "InstanceId": "i-XXXXX", 
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda", 
                            "Ebs": {
                                "Status": "attached", 
                                "DeleteOnTermination": true, 
                                "VolumeId": "vol-XXXXX", 
                                "AttachTime": "2019-02-27T07:56:07.000Z"
                            }
                        }, 
                        {
                            "DeviceName": "/dev/sdm", 
                            "Ebs": {
                                "Status": "attached", 
                                "DeleteOnTermination": false, 
                                "VolumeId": "vol-XXXXX", 
                                "AttachTime": "2019-02-27T07:58:02.000Z"
                            }
                        }
                    ], 
                    "RootDeviceType": "ebs", 
                    "RootDeviceName": "/dev/xvda", 
                }
            ], 
            "ReservationId": "r-XXXXX", 
            "RequesterId": "XXXXX", 
            "Groups": [], 
            "OwnerId": "XXXXX"
        }
    ]
}

您将看到:每个实例都有BlockDeviceMappings和RootDeviceName属性.
1)您可以从 RootDeviceName 属性中选择当前作为 DeviceName 作为值.
2)利用这些信息,您可以通过匹配所选的 DeviceName 来解析 BlockDeviceMappings ,并最终获得 VolumeID .

As you can see: every instance has BlockDeviceMappings and a RootDeviceName property.
1) You can select the current as DeviceName as Value from RootDeviceName property.
2) With that information you can parse your BlockDeviceMappings by matching your selected DeviceName and finally get the VolumeID.

就这样.

这篇关于从实例元数据端点检索正确的Amazon连接的EBS设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆