ECS 补丁管理
使用 OOS ACS-ECS-BulkyApplyPatchBaseline 模板在阿里云 ECS 实例上扫描和安装操作系统补丁。
架构
ECS + OOS + 云助手 + 快照(可选)
- OOS 模板:
ACS-ECS-BulkyApplyPatchBaseline—— 用于批量补丁操作的内置公共模板 - 云助手:在 ECS 实例上执行补丁命令(需要安装云助手客户端)
- 快照服务:补丁前创建磁盘快照用于回滚安全(可选)
- 补丁基线:定义扫描/安装哪些补丁(使用默认系统基线或自定义)
预检查:需要 Aliyun CLI >= 3.3.3
运行aliyun version验证 >= 3.3.3。如果未安装或版本过低,
运行curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash安装/更新,
或参阅references/cli-installation-guide.md获取安装说明。
预检查:需要更新 Aliyun CLI 插件
[必须] 运行aliyun configure set --auto-plugin-install true启用插件自动安装。
[必须] 运行aliyun plugin update确保现有插件始终为最新版本。
预检查:需要阿里云凭证
安全规则:
- 绝不读取、回显或打印 AK/SK 值
- 绝不要求用户在对话或命令行中直接输入 AK/SK
- 绝不使用带有明文凭证值的aliyun configure set
- 只能使用aliyun configure list检查凭证状态
```bash
aliyun configure list
```
检查输出中是否存在有效 profile(AK、STS 或 OAuth 身份)。
如果不存在有效 profile,请在此停止。
1. 从 阿里云控制台 获取凭证
2. 在本会话之外配置凭证(通过终端中的aliyun configure或 shell profile 中的环境变量)
3. 在aliyun configure list显示有效 profile 后返回并重新运行
AI-Mode 生命周期管理
在核心工作流开始时(任何 CLI 调用之前):
[必须] 启用 AI-Mode —— Agent Skill 执行需要 AI-mode。
在任何 CLI 调用之前运行以下命令:
```bash
aliyun configure ai-mode enable
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-ecs-patch-management"
```
[必须] 在每一个退出点禁用 AI-Mode —— 在交付最终响应之前(无论何种原因),必须先禁用 AI-mode。这适用于所有退出路径:工作流成功、工作流失败、错误/异常、用户取消、会话结束,或任何不再执行 CLI 命令的场景。
AI-mode 仅用于 Agent Skill 调用场景,Skill 停止运行后绝不能保持启用状态。
```bash
aliyun configure ai-mode disable
```
RAM 策略
本 Skill 所需权限:
| 服务 | Actions | 用途 |
|---|---|---|
| OOS | StartExecution、ListExecutions、CancelExecution、ListTemplates、GetTemplate | 管理补丁执行 |
| OOS | ListPatchBaselines、GetPatchBaseline、ListInstancePatches、ListInstancePatchStates | 补丁基线和状态查询 |
| ECS | DescribeInstances、DescribeInvocations、DescribeInvocationResults、InvokeCommand | 实例验证和云助手 |
| ECS | CreateSnapshot、DescribeSnapshots | 快照管理(可选) |
完整详情:references/ram-policies.md
[必须] 权限失败处理: 当任何命令或 API 调用在执行过程中因权限错误失败时,遵循以下流程:
1. 阅读references/ram-policies.md获取本 SKILL 所需的完整权限列表
2. 使用ram-permission-diagnoseskill 引导用户申请必要权限
3. 暂停并等待用户确认所需权限已授予
需要用户确认的参数
重要:参数确认 —— 在执行任何命令或 API 调用之前,
所有用户可自定义参数(例如 RegionId、实例 ID、操作类型、
快照设置等)都必须与用户确认。未经用户明确批准,不要假设或使用默认值。
| 参数 | 必填 | 说明 | 默认 |
|---|---|---|---|
regionId | 是 | 阿里云地域 ID(例如 cn-hangzhou、cn-shanghai) | 无 |
instanceIds | 是 | 目标 ECS 实例 ID(例如 ["i-bp1example0000000001"]) | 无 |
action | 是 | 操作类型:scan(仅扫描)或 install(扫描 + 安装) | 无 |
rebootIfNeed | 否(仅 install) | 补丁需要时是否重启实例 | false |
whetherCreateSnapshot | 否(仅 install) | 安装补丁前是否创建快照 | false |
retentionDays | 否(仅 install) | 快照保留天数。推荐:7-30(API 范围:1-65536) | 7 |
上述参数名匹配--parameters中使用的 JSON 字段名(顶层键为 camelCase)。注意嵌套targets对象使用 PascalCase 键(ResourceIds、RegionId、Type)——见下方步骤 3 示例。
核心工作流
步骤 0:启用 AI-Mode
aliyun configure ai-mode enable
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-ecs-patch-management"
[必须] 注册 shell trap,使 AI-mode 在每一个退出路径都被禁用
(成功、错误、信号、Ctrl-C、异常终止)。这是步骤 7 中
显式 disable 调用的故障安全补充。
trap 'aliyun configure ai-mode disable' EXIT
### 步骤 1:验证 CLI 和凭证
aliyun version
aliyun configure list
### 步骤 2:验证目标实例
确认目标 ECS 实例存在且处于 `Running` 状态:
aliyun ecs describe-instances \
--region <RegionId> \
--instance-ids '<InstanceIds_JSON>' \
--cli-query 'Instances.Instance[].{InstanceId:InstanceId, Status:Status, OSName:OSName}'
> **前置条件**:目标 ECS 实例必须安装并运行云助手客户端。大多数阿里云公共镜像默认包含它。
### 步骤 3:启动补丁执行
> **[必须] 遵从用户请求的操作。** 如果用户明确要求**安装**补丁(例如“装补丁”、“安装补丁”、“install patches”),你**必须**执行 `action=install`。不要因为先前扫描返回零缺失补丁就跳过安装调用。扫描仅供参考——安装操作有自己的检测逻辑,用户的明确意图始终优先。
> **[必须] StartExecution 是异步的。** 响应仅确认执行已**提交**,而非已完成。响应返回格式为 `exec-xxx` 的 `ExecutionId`(例如 `exec-example0000000001`)。你**必须**捕获此 `ExecutionId` 并轮询 `ListExecutions`(步骤 4)直到 `Status` 达到终态(`Success` 或 `Failed`)才认为操作完成。不要把 StartExecution 成功响应当作补丁操作成功的证明。
> **[必须] 通过 `ClientToken` 保证幂等性。** `StartExecution` 是写操作。网络超时、传输层错误或 Agent 重试循环可能导致同一调用被发出多次,否则会创建**重复执行**(对于 `install`,还会重复快照/重启)。你**必须**传递一个根据请求输入确定性派生的 `--client-token`,使相同输入的重试收敛到同一执行。
>
> **生成规则** —— 对规范输入(action、region、排序后的实例 ID,以及改变行为的仅安装旋钮)计算稳定哈希:
>
> ```bash
> # 从规范输入生成确定性 ClientToken(≤ 64 字符)。
> # 重试时使用相同公式——服务器在约 24 小时内去重。
> CLIENT_TOKEN="patch-$(printf '%s|%s|%s|%s|%s|%s' \
> "<action>" "<RegionId>" "<sorted_comma_joined_InstanceIds>" \
> "<rebootIfNeed_or_empty>" "<whetherCreateSnapshot_or_empty>" "<retentionDays_or_empty>" \
> | shasum -a 256 | cut -c1-32)"
> # 示例输出:patch-9f3c1a8b7e6d5c4f3a2b1d0e9c8b7a6f
> ```
>
> 将结果作为 `--client-token "$CLIENT_TOKEN"` 传给每次 `start-execution` 调用。如果必须在瞬时失败后重试,**复用同一 token**;不要重新生成。
#### 选项 A:仅扫描
aliyun oos start-execution \
--region <RegionId> \
--biz-region-id <RegionId> \
--template-name ACS-ECS-BulkyApplyPatchBaseline \
--client-token "$CLIENT_TOKEN" \
--parameters '{"regionId":"<RegionId>","action":"scan","targets":{"ResourceIds":<InstanceIds_JSON>,"RegionId":"<RegionId>","Type":"ResourceIds"}}'
#### 选项 B:安装补丁
> **🚨 危险——需要用户明确确认的破坏性操作。**
> `action=install` 将修改目标实例上的系统包,并且如果
> `rebootIfNeed=true`,可能**重启**它们,导致服务停机。
>
> 执行下方命令之前,你**必须**:
> 1. 向用户展示完整执行计划——`regionId`、目标实例 ID 的精确列表
> (及**数量**)、`rebootIfNeed`、`whetherCreateSnapshot`、
> `retentionDays`——在单条确认消息中。
> 2. 明确说明:*“即将在 <region> 的 N 个实例上安装补丁。
> Reboot=<true/false>。Snapshot=<true/false>。继续吗?”*
> 3. 等待用户以肯定答复(`yes` / `确认` / `proceed`)回复。
> **不要**从先前轮次推断同意,也不要在沉默时默认 yes。
> 4. 如果用户更改任何参数,重新生成 `CLIENT_TOKEN` 并重新确认。
aliyun oos start-execution \
--region <RegionId> \
--biz-region-id <RegionId> \
--template-name ACS-ECS-BulkyApplyPatchBaseline \
--client-token "$CLIENT_TOKEN" \
--parameters '{"regionId":"<RegionId>","action":"install","rebootIfNeed":<true/false>,"whetherCreateSnapshot":<true/false>,"retentionDays":<number>,"targets":{"ResourceIds":<InstanceIds_JSON>,"RegionId":"<RegionId>","Type":"ResourceIds"}}'
**示例——扫描 `cn-hangzhou` 中的实例 `i-bp1example0000000001`:**
CLIENT_TOKEN="patch-$(printf 'scan|cn-hangzhou|i-bp1example0000000001|||' | shasum -a 256 | cut -c1-32)"
aliyun oos start-execution \
--region cn-hangzhou \
--biz-region-id cn-hangzhou \
--template-name ACS-ECS-BulkyApplyPatchBaseline \
--client-token "$CLIENT_TOKEN" \
--parameters '{"regionId":"cn-hangzhou","action":"scan","targets":{"ResourceIds":["i-bp1example0000000001"],"RegionId":"cn-hangzhou","Type":"ResourceIds"}}'
**示例——安装补丁并创建快照和自动重启:**
CLIENT_TOKEN="patch-$(printf 'install|cn-hangzhou|i-bp1example0000000001|true|true|7' | shasum -a 256 | cut -c1-32)"
aliyun oos start-execution \
--region cn-hangzhou \
--biz-region-id cn-hangzhou \
--template-name ACS-ECS-BulkyApplyPatchBaseline \
--client-token "$CLIENT_TOKEN" \
--parameters '{"regionId":"cn-hangzhou","action":"install","rebootIfNeed":true,"whetherCreateSnapshot":true,"retentionDays":7,"targets":{"ResourceIds":["i-bp1example0000000001"],"RegionId":"cn-hangzhou","Type":"ResourceIds"}}'
### 步骤 4:监控执行状态
从步骤 3 的响应中提取 `ExecutionId`(格式:`exec-xxx`),然后轮询 `ListExecutions` 直到执行达到终态:
aliyun oos list-executions \
--region <RegionId> \
--biz-region-id <RegionId> \
--execution-id <ExecutionId> \
--cli-query 'Executions.Execution[0].{ExecutionId:ExecutionId, Status:Status, StartDate:StartDate, EndDate:EndDate}'
**终态**(`Status` 匹配以下之一时停止轮询):
| 状态 | 含义 | 下一步 |
|--------|---------|-------------|
| `Success` | 执行成功完成 | 进入步骤 5(日志)和步骤 6(验证补丁) |
| `Failed` | 执行失败 | 检查步骤 5 的日志以诊断失败 |
| `Cancelled` | 执行被取消 | 无进一步操作;如需要则重新运行 |
**非终态**(继续轮询):`Started`、`Running`、`Queued`、`Waiting`。以合理间隔(例如每 10-30 秒)继续轮询直到达到终态。只有 `Status` 为 `Success` 或 `Failed` 时才认为补丁操作完成。
### 步骤 5:查看执行日志
aliyun oos list-execution-logs \
--region <RegionId> \
--biz-region-id <RegionId> \
--execution-id <ExecutionId>
### 步骤 6:验证补丁结果
`scan` 或 `install` 执行达到 `Success` 后,两个互补 API 报告每个实例上的补丁状态:
#### 6a. `ListInstancePatches` —— 单实例逐补丁详情
返回实例上检测到的完整单个补丁列表,带元数据如补丁名/KB、分类、严重程度和逐补丁状态(例如 `Installed`、`Missing`、`NotApplicable`)。用此检查**哪些**补丁存在、缺失或失败。
aliyun oos list-instance-patches \
--region <RegionId> \
--biz-region-id <RegionId> \
--instance-id <InstanceId>
#### 6b. `ListInstancePatchStates` —— 跨实例按状态计数摘要
返回每个实例按状态分组的补丁聚合计数(例如 `InstalledCount`、`MissingCount`、`FailedCount`、`NotApplicableCount`)。用此快速评估每个类别**有多少**补丁,而无需枚举单个补丁。
aliyun oos list-instance-patch-states \
--region <RegionId> \
--biz-region-id <RegionId> \
--instance-ids '<InstanceIds_JSON>'
**何时用哪个:**
- 需要高层合规摘要(例如“实例 i-xxx 仍有 3 个缺失补丁”)?→ `ListInstancePatchStates`
- 需要识别具体补丁(例如“哪些 CVE 仍缺失”)?→ `ListInstancePatches`
### 步骤 7:禁用 AI-Mode
aliyun configure ai-mode disable
> **[必须] 在每一个退出点始终禁用 AI-mode** —— 成功、失败、错误或取消。
成功验证
详细验证步骤见 references/verification-method.md。
快速验证检查清单:
| 步骤 | 检查 | 命令 |
|---|---|---|
| 1 | CLI 版本 >= 3.3.3 | aliyun version |
| 2 | 凭证有效 | aliyun configure list |
| 3 | 实例运行中 | aliyun ecs describe-instances |
| 4 | 执行已启动 | 响应包含 ExecutionId |
| 5 | 执行成功 | 通过 list-executions 的 Status = Success |
| 6 | 补丁已应用 | list-instance-patches 显示 Missing 计数减少 |
清理
取消运行中的执行
aliyun oos cancel-execution \
--region <RegionId> \
--execution-id <ExecutionId>
快照生命周期
用 whetherCreateSnapshot=true 创建的快照在其 retentionDays 窗口到期时自动删除。不要手动删除它们——依赖保留窗口保持清理确定性,并避免意外移除另一个回滚工作流仍需要的快照。
检查现有快照(只读):
aliyun ecs describe-snapshots \
--region <RegionId> \
--instance-id <InstanceId>
最佳实践
- 安装前始终先扫描 —— 先运行
action: scan了解有哪些补丁可用,再决定是否安装。但是,如果用户明确请求安装补丁,你必须仍然执行action=install,无论扫描结果如何。 扫描显示零缺失补丁不意味着你可以跳过安装——用户的明确意图优先。install操作执行自己的内部扫描,可能检测到独立扫描未检测到的补丁。用户要求安装时,绝不用扫描替代安装。 - 生产环境启用快照 —— 为生产实例设置
whetherCreateSnapshot: true并设置合适的retentionDays以启用回滚。快照自动过期——无需手动清理。 - 在维护窗口安排 —— 补丁安装可能需要重启。与业务相关方协调。
- 先在非生产测试 —— 应用到生产前始终在预发布/开发实例验证补丁。
- 监控执行日志 —— 用
list-execution-logs跟踪实时进度并排查失败。 - 谨慎处理重启 —— 只有在你可容忍实例停机时才设置
rebootIfNeed: true。对于关键服务,使用rebootIfNeed: false并手动重启。 - 保持 retentionDays 合理 —— 推荐 7-30 天。更长保留增加存储成本。
参考链接
| 资源 | 路径 |
|---|---|
| CLI 安装指南 | references/cli-installation-guide.md |
| RAM 策略 | references/ram-policies.md |
| 相关命令 | references/related-commands.md |
| 验证方法 | references/verification-method.md |
| 验收标准 | references/acceptance-criteria.md |
阿里云skills
◯ 评论 0