元数据

Nova 通过一种称为元数据的机制向其启动的实例提供配置信息。这些机制被广泛用于 cloud-init 等辅助工具,以指定诸如实例应使用的 root 密码等内容。

这些元数据可以通过config drive(配置驱动)或metadata service(元数据服务)提供,并且可以通过user data(用户数据)功能进行一定程度的自定义。本指南概述了这些功能以及可用元数据的类型。

元数据类型

有三组不同的用户需要能够为实例指定元数据。

用户提供的数据

启动实例的用户可以通过多种方式将元数据传递给实例。对于认证密钥对,可以使用 nova API 的密钥对功能上传密钥,然后在 nova boot API 请求期间指定该密钥。对于结构不那么清晰的数据,可以通过 nova API 的 user data 功能传递一个小的不透明数据块。这种非结构化数据的示例包括实例应使用的 puppet 角色,或者从其获取启动后配置信息的服务器的 HTTP 地址。

Nova 提供的数据

Nova 本身需要通过其元数据系统的内部实现向实例传递信息。这些信息包括实例请求的主机名以及实例所在的可用区。默认情况下会发生这种情况,不需要用户或部署者进行任何配置。

Nova 提供了 OpenStack 元数据 APIEC2 兼容 API。OpenStack 元数据和 EC2 兼容 API 都按日期进行版本控制。稍后会对此进行描述。

部署者提供的数据

OpenStack 的部署者可能需要将数据传递给实例。也可能用户在启动实例时不知道这些数据。例如,可能是一个在启动后用于将实例注册到 Active Directory 的加密令牌——启动实例的用户不应有权访问 Active Directory 以创建此令牌,但 nova 部署可能具有代表用户生成令牌的权限。可以使用 vendordata 功能来实现,该功能必须由您的云操作员配置。

元数据服务

注意

本节提供关于元数据服务的最终用户信息。有关元数据服务的部署信息,请参阅 admin guide(管理员指南)。

metadata service(元数据服务)提供了一种方式,让实例可以通过 REST API 检索特定于实例的数据。实例通过 169.254.169.254fe80::a9fe:a9fe 访问此服务。所有类型的元数据,无论是用户提供的、nova 提供的还是供应商提供的,都可以通过此服务访问。

版本 22.0.0 中已更改:从 Victoria 版本开始,元数据服务可以通过 IPv6 在链路本地地址 fe80::a9fe:a9fe 上访问。

注意

与所有 IPv6 链路本地地址一样,元数据 IPv6 地址不完整,没有区域标识符(在 Linux 来宾中,通常是接口名称与百分号连接)。请注意,在 URL 中,您应该对百分号本身进行 URL 编码。例如,假设来宾中的主网络接口是 ens2,则将 http://[fe80::a9fe:a9fe%25ens2]:80/... 替换为 http://169.254.169.254/...

使用元数据服务

要检索 OpenStack 元数据 API 支持的版本列表,请向 http://169.254.169.254/openstack 发送 GET 请求,这将返回一个目录列表

$ curl http://169.254.169.254/openstack
2012-08-10
2013-04-04
2013-10-17
2015-10-15
2016-06-30
2016-10-06
2017-02-22
2018-08-27
latest

有关这些目录的内容和结构的信息,请参阅 OpenStack 格式元数据

要列出 EC2 兼容元数据 API 支持的版本,请向 http://169.254.169.254 发送 GET 请求,这将再次返回一个目录列表

$ curl http://169.254.169.254
1.0
2007-01-19
2007-03-01
2007-08-29
2007-10-10
2007-12-15
2008-02-01
2008-09-01
2009-04-04
latest

有关这些目录的内容和结构的信息,请参阅 EC2 兼容元数据

Config drives

注意

本节提供关于 config drive(配置驱动)的最终用户信息。有关 config drive 功能的部署信息,请参阅 admin guide(管理员指南)。

config drive(配置驱动)是在实例启动时附加到实例的特殊驱动器。实例可以挂载此驱动器并从中读取文件,以获取通常通过元数据服务可用的信息。

使用 config drive 的一个用例是在不使用 DHCP 为实例分配 IP 地址时传递网络配置。例如,您可以通过 config drive 传递实例的 IP 地址配置,实例可以在您配置实例的网络设置之前挂载和访问该配置。

使用 config drive

要为实例启用 config drive,请将 --config-drive true 参数传递给 openstack server create 命令。

以下示例启用 config drive 并传递一个 user data 文件和两个键值元数据对,所有这些都可以从 config drive 访问

$ openstack server create --config-drive true --image my-image-name \
    --flavor 1 --key-name mykey --user-data ./my-user-data.txt \
    --property role=webservers --property essential=false MYINSTANCE

注意

Compute 服务可以配置为始终创建一个 config drive。有关更多信息,请参阅 admin guide(管理员指南)。

如果您的客户操作系统支持按标签访问磁盘,您可以将 config drive 挂载为 /dev/disk/by-label/configurationDriveVolumeLabel 设备。在以下示例中,config drive 具有 config-2 卷标

# mkdir -p /mnt/config
# mount /dev/disk/by-label/config-2 /mnt/config

如果您的客户操作系统不使用 udev,则 /dev/disk/by-label 目录不存在。您可以使用 blkid 命令来识别与 config drive 对应的块设备。例如

# blkid -t LABEL="config-2" -odevice
/dev/vdb

识别后,您可以挂载该设备

# mkdir -p /mnt/config
# mount /dev/vdb /mnt/config

挂载后,您可以检查 config drive 的内容

$ cd /mnt/config
$ find . -maxdepth 2
.
./ec2
./ec2/2009-04-04
./ec2/latest
./openstack
./openstack/2012-08-10
./openstack/2013-04-04
./openstack/2013-10-17
./openstack/2015-10-15
./openstack/2016-06-30
./openstack/2016-10-06
./openstack/2017-02-22
./openstack/latest

config drive 上出现的文件取决于您传递给 openstack server create 命令的参数。此目录的格式与 元数据服务 提供的格式相同,不同之处在于 EC2 兼容元数据现在位于 ec2 目录而不是根 (/) 目录中。有关这些目录中文件和子目录的格式的信息,请参阅 OpenStack 格式元数据EC2 兼容元数据 部分。

镜像中的设置

$ openstack image set IMG-UUID --property img_config_drive=mandatory

img_config_drive 镜像元数据属性可用于强制启用 config drive。设置 img_config_drive 指定镜像是否需要 config drive。

Nova 元数据

如前所述,nova 以两种格式提供其元数据:OpenStack 格式和 EC2 兼容格式。

OpenStack 格式元数据

版本 12.0.0 中已更改:Liberty 版本中添加了对网络元数据的支持。

来自 OpenStack API 的元数据以 JSON 格式分发。为每个版本提供两个文件:meta_data.jsonnetwork_data.jsonmeta_data.json 文件包含 nova 特定的信息,而 network_data.json 文件包含从 neutron 检索的信息。例如

$ curl http://169.254.169.254/openstack/2018-08-27/meta_data.json
{
   "random_seed": "yu5ZnkqF2CqnDZVAfZgarG...",
   "availability_zone": "nova",
   "keys": [
       {
         "data": "ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n",
         "type": "ssh",
         "name": "mykey"
       }
   ],
   "hostname": "test.novalocal",
   "launch_index": 0,
   "meta": {
      "priority": "low",
      "role": "webserver"
   },
   "devices": [
       {
         "type": "nic",
         "bus": "pci",
         "address": "0000:00:02.0",
         "mac": "00:11:22:33:44:55",
         "tags": ["trusted"]
       },
       {
         "type": "disk",
         "bus": "ide",
         "address": "0:0",
         "serial": "disk-vol-2352423",
         "path": "/dev/sda",
         "tags": ["baz"]
       }
   ],
   "project_id": "f7ac731cc11f40efbc03a9f9e1d1d21f",
   "public_keys": {
       "mykey": "ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n"
   },
   "name": "test"
}
$ curl http://169.254.169.254/openstack/2018-08-27/network_data.json
{
    "links": [
        {
            "ethernet_mac_address": "fa:16:3e:9c:bf:3d",
            "id": "tapcd9f6d46-4a",
            "mtu": null,
            "type": "bridge",
            "vif_id": "cd9f6d46-4a3a-43ab-a466-994af9db96fc"
        }
    ],
    "networks": [
        {
            "id": "network0",
            "link": "tapcd9f6d46-4a",
            "network_id": "99e88329-f20d-4741-9593-25bf07847b16",
            "type": "ipv4_dhcp"
        }
    ],
    "services": [
        {
            "address": "8.8.8.8",
            "type": "dns"
        }
    ]
}

:下载 network_data.json JSON 模式。

EC2 兼容元数据

EC2 兼容 API 与 Amazon EC2 元数据服务 的 2009-04-04 版本兼容。这意味着为 EC2 设计的虚拟机镜像可以与 OpenStack 正常工作。

EC2 API 为每个元数据元素公开一个单独的 URL。通过向 http://169.254.169.254/2009-04-04/meta-data/ 发送 GET 查询来检索这些元素的列表。例如

$ curl http://169.254.169.254/2009-04-04/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
hostname
instance-action
instance-id
instance-type
kernel-id
local-hostname
local-ipv4
placement/
public-hostname
public-ipv4
public-keys/
ramdisk-id
reservation-id
security-groups
$ curl http://169.254.169.254/2009-04-04/meta-data/block-device-mapping/
ami
$ curl http://169.254.169.254/2009-04-04/meta-data/placement/
availability-zone
$ curl http://169.254.169.254/2009-04-04/meta-data/public-keys/
0=mykey

实例可以通过向 http://169.254.169.254/2009-04-04/meta-data/public-keys/0/openssh-key 发送 GET 请求来检索公共 SSH 密钥(当用户请求新实例时,由密钥对名称标识)

$ curl http://169.254.169.254/2009-04-04/meta-data/public-keys/0/openssh-key
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDYVEprvtYJXVOBN0XNKVVRNCRX6BlnNbI+US\
LGais1sUWPwtSg7z9K9vhbYAPUZcq8c/s5S9dg5vTHbsiyPCIDOKyeHba4MUJq8Oh5b2i71/3B\
ISpyxTBH/uZDHdslW2a+SrPDCeuMMoss9NFhBdKtDkdG9zyi0ibmCP6yMdEX8Q== Generated\
by Nova

User data

User data(用户数据)是用户在启动实例时可以指定的数据块。实例可以通过元数据服务或 config drive 访问此数据。通常用于传递实例在启动时运行的 shell 脚本。

例如,一个使用 user data 的应用程序是 cloud-init 系统,它是 Ubuntu 的一个开源包,可在各种 Linux 发行版上使用,并且处理云实例的早期初始化。

您可以将 user data 放在本地文件中,并通过 --user-data <user-data-file> 参数在实例创建期间传递它。

$ openstack server create --image ubuntu-cloudimage --flavor 1 \
    --user-data mydata.file VM_INSTANCE

注意

提供的 user data 不应进行 base64 编码,因为它将被自动编码,以便传递给 REST API 的有效输入,该 API 在编码后具有 65535 字节的限制。

启动后,您可以使用元数据服务或 config drive 从实例访问此数据。要通过元数据服务访问它,请向 http://169.254.169.254/openstack/{version}/user_data(OpenStack API)或 http://169.254.169.254/{version}/user-data(EC2 兼容 API)发送 GET 请求。例如

$ curl http://169.254.169.254/openstack/2018-08-27/user_data
#!/bin/bash
echo 'Extra user data here'

Vendordata

注意

本节提供关于 vendordata 功能的最终用户信息。有关此功能的部署信息,请参阅 admin guide(管理员指南)。

版本 14.0.0 中已更改:Newton 版本中添加了对动态供应商数据支持。

如果已配置,实例可以从元数据服务或 config drive 检索特定于供应商的数据。要通过元数据服务访问它,请向 http://169.254.169.254/openstack/{version}/vendor_data.jsonhttp://169.254.169.254/openstack/{version}/vendor_data2.json 发送 GET 请求,具体取决于部署。例如

$ curl http://169.254.169.254/openstack/2018-08-27/vendor_data2.json
{
    "testing": {
        "value1": 1,
        "value2": 2,
        "value3": "three"
    }
}

注意

此文件的存在和内容因部署而异。

通用指南

  • 不要依赖元数据 API 或 config drive 中的 EC2 元数据存在,因为此内容可能会在未来的版本中删除。例如,不要依赖 ec2 目录中的文件。

  • 当您创建访问元数据服务或 config drive 数据的镜像,并且 openstack 目录中有多个目录时,始终选择您的消费者支持的最新日期 API 版本。例如,如果您的客户镜像支持 2012-03-052012-08-052013-04-13 版本,请首先尝试 2013-04-13,如果不存在 2013-04-13,则回退到早期版本。