故障¶
本文档解释了如何理解您的 API 请求发生了什么。
每个 HTTP 请求都有一个状态码。2xx 状态码表示 API 调用成功。然而,这通常不是故事的结尾。这通常仅意味着启动操作的请求已被接受。它并不意味着您请求的操作已成功完成。
通过请求 ID 跟踪错误¶
有两种类型的请求 ID。
类型 |
描述 |
|---|---|
本地请求 ID |
由每个服务本地生成的唯一请求 ID,并且在参与该操作的所有服务(Nova、Cinder、Glance、Neutron 等)之间不同。格式为 |
全局请求 ID |
用户指定的请求 ID,由参与该操作的所有服务(Nova、Cinder、Glance、Neutron 等)用作通用标识符。此请求 ID 在参与该操作的所有服务中是相同的。格式为 |
云环境通常拥有 ELK(Elastic Search、Logstash、Kibana)基础设施来收集其日志。查询这些流程的唯一方法是在所有相关消息中存在一个通用标识符。全局请求 ID 立即使现有的已部署工具更适合管理 OpenStack。
请求头
在每个 REST API 请求中,您可以从 microversion 2.46 开始在 X-Openstack-Request-Id 头中指定全局请求 ID。格式必须为 req- + UUID (UUID4)。如果格式不正确,Nova 将忽略全局请求 ID。
请求头示例
X-Openstack-Request-Id: req-3dccb8c4-08fe-4706-a91d-e843b8fe9ed2
响应头
在每个 REST API 请求中,X-Compute-Request-Id 会在响应头中返回。从 microversion 2.46 开始,X-Openstack-Request-Id 也会在响应头中返回。
X-Compute-Request-Id 和 X-Openstack-Request-Id 是本地请求 ID。全局请求 ID 不会返回。
响应头示例
X-Compute-Request-Id: req-d7bc29d0-7b99-4aeb-a356-89975043ab5e
X-Openstack-Request-Id: req-d7bc29d0-7b99-4aeb-a356-89975043ab5e
服务器操作¶
大多数 服务器操作 API 都是异步的。通常,API 服务会执行一些最小的工作,然后将请求发送到 nova-compute 服务以完成操作,API 会向客户端返回 202 响应。客户端将轮询 API,直到操作完成,这可能是服务器状态的更改,但通常至少始终等待服务器 OS-EXT-STS:task_state 字段变为 null,表示操作已成功完成或出错。
如果服务器操作失败,并且服务器状态更改为 ERROR,则服务器详细信息中将显示 实例故障。
os-instance-actions API 允许用户最终用户列出服务器操作的结果,通过请求 ID 引用请求的操作。当操作失败并且服务器状态未更改为 ERROR 时,这很有用。
为了说明,考虑使用 flavor m1.tiny 创建的服务器 (vm1)
$ openstack server create --flavor m1.tiny --image cirros-0.4.0-x86_64-disk --wait vm1
+-----------------------------+-----------------------------------------------------------------+
| Field | Value |
+-----------------------------+-----------------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-STS:power_state | Running |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | active |
| OS-SRV-USG:launched_at | 2019-12-02T19:14:48.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | private=10.0.0.60, fda0:e0c4:2764:0:f816:3eff:fe03:806 |
| adminPass | NgascCr3dYo4 |
| config_drive | |
| created | 2019-12-02T19:14:42Z |
| flavor | m1.tiny (1) |
| hostId | 22e88bec09a7e33606348fce0abac0ebbbe091a35e29db1498ec4e14 |
| id | 344174b8-34fd-4017-ae29-b9084dcf3861 |
| image | cirros-0.4.0-x86_64-disk (cce5e6d6-d359-4152-b277-1b4f1871557f) |
| key_name | None |
| name | vm1 |
| progress | 0 |
| project_id | b22597ea961545f3bde1b2ede0bd5b91 |
| properties | |
| security_groups | name='default' |
| status | ACTIVE |
| updated | 2019-12-02T19:14:49Z |
| user_id | 046033fb3f824550999752b6525adbac |
| volumes_attached | |
+-----------------------------+-----------------------------------------------------------------+
服务器的所有者随后尝试将服务器调整为 flavor m1.small,由于没有可用于调整服务器的主机,因此失败
$ openstack server resize --flavor m1.small --wait vm1
Complete
尽管 openstack 命令显示操作已完成,但服务器显示原始 m1.tiny flavor,并且状态不是 VERIFY_RESIZE
$ openstack server show vm1 -f value -c status -c flavor
m1.tiny (1)
ACTIVE
由于状态不是 ERROR,因此服务器详细信息中没有 fault 字段,因此我们通过列出服务器的事件来查找详细信息
$ openstack server event list vm1
+------------------------------------------+--------------------------------------+--------+----------------------------+
| Request ID | Server ID | Action | Start Time |
+------------------------------------------+--------------------------------------+--------+----------------------------+
| req-ea1b0dfc-3186-42a9-84ff-c4f4fb130fae | 344174b8-34fd-4017-ae29-b9084dcf3861 | resize | 2019-12-02T19:15:35.000000 |
| req-4cdc4c93-0668-4ae6-98c8-a0a5fcc63d39 | 344174b8-34fd-4017-ae29-b9084dcf3861 | create | 2019-12-02T19:14:42.000000 |
+------------------------------------------+--------------------------------------+--------+----------------------------+
要查看 resize 操作的详细信息,我们使用该操作的请求 ID
$ openstack server event show vm1 req-ea1b0dfc-3186-42a9-84ff-c4f4fb130fae
+---------------+------------------------------------------+
| Field | Value |
+---------------+------------------------------------------+
| action | resize |
| instance_uuid | 344174b8-34fd-4017-ae29-b9084dcf3861 |
| message | Error |
| project_id | b22597ea961545f3bde1b2ede0bd5b91 |
| request_id | req-ea1b0dfc-3186-42a9-84ff-c4f4fb130fae |
| start_time | 2019-12-02T19:15:35.000000 |
| user_id | 046033fb3f824550999752b6525adbac |
+---------------+------------------------------------------+
我们看到消息是“Error”,但不知道失败了什么。默认情况下,操作的事件详细信息不会显示给没有管理员角色的用户,因此使用 microversion 2.51 查看事件(此处 events 字段为 JSON 格式,以便于阅读)
$ openstack --os-compute-api-version 2.51 server event show vm1 req-ea1b0dfc-3186-42a9-84ff-c4f4fb130fae -f json -c events
{
"events": [
{
"event": "cold_migrate",
"start_time": "2019-12-02T19:15:35.000000",
"finish_time": "2019-12-02T19:15:36.000000",
"result": "Error"
},
{
"event": "conductor_migrate_server",
"start_time": "2019-12-02T19:15:35.000000",
"finish_time": "2019-12-02T19:15:36.000000",
"result": "Error"
}
]
}
默认策略配置允许具有管理员角色的用户查看每个失败事件的 traceback,就像实例故障一样
$ source openrc admin admin
$ openstack --os-compute-api-version 2.51 server event show 344174b8-34fd-4017-ae29-b9084dcf3861 req-ea1b0dfc-3186-42a9-84ff-c4f4fb130fae -f json -c events
{
"events": [
{
"event": "cold_migrate",
"start_time": "2019-12-02T19:15:35.000000",
"finish_time": "2019-12-02T19:15:36.000000",
"result": "Error",
"traceback": " File \"/opt/stack/nova/nova/conductor/manager.py\",
line 301, in migrate_server\n host_list)\n
File \"/opt/stack/nova/nova/conductor/manager.py\", line 367, in
_cold_migrate\n raise exception.NoValidHost(reason=msg)\n"
},
{
"event": "conductor_migrate_server",
"start_time": "2019-12-02T19:15:35.000000",
"finish_time": "2019-12-02T19:15:36.000000",
"result": "Error",
"traceback": " File \"/opt/stack/nova/nova/compute/utils.py\",
line 1410, in decorated_function\n return function(self, context,
*args, **kwargs)\n File \"/opt/stack/nova/nova/conductor/manager.py\",
line 301, in migrate_server\n host_list)\n
File \"/opt/stack/nova/nova/conductor/manager.py\", line 367, in
_cold_migrate\n raise exception.NoValidHost(reason=msg)\n"
}
]
}
日志¶
默认情况下,系统上的所有日志都包含全局请求 ID 和本地请求 ID(如果可用)。这允许管理员跟踪 API 请求处理,因为它在所有不同的 nova 服务或 nova 调用期间的其他组件服务之间过渡。
当 nova 服务在 X-Openstack-Request-Id 头中接收到其他组件的本地请求 ID 时,本地请求 ID 会输出到日志以及 nova 服务的本地请求 ID。
提示
如果在客户端库中使用会话客户端,请将 DEBUG 级别设置为 keystoneauth 日志级别。如果不是,请将 DEBUG 级别设置为客户端库包。例如,glanceclient、cinderclient。
下面提供了示例日志输出。在此示例中,nova 正在使用本地请求 ID req-034279a7-f2dd-40ff-9c93-75768fda494d,而 neutron 正在使用本地请求 ID req-39b315da-e1eb-4ab5-a45b-3f2dbdaba787
Jun 19 09:16:34 devstack-master nova-compute[27857]: DEBUG keystoneauth.session [None req-034279a7-f2dd-40ff-9c93-75768fda494d admin admin] POST call to network for http://10.0.2.15:9696/v2.0/ports used request id req-39b315da-e1eb-4ab5-a45b-3f2dbdaba787 {{(pid=27857) request /usr/local/lib/python2.7/dist-packages/keystoneauth1/session.py:640}}
注意
本地请求 ID 对于创建“调用图”很有用。
实例故障¶
Nova 经常为处理 API 请求时发生的异常添加实例故障数据库条目。这通常包括更多面向管理员的信息,例如堆栈跟踪。对于状态为 ERROR 或 DELETED 的服务器,GET /servers/{server_id} 请求将在 server 资源响应体中包含一个 fault 对象。例如
GET https://10.211.2.122/compute/v2.1/servers/c76a7603-95be-4368-87e9-7b9b89fb1d7e
{
"server": {
"id": "c76a7603-95be-4368-87e9-7b9b89fb1d7e",
"fault": {
"created": "2018-04-10T13:49:40Z",
"message": "No valid host was found.",
"code": 500
},
"status": "ERROR",
...
}
}
通知¶
在许多情况下,还会发出描述错误的通知。这是一个面向管理员的 API,在将其视为结构化日志时效果最佳。
同步故障¶
如果处理我们的 API 请求时发生错误,您将收到非 2xx API 状态码。系统还在响应体中返回有关故障的其他信息。
示例:故障:JSON 响应
{
"itemNotFound":{
"code": 404,
"message":"Aggregate agg_h1 could not be found."
}
}
为了方便起见,错误 code 返回在响应体中。 message 部分返回适合向最终用户显示的易于理解的消息。 details 部分是可选的,可能包含信息——例如,堆栈跟踪——以帮助跟踪错误。 details 部分可能不适合向最终用户显示。
故障的根元素(例如,computeFault)可能会根据错误的类型而变化。以下链接包含一个可能的元素列表及其关联的错误代码。
有关可能的错误代码的更多信息,请参见:https://specs.openstack.org/openstack/api-wg/guidelines/http/response-codes.html
异步故障¶
错误可能发生在服务器构建期间或服务器执行操作时。
在这些情况下,服务器通常被置于 ERROR 状态。对于某些操作,例如调整大小,操作可能会失败,但实例会在尝试操作之前优雅地返回到其原始状态。在这两种情况下,您应该能够从上面描述的 服务器操作 API 中找到更多信息。
当服务器被置于 ERROR 状态时,故障会嵌入到有问题的服务器中。请注意,这些异步故障遵循与同步故障相同的格式。故障包含错误代码、人类可读的消息以及有关错误的可选详细信息。此外,异步故障可能还包含一个 created 时间戳,该时间戳指定了故障发生的时间。
示例:处于错误状态的服务器:JSON 响应
{
"server": {
"id": "52415800-8b69-11e0-9b19-734f0000ffff",
"tenant_id": "1234",
"user_id": "5678",
"name": "sample-server",
"created": "2010-08-10T12:00:00Z",
"hostId": "e4d909c290d0fb1ca068ffafff22cbd0",
"status": "ERROR",
"progress": 66,
"image" : {
"id": "52415800-8b69-11e0-9b19-734f6f007777"
},
"flavor" : {
"id": "52415800-8b69-11e0-9b19-734f216543fd"
},
"fault" : {
"code" : 500,
"created": "2010-08-10T11:59:59Z",
"message": "No valid host was found. There are not enough hosts available.",
"details": [snip]
},
"links": [
{
"rel": "self",
"href": "http://servers.api.openstack.org/v2/1234/servers/52415800-8b69-11e0-9b19-734f000004d2"
},
{
"rel": "bookmark",
"href": "http://servers.api.openstack.org/1234/servers/52415800-8b69-11e0-9b19-734f000004d2"
}
]
}
}