4. 计算资源自助服务
在 Oracle Cloud Infrastructure(OCI)中,计算资源自助服务的核心不是“让用户自己去点控制台创建机器”,而是把“创建什么规格、装什么系统、初始化成什么状态、挂到哪个网络、谁能创建”这些决策,提前固化成可复用的模板与策略。开发者或业务团队只需提交少量参数,平台就能自动完成虚拟机(VM)或裸金属(BM)实例的交付。这一节围绕三个关键机制展开:实例配置(Instance Configuration)、启动脚本(Cloud-init / User Data)与实例元数据(Metadata),并说明它们如何组合成一条可重复、可审计的自动化交付链路。
一、实例配置:把“一台机器的完整定义”变成可复用对象
实例配置是 OCI Compute 提供的一种模板化资源。它保存了创建实例所需的全部参数:可用性域或容错域、形状(Shape)、镜像(Image)、VCN 与子网、启动卷大小与性能、SSH 密钥、标签、故障域、以及是否分配公共 IP 等。实例配置本身不消耗计算资源,它只是一个“配方”。当平台需要交付一批相同规格的机器时,可以基于同一个实例配置反复创建实例,也可以把它作为实例池(Instance Pool)的模板,配合自动扩缩容使用。
实例配置的价值在于消除手工差异。如果让每个开发者自己在控制台选镜像、选子网、填 SSH 密钥,很容易出现子网选错、镜像版本不一致、标签缺失等问题。平台工程团队可以预先定义若干标准配置,例如“标准 Web 节点”“GPU 训练节点”“裸金属数据库节点”,然后通过 IAM 策略限制普通用户只能使用这些配置,而不能随意指定任意形状或镜像。
下面是一个使用 OCI CLI 从已有实例创建实例配置的示例。注意,这里假设源实例已经按标准配置运行,平台团队通过“反向固化”的方式生成模板:
oci compute instance-configuration create \
--compartment-id ocid1.compartment.oc1..example \
--display-name "std-web-amd-2ocpu" \
--instance-details '{
"shape": "VM.Standard.E4.Flex",
"shapeConfig": {"ocpus": 2, "memoryInGBs": 16},
"sourceDetails": {
"sourceType": "image",
"imageId": "ocid1.image.oc1..example",
"bootVolumeSizeInGBs": 100
},
"metadata": {
"ssh_authorized_keys": "ssh-rsa AAAA... platform@example"
},
"createVnicDetails": {
"subnetId": "ocid1.subnet.oc1..example",
"assignPublicIp": false
}
}'
执行成功后,OCI 返回一个实例配置 OCID。后续创建实例时,只需引用该 OCID,并覆盖少量运行时参数(如显示名称、故障域),即可保证规格一致。对于裸金属实例,实例配置同样适用,只是形状会变为 BM.* 系列,且启动卷、网络附件等参数需要按裸金属的硬件特性调整。
二、启动脚本与元数据:让机器“开机即就绪”
实例配置解决了“机器长什么样”,但机器启动后还需要完成系统初始化:安装软件包、配置服务、拉取代码、注册到监控、挂载存储等。OCI 通过 Cloud-init 机制支持启动脚本。用户可以在创建实例时通过 user_data 字段传入一段 Base64 编码的 Cloud-init 脚本,实例首次启动时由 Cloud-init 自动执行。
与此同时,实例元数据提供了一种“键值对”方式向实例内部传递信息。元数据分为两类:一类是 OCI 系统保留的元数据,如实例 OCID、区域、可用性域、形状等,实例内部可通过元数据服务(169.254.169.254)读取;另一类是用户自定义元数据,平台团队可以把环境标识、应用版本、配置中心地址等写入元数据,启动脚本再读取这些值,从而让同一份脚本适配不同环境。
下面是一个典型的 Cloud-init 启动脚本示例,它从元数据中读取环境标识,并据此安装不同的软件包:
#cloud-config
package_update: true
packages:
- nginx
- jq
runcmd:
- ENV=$(curl -s http://169.254.169.254/opc/v2/instance/metadata/env)
- APP_VER=$(curl -s http://169.254.169.254/opc/v2/instance/metadata/app_version)
- echo "env=$ENV app_version=$APP_VER" >> /etc/app-release
- if [ "$ENV" = "prod" ]; then systemctl enable --now nginx; fi
- curl -s http://169.254.169.254/opc/v2/instance/metadata/config_url -o /etc/app/config.json
这段脚本的关键在于:它没有把环境名、版本号硬编码在脚本里,而是通过元数据服务动态获取。平台团队只需要在创建实例时传入不同的元数据,就能让同一份启动脚本在开发、测试、生产环境中产生不同行为。这既减少了脚本分支,也避免了敏感信息直接写入脚本。
http://169.254.169.254/opc/v2/instance/,并在请求头中携带 Authorization: Bearer Oracle。v1 端点已逐步弃用,新脚本应直接使用 v2。三、自动化交付链路:从请求到就绪实例
把实例配置、启动脚本和元数据组合起来,就形成了一条完整的自动化交付链路。平台团队可以对外提供一个简单的自助接口,例如一个内部工单表单或一个 REST API,用户只需填写“应用名、环境、规格档位、数量”。平台后端根据这些输入选择对应的实例配置,生成 Cloud-init 脚本,并把环境、版本、配置地址等写入元数据,最后调用 OCI API 创建实例。
下面这张图展示了该链路中三个核心对象之间的关系:实例配置提供“静态规格”,元数据提供“动态参数”,启动脚本负责“开机执行”,三者共同作用后,实例进入“就绪”状态并注册到平台。
四、裸金属实例的差异与注意事项
裸金属实例与虚拟机实例在自动化交付上的主要差异在于:裸金属实例通常不共享宿主机,启动时间更长,且部分形状对可用性域、故障域有更严格的限制。使用实例配置时,需要确认目标形状在所选可用性域中可用,并预留足够的容量。此外,裸金属实例的启动卷往往需要更大的容量和更高的性能级别,元数据中的 SSH 密钥、网络配置也需要与物理网卡数量匹配。
在启动脚本方面,裸金属实例同样支持 Cloud-init,但由于其常用于高性能数据库、HPC 或专用工作负载,脚本中可能需要额外处理大页内存、NUMA 绑定、RDMA 网卡配置等。平台团队应把这些差异封装在“裸金属专用实例配置 + 专用启动脚本”中,而不是让用户自行处理。
五、可执行的自助交付检查清单
为了让平台团队能够落地这套机制,下面给出一份可直接使用的检查清单。它覆盖了从模板定义到实例就绪的关键判断点:
| 检查项 | 判断依据 | 常见问题 |
|---|---|---|
| 实例配置是否覆盖目标形状 | VM 与 BM 分别建立配置,形状、镜像、子网已固定 | 用户绕过配置直接选任意形状 |
| 元数据是否包含环境标识 | env、app_version、config_url 等键存在且非空 | 脚本硬编码环境名,导致误配 |
| 启动脚本是否幂等 | 重复执行不会破坏系统状态 | 脚本中直接覆盖配置文件 |
| 实例是否注册到平台 | 启动完成后能读取到实例 OCID 与就绪标记 | 脚本执行失败但实例仍显示运行中 |
| 裸金属容量是否预留 | 目标可用性域中 BM 形状有可用容量 | 创建请求排队或失败 |
最后需要强调:自助服务不等于“无约束”。平台工程团队应通过 IAM 策略限制用户只能使用已批准的实例配置,通过标签强制要求资源归属,通过元数据注入审计信息。这样,开发者获得的是“快速拿到一台符合规范的机器”,而不是“随意创建任意机器”。实例配置、启动脚本与元数据三者配合,正是把这种“受控的自助”落到实处的技术基础。