【问题标题】:Find region from within an EC2 instance从 EC2 实例中查找区域
【发布时间】:2011-05-14 01:33:17
【问题描述】:

有没有办法从实例中查找实例的区域?

我在找类似finding the instance id的方法。

【问题讨论】:

标签: amazon-ec2 amazon-web-services


【解决方案1】:

该 URL (http://169.254.169.254/latest/dynamic/instance-identity/document) 似乎不再有效。当我尝试使用它时,我得到了 404。我有以下似乎可以工作的代码:

EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed 's/[a-z]$//'`"

希望这会有所帮助。

编辑:基于 cmets 改进了 sed

【讨论】:

  • 这将在 EC2 实例内部运行,并由 AWS 的后端提供支持。它在其他任何地方都不起作用(主要是因为该 IP 是 APIPA)。此外,如果不连接到元数据源,也无法直接从实例内部获取此信息。这假设 169.254.169.254 API 可用,并且您的脚本应该相应地处理网络故障。 ec2-metadata 只是这个 API 的一个包装器,但本质上是做同样的事情。
  • 这是有记录的吗?你能解释一下你是怎么找到它的吗?
  • 老实说,当我想出那个 2-liner 时,我只是在探索 API,寻找可以用来识别正确区域的任何东西。 AWS 元数据 API 已在此处完整记录:docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
  • sed 替换命令比为 EC2_REGION 提供的命令简单得多:sed 's/[a-z]$//
  • 如果这是在引导脚本中,元数据服务可能还没有被实例化 - 如果是这样,请等待并重试。我发现启动后需要 10-15 秒才能使元数据位置可用。
【解决方案2】:

还有另一种方法可以实现:

REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`

echo $REGION

us-east-1

【讨论】:

  • 是否应该在任何地区/az(以及任何 AMI)上工作?我得到404 - Not Found 试图从us-east-1a 的机器上GET 那个URL。
  • @AdamMonsen 也许这是一个暂时性错误。我在 us-east-1a 上,效果很好。
  • 感谢@FlorinAndrei。现在也对我有用。
  • 与jq:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
  • 使用 awk:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | awk -F\" '/region/ {print $4}'
【解决方案3】:

如果您可以使用jq,您可以运行以下命令:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq .region -r

我想这是最干净的方式。

【讨论】:

    【解决方案4】:
    ec2-metadata --availability-zone | sed 's/.$//'
    

    对于基于 debian 的系统,该命令不带破折号。

    ec2metadata --availability-zone | sed 's/.$//'
    

    【讨论】:

    • 获取只有区域名称的纯字符串:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
    • ec2-metadata 似乎不是默认可用的东西 - 你能附上安装说明吗?
    【解决方案5】:

    如果你想避免正则表达式,这里有一个你可以用 Python 做的单行代码:

    curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | python -c "import json,sys; print json.loads(sys.stdin.read())['region']"
    

    【讨论】:

    • 这个答案应该更高!
    • @KostasDemiris 我同意,我更愿意从 JSON 结构中读取值而不是正则表达式。
    • 我同意如果您没有安装 jq,这似乎是最好的方法。您真的希望 AWS 将其公开为 169.254.169.254/latest/meta-data/placement/region ...
    【解决方案6】:

    你可以使用ec2-metadata:

    ec2-metadata -z | grep -Po "(us|sa|eu|ap)-(north|south|central)?(east|west)?-[0-9]+"
    

    【讨论】:

    • 有了这个,如果你在eu-central-1,你就完蛋了。
    • central 在我最初写答案时并不存在。现已添加。
    • 对我来说,每次 AWS 添加新区域时都会中断的脚本似乎不是一个特别强大的解决方案。
    • awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}' 将仅保留 AZ 名称的前两个组成部分,而不是 grep。
    • @dskrvk 如果只保留前两个组件,您如何区分eu-west-1eu-west-2eu-west-3(还有us-west-1us-west-2)@OP:只是匹配'[a-z][a-z]-[a-z]*-[0-9][0-9]*' 似乎更安全(这是一个基本的正则表达式,可以通过扩展 RE 使其更短)。 (当前的正则表达式将在ca 区域、af 区域和me 区域中断)
    【解决方案7】:

    目前为止我发现的最简单的

     curl -s 169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/.$//'
    

    【讨论】:

    • 这样做的好处是没有非默认依赖,而且只有一行。
    【解决方案8】:

    非常简单的一个班轮

    export AVAILABILITY_ZONE=`wget -qO- http://instance-data/latest/meta-data/placement/availability-zone`
    export REGION_ID=${AVAILABILITY_ZONE:0:${#AVAILABILITY_ZONE} - 1}
    

    【讨论】:

    • 那是两行
    • 但这不适用于 us-west-1 区域。返回curl: (6) Could not resolve host: instance-data; Name or service not known 错误。
    • @S.K.Venkat 这可能与您的 VPC 的 DNS 设置有关...使用元数据 API 的 IP 似乎更安全(其他答案的一半这样做)
    【解决方案9】:

    在大多数这些答案已经发布后的某个时间点,AWS 做了合理的事情并实施了一条新路径:latest/meta-data/placement/region

    这意味着获取区域应该很简单

    curl http://169.254.169.254/latest/meta-data/placement/region
    

    编辑:还可能值得一提的是,此端点在元数据 API 的 2019-10-01 版本中可用。通过检查http://169.254.169.254/,确保您的实例支持该版本或更高版本,然后再使用它。

    【讨论】:

    • 这在某些情况下对我有用,但在其他情况下我得到 404 Not Found,即使最新的可用版本是 2020-10-27。
    • 嗯,试试http://169.254.169.254/latest/meta-data/placementregion 是否作为列出的选项之一回来?
    • 事实证明,自从添加region端点之前,有问题的实例在没有重启的情况下运行,这就是它不可用的原因-documented
    【解决方案10】:

    如果你安装了 jq,你也可以这样做(可能是最“优雅”的方法):

    curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -c -r .region
    

    这只是返回“区域”的原始值,没有任何漂亮的打印或其他格式。 参考:AWS Forum

    【讨论】:

      【解决方案11】:

      从可用区获取区域,去掉最后一个字母。

      ec2-metadata -z | awk '{print $2}' | sed 's/[a-z]$//'
      

      【讨论】:

        【解决方案12】:

        使用JQ:

        curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
        

        【讨论】:

          【解决方案13】:

          如果您能够使用 AWS Java 开发工具包,现在有一种方法可以返回当前区域名称(例如“us-east-1”、“eu-west-1”):

          http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/regions/Regions.html#getCurrentRegion()

          【讨论】:

            【解决方案14】:

            这是我找到的最干净的解决方案:

            curl -s http://169.254.169.254/latest/dynamic/instance-identity/document |sed -n 's/  "region" : "\(.*\)"/\1/p'

            例如,

            export REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document |sed -n 's/  "region" : "\(.*\)"/\1/p')

            • 不进行 API 调用,使用 EC2 实例元数据
            • 仅使用 curl 和基本 sed,因此不依赖于不太可能安装的 SDK 或工具。
            • 不尝试解析可用区名称,因此无需担心 AWS 更改 AZ/区域名称格式

            【讨论】:

            • 完美,谢谢。这个结果可以很容易地反序列化成一个 json 对象。
            • 我在结尾加了一个逗号。
            【解决方案15】:

            感谢https://unix.stackexchange.com/a/144330/135640,使用 bash 4.2+ 我们可以从可用区中删除最后一个字符:

            $ region=`curl -s 169.254.169.254/latest/meta-data/placement/availability-zone`
            $ region=${region::-1}
            $ echo $region
            us-east-1
            

            这假设 AWS 继续对附加到该区域的可用区使用单个字符。

            【讨论】:

            • 我们总是能够剥离 shell 中的最后一个字符:region=${region%?}
            • 这本质上与 aws.qwiklabs.com 的“AWS 上的系统操作”课程中的答案相同(不幸的是,在付费墙后面)。 “实验室 1 - 使用 AWS Systems Manager 和 AWS Config 审核您的 AWS 资源”具有以下代码:AZ=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`export AWS_DEFAULT_REGION=${AZ::-1}
            【解决方案16】:

            2 只要您使用 ec2.internal 作为搜索域,它就可以工作:

            az=$(curl -s http://instance-data/latest/meta-data/placement/availability-zone)
            region=${az:0:${#az} - 1}
            

            【讨论】:

              【解决方案17】:

              对于任何想要使用良好的 ol powershell 来做到这一点的人

              $var = (curl http://169.254.169.254/latest/dynamic/instance-identity/document | Select-String-Pattern "Zone" | ConvertFrom-Json | Select-Object -ExpandProperty "region")
              echo $var
              

              【讨论】:

                【解决方案18】:

                或者不要让 Ubuntu 或这个工具成为必需品,只需这样做:

                : "${EBS_VOLUME_AVAILABILITY_ZONE:=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)}"
                : ${EBS_VOLUME_REGION:="${EBS_VOLUME_AVAILABILITY_ZONE%%*([![:digit:]])}"}
                

                【讨论】:

                • 请注意,这仅适用于当前可用区始终是区域名称,并附加一个小写字母(例如,区域为“us-west-1” ,区域是“us-west-1a”)。如果亚马逊打破这种模式,那么上面的逻辑将不再有效。
                【解决方案19】:

                如果您使用 json - 使用正确的工具。 jq 在这种情况下非常强大。

                # curl -s curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region'
                eu-west-1
                

                【讨论】:

                  【解决方案20】:

                  这适用于 eu-central-1 以及各种字母区域。 (我没有足够的代表来回复上面的 sed 答案)

                  ec2-metadata --availability-zone | sed 's/[a-z]$//'
                  

                  【讨论】:

                  • 应该是ec2metadata --availability-zone | sed 's/.$//'(没有破折号)
                  【解决方案21】:

                  如果你在 windows 上运行,你可以使用这个 powershell one-liner:

                  $region=(Invoke-RestMethod "http://169.254.169.254/latest/dynamic/instance-identity/document").region
                  

                  【讨论】:

                    【解决方案22】:

                    要查找有关您登录的 EC2 的信息,您可以使用 ec2-元数据工具。

                    您可以通过关注this link.来安装该工具 安装工具后,就可以运行了

                    # ec2-metadata -z

                    找出地区。

                    此工具随最新 (10.10) Ubuntu AMI 一起安装,

                    【讨论】:

                    • 这是不正确的。 ec2-metadata -z 只显示可用区,不显示区域。
                    【解决方案23】:

                    如果您希望使用 JS 获取区域,这应该可以:

                    meta.request("/latest/meta-data/placement/availability-zone",function(err,data){
                            if(err)
                                    console.log(err);
                            else{
                                    console.log(data);
                                    str = data.substring(0, data.length - 1);
                                    AWS.config.update({region:str});
                                    ec2 = new AWS.EC2();
                                }
                         });
                    

                    这是从 AWS DOCS 中找到的映射,以响应元数据 API 调用,只需修剪最后一个字符即可。

                      eu-west-1a :eu-west-1
                      eu-west-1b :eu-west-1
                      eu-west-1c :eu-west-1
                      us-east-1a :us-east-1
                      us-east-1b :us-east-1
                      us-east-1c :us-east-1
                      us-east-1d :us-east-1
                      ap-northeast-1a :ap-northeast-1
                      ap-northeast-1b :ap-northeast-1
                      us-west-1a :us-west-1
                      us-west-1b :us-west-1
                      us-west-1c :us-west-1
                      ap-southeast-1a :ap-southeast-1
                      ap-southeast-1b :ap-southeast-1
                    

                    【讨论】:

                      【解决方案24】:

                      还在寻找从实例中查找区域的解决方案,这是我的纯 Bash 解决方案:

                      az=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
                      region=${az:0:${#az}-1}
                      

                      除非有些地区的 AZ 有两个以上的字母,我不知道。

                      【讨论】:

                        【解决方案25】:

                        如果您正在寻找更简单的方法,您可以查看 /etc/resolv.conf 并找到类似“search us-west-2.compute.internal”的行。例如:

                        $ grep "^search" /etc/resolv.conf | sed "s:.* ::; s:\..*::"
                        us-west-2
                        

                        【讨论】:

                          【解决方案26】:

                          ec2metadata(无破折号)是为您提供有关您的 ec2 盒子的所有 aws 托管信息的当前命令。这是最优雅和最安全的方法。 (ec2-metadata 是旧的,不再有效的命令。)

                          【讨论】:

                          • 这可能取决于您选择的虚拟盒子类型。我坚持使用 Linux。
                          【解决方案27】:

                          一种仅使用 egrep 的方法,它应该适用于大多数启动的 linux 实例,而无需安装任何额外的工具。我根据所有当前 AWS 区域的列表对此进行了测试,它们都匹配。

                          curl http://169.254.169.254/latest/meta-data/placement/availability-zone | egrep -o '(\w)+-(\w)+-[0-9]'

                          正则表达式的解释:

                          • "(\w)+" 这匹配任意数量的字母
                          • “-”只匹配一个破折号
                          • “[0-9]”匹配任意1个数字

                          如果你想把它变成一个变量:

                          region=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone | egrep -o '(\w)+-(\w)+-[0-9]')

                          【讨论】:

                            【解决方案28】:

                            对于 sed 和 curl 解决方案,格式似乎发生了一些变化。 对我有用

                            curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | sed -n 's/ "region" : "\(.*\)"[,]/\1/p'
                            

                            【讨论】:

                              【解决方案29】:

                              您可能会使用此 curl 请求获取实例区域

                              $ curl http://169.254.169.254/latest/meta-data/placement/region
                              us-east-1
                              

                              【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2019-11-30
                              • 2015-07-22
                              • 2013-08-02
                              • 1970-01-01
                              • 1970-01-01
                              • 2012-07-18
                              • 2013-02-11
                              • 1970-01-01
                              相关资源
                              最近更新 更多