OpenStack API实战:从Token获取到云主机管理

张开发
2026/4/21 6:54:08 15 分钟阅读

分享文章

OpenStack API实战:从Token获取到云主机管理
1. OpenStack API入门为什么需要从Token开始第一次接触OpenStack API时很多人会直接跳到云主机管理部分结果发现连最简单的查询都报401错误。这就像去银行取钱却忘了带银行卡——Token就是你在OpenStack系统中的身份凭证。我在实际项目中见过太多开发者卡在这一步所以特别强调所有OpenStack API调用都必须先获取Token。OpenStack的认证系统Keystone就像个严格的安检门。当你发送创建虚拟机的请求时Nova服务会先问Keystone这个Token能进吗有权限吗如果Token无效或过期所有操作都会被拒绝。这种设计虽然增加了初始步骤但大幅提升了系统安全性。获取Token的过程其实很简单只需要三个关键信息认证地址通常是http://IP:35357/v3/auth/tokens管理员账号密码一般在安装时的admin-operc.sh文件里项目作用域默认用admin项目即可我习惯用curl命令测试Token获取比GUI工具更直观。下面这个命令模板可以直接套用curl -i \ -H Content-Type: application/json \ -d { auth: { identity: { methods: [password], password: { user: { name: admin, password: 你的密码, domain: { id: default } } } }, scope: { project: { name: admin, domain: { id: default } } } } } \ http://你的IP:35357/v3/auth/tokens | grep X-Subject-Token执行后会返回类似X-Subject-Token: gAAAAAB...的响应头后面那串乱码似的字符就是你的通行证。记得把它保存到环境变量后续所有API调用都要带着它。2. 实战获取Token细节决定成败虽然获取Token的流程看起来简单但新手常会遇到几个坑。去年我给团队做培训时就有人因为Content-Type没设置对折腾了一下午。这里分享几个必须注意的细节HTTP头部的秘密Content-Type: application/json必须明确指定有些工具默认用form格式响应中的Token在Headers里而非Body中要用-i参数显示完整响应Token有效期默认1小时过期后需要重新获取我推荐用Postman或Apipost这类专业工具调试它们能自动解析响应头。以Apipost为例新建POST请求URL填http://IP:35357/v3/auth/tokens在Body选raw/JSON粘贴上面的JSON模板发送后在下方的响应头标签页找X-Subject-Token常见错误排查返回401检查用户名/密码特别注意domain是否填写正确返回404确认Keystone服务端口35357或5000返回500查看/var/log/keystone/keystone.log日志获取Token后响应体里还藏着重要信息——各个服务的Endpoint。比如catalog: [ { type: compute, endpoints: [ { url: http://172.20.192.161:8774/v2.1/13c023..., interface: public } ] } ]这个url就是后续操作Nova API的地址。不同版本的OpenStack端点可能不同建议动态获取而非硬编码。3. 查询云主机列表你的第一份资源清单拿到Token后第一个实用的API就是查询云主机列表。这相当于你进入机房后先环顾四周——看看有哪些机器、它们的状态如何。通过这个API我们可以获取所有虚拟机的ID、名称、状态等基础信息。完整请求示例curl -X GET \ -H X-Auth-Token: $OS_TOKEN \ -H Content-Type: application/json \ http://172.20.192.161:8774/v2.1/13c023cbddfa4ef39f93c38dfa4b0456/servers?all_tenantstrue关键点解析$OS_TOKEN是前面获取的Token项目ID13c02...必须与Token所属项目一致all_tenantstrue参数表示查询所有租户的云主机返回的数据结构很丰富我通常关注这几个字段{ servers: [ { id: 896e7778-0e27-4ad4-bed9-090d0e0bafb2, name: web-server-01, status: ACTIVE, flavor: { id: 1 }, image: { id: f560b2e0-9801-4f31-8b67-0b1a6e0d3a0e } } ] }高级查询技巧过滤特定状态的云主机?statusERROR分页查询?limit10marker上一页最后一条ID字段过滤?fieldsid,name,status减少返回数据量实际项目中我建议用jq工具处理返回的JSONcurl -s [API地址] | jq .servers[] | {id, name, status}这样输出更简洁{ id: 896e7778..., name: web-server-01, status: ACTIVE }4. 深入云主机详情从宏观到微观知道有哪些云主机后下一步就是查看具体某台的详细信息。这就像从机房总览转到检查单台服务器——查看它的配置、网络、挂载的磁盘等完整信息。请求格式很有规律GET /v2.1/{project_id}/servers/{server_id}用curl实现curl -X GET \ -H X-Auth-Token: $OS_TOKEN \ http://172.20.192.161:8774/v2.1/13c023cbddfa4ef39f93c38dfa4b0456/servers/896e7778-0e27-4ad4-bed9-090d0e0bafb2返回的详情中这些信息特别有用hostId物理机标识排查性能问题时有用addresses云主机的IP地址列表security_groups绑定的安全组规则volumes_attached挂载的云硬盘示例响应片段{ server: { OS-EXT-STS:vm_state: active, addresses: { private: [ { addr: 192.168.1.100, version: 4 } ] }, flavor: { disk: 40, ram: 4096, vcpus: 2 }, metadata: { app: nginx } } }实战技巧获取控制台日志排错神器/servers/{server_id}/console查看虚拟设备拓扑/servers/{server_id}/os-virtual-interfaces获取监控数据需安装ceilometer/servers/{server_id}/diagnostics5. 镜像管理云主机的基因库创建云主机需要先有镜像Image就像装系统需要ISO文件。OpenStack的Glance服务管理这些镜像通过API可以查询、上传、删除镜像。获取镜像列表的APIcurl -X GET \ -H X-Auth-Token: $OS_TOKEN \ http://172.20.192.161:9292/v2/images返回数据示例{ images: [ { id: f560b2e0-9801-4f31-8b67-0b1a6e0d3a0e, name: centos7, disk_format: qcow2, min_disk: 20, min_ram: 1024 } ] }镜像上传实操准备镜像文件如CentOS.qcow2创建镜像元数据curl -X POST \ -H X-Auth-Token: $OS_TOKEN \ -H Content-Type: application/json \ -d { name: my-centos, disk_format: qcow2, container_format: bare } \ http://172.20.192.161:9292/v2/images上传镜像数据curl -X PUT \ -H X-Auth-Token: $OS_TOKEN \ -H Content-Type: application/octet-stream \ --data-binary CentOS.qcow2 \ http://172.20.192.161:9292/v2/images/{image_id}/file镜像管理经验谈公共镜像设置visibilitypublic让所有租户可见大型镜像上传用split分块后并行上传定期清理statusqueued的僵尸镜像6. 完整流程示例从零创建云主机现在我们把所有知识点串联起来完成从创建到查询的完整流程。假设我们要创建一台2核4G的CentOS云主机。步骤1准备基础资源# 获取Token TOKEN$(curl -s -i \ -H Content-Type: application/json \ -d {auth:{identity:{methods:[password],password:{user:{name:admin,password:xxxxxx,domain:{id:default}}}},scope:{project:{name:admin,domain:{id:default}}}}} \ http://172.20.192.161:35357/v3/auth/tokens | grep X-Subject-Token | awk {print $2}) # 查询镜像ID IMAGE_ID$(curl -s \ -H X-Auth-Token: $TOKEN \ http://172.20.192.161:9292/v2/images | jq -r .images[] | select(.namecentos7) | .id) # 查询规格ID FLAVOR_ID$(curl -s \ -H X-Auth-Token: $TOKEN \ http://172.20.192.161:8774/v2.1/flavors | jq -r .flavors[] | select(.ram4096) | .id)步骤2创建云主机curl -X POST \ -H X-Auth-Token: $TOKEN \ -H Content-Type: application/json \ -d { server: { name: api-created-vm, imageRef: $IMAGE_ID, flavorRef: $FLAVOR_ID, networks: [{uuid: 网段ID}] } } \ http://172.20.192.161:8774/v2.1/servers步骤3验证创建结果# 查询创建状态 curl -s \ -H X-Auth-Token: $TOKEN \ http://172.20.192.161:8774/v2.1/servers/detail?nameapi-created-vm | jq .servers[0].status # 获取登录IP curl -s \ -H X-Auth-Token: $TOKEN \ http://172.20.192.161:8774/v2.1/servers/detail?nameapi-created-vm | jq .servers[0].addresses7. 避坑指南我踩过的那些雷在OpenStack API的使用过程中有些错误看似简单却可能浪费你数小时。这里分享几个真实案例时间同步问题有次Token总是莫名失效最后发现是控制节点时间不同步。Keystone会校验Token的签发时间如果节点间时间差超过5分钟就会拒绝请求。解决方法很简单# 所有节点执行 ntpdate time.apple.com版本兼容陷阱某次升级后API突然报404原来是Nova从v2迁移到v2.1时部分端点发生了变化。建议始终使用/v2.1而非/v2动态获取Endpoint而非硬编码检查/etc/nova/nova.conf中的enable_deprecated_api配置权限不足的隐形错误即使使用admin账号某些操作也需要明确指定权限。比如查询所有租户的云主机需要在policy.json中添加规则请求时带all_tenantsTrue参数确认Token的scope是system而非project性能优化建议当管理大量云主机时API响应可能变慢。我的经验是添加limit100markerxxx分页参数使用fieldsid,name减少返回数据量对频繁查询的数据做本地缓存8. 扩展应用API调用的高级玩法基础操作掌握后可以尝试这些提升效率的技巧并发创建云主机用Python多线程同时创建多台云主机import threading import requests def create_vm(token, name): headers {X-Auth-Token: token} data {server: {name: name, imageRef: img-id, flavorRef: flavor-id}} requests.post(http://IP:8774/v2.1/servers, jsondata, headersheaders) threads [] for i in range(5): t threading.Thread(targetcreate_vm, args(token, fvm-{i})) threads.append(t) t.start() for t in threads: t.join()自动化运维脚本定期检查异常云主机的Shell脚本#!/bin/bash TOKEN$(获取Token的逻辑) ABNORMAL_VMS$(curl -s -H X-Auth-Token: $TOKEN \ http://IP:8774/v2.1/servers/detail?statusERROR | jq -r .servers[].id) for vm in $ABNORMAL_VMS; do echo 重启异常虚拟机 $vm curl -X POST -H X-Auth-Token: $TOKEN \ http://IP:8774/v2.1/servers/$vm/action \ -d {reboot: {type: SOFT}} done与Terraform集成在Terraform中直接调用OpenStack API获取动态数据data external flavor_info { program [bash, -c, EOF curl -s -H X-Auth-Token: $(openstack token issue -f value -c id) \ http://IP:8774/v2.1/flavors/1 | jq {name: .flavor.name, vcpus: .flavor.vcpus} EOF ] } output flavor_details { value data.external.flavor_info.result }

更多文章