# Oracle Cloud 自动化部署 ARM 实例 (A1.Flex) 实践指南与避坑笔记

这是一份为您系统整理的 Oracle Cloud 自动化部署实践技术文档。

---

# Oracle Cloud 自动化部署 ARM 实例 (A1.Flex) 实践指南与避坑笔记

**文档版本：** v1.0
**场景描述：** 在 Oracle Cloud 免费套餐额度内，利用闲置 AMD 实例作为跳板机，通过 OCI CLI 与资源管理器（Resource Manager），实现 24 小时无人值守自动化申请极度紧缺的美西圣何塞机房 ARM (A1.Flex) 实例。

---

## 1. 需求与根本原因排查复盘

* **初始需求：** 申请一台 Always Free 的 `VM.Standard.A1.Flex`（4 OCPU, 24GB 内存, 100GB 引导卷）实例。
* **核心故障现象：** 网页端创建时底部提示 `API 错误: 可用性域 VM.Standard.A1.Flex 中配置 AD-1 的容量不足`。
* **根本原因分析 (Root Cause Analysis)：**
美西圣何塞机房（US West San Jose）因物理距离国内较近且网络直连质量高，其免费 ARM 物理宿主机资源池长期处于枯竭状态。常规的手动网页点击创建请求，在并发极高的机器脚本面前毫无胜算。
* **解决方案演进：**
* *方案 A（抓包方案）：* 提取网页 Cookie 写 Python 脚本。**废弃原因**：鉴权 Cookie 有效期极短（通常不足数小时），无法满足长期挂机需求。
* *方案 B（第三方开源庞大脚本）：* 如 `futchas` 的纯手搓 CLI 脚本。**废弃原因**：需要手动从零抓取底层网络、镜像、子网等十几个 OCID 参数，极度繁琐且易错。
* *方案 C（最终最佳实践）：* **网页端生成 Stack (堆栈) + 免密 API Key 鉴权 + 极简 OCI CLI 定时触发 + tmux 守护进程**。将复杂的配置参数固化在云端，本地仅需发送触发执行指令。



---

## 2. 核心技术名词解释

* **Resource Manager (资源管理器) / Stack (堆栈):** Oracle Cloud 提供的“基础设施即代码 (IaC)”服务，底层基于 Terraform。将网页上配置好的机器参数（CPU、内存、硬盘大小、网络）打包存放在云端，形成一个标准的执行模板（即“堆栈”）。
* **OCI CLI (Oracle Cloud Infrastructure Command Line Interface):** Oracle 官方出品的命令行控制工具，是替代网页操作、实现云资源自动化的核心引擎。
* **OCID (Oracle Cloud Identifier):** Oracle Cloud 中所有资源的唯一全局标识符。本方案主要涉及 `User OCID`（用户）、`Tenancy OCID`（租户）和 `Stack OCID`（堆栈）。
* **API Signing Key (API 签名密钥):** 用于 OCI CLI 身份验证的 RSA 非对称密钥对。与 Cookie 不同，API 密钥不过期，是实现长期无人值守自动化的核心鉴权凭据。
* **tmux:** Linux 下的终端复用器 (Terminal Multiplexer)。允许用户在一个窗口中创建多个会话，并且能在 SSH 断开连接后，让进程在系统后台继续安全运行。

---

## 3. 带注释的实操命令汇总

### 环境安装与鉴权配置

```bash
# 1. 下载并执行 OCI CLI 官方安装脚本
bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"

# 2. 刷新环境变量，使 oci 命令立刻生效
source ~/.bashrc
# 或者使用：exec -l $SHELL

# 3. 运行交互式配置向导 (需提前准备 User OCID 和 Tenancy OCID)
oci setup config

# 4. 查看并提取自动生成的公钥，用于填入 Oracle 网页端完成授权
cat ~/.oci/oci_api_key_public.pem

```

### 进程守护与挂机管理 (tmux)

```bash
# 创建并进入一个名为 auto_arm 的新后台会话
tmux new -s auto_arm

# 赋予脚本执行权限并启动脚本
chmod +x arm_stack.sh
./arm_stack.sh

# 退出但不终止当前后台会话的快捷键手势：
# 依次按下：Ctrl+B -> 松开 -> 按 D

# 重新进入已存在的后台会话（查岗或停止脚本用）
tmux attach -t auto_arm

# 在主系统外排查脚本是否仍在运行
ps -ef | grep arm_stack.sh

```

### 实例获取后的防火墙清理 (Ubuntu)

```bash
# 获取机器后，清理系统自带的强管控 iptables 规则，放行所有端口
sudo -i
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
apt-get install -y iptables-persistent
netfilter-persistent save

```

---

## 4. 最终版配置文件代码

创建文件 `arm_stack.sh`，填入以下代码。

**修改重点说明：**

* **`STACK_OCID`**: 必须替换为您自己在 Resource Manager 中生成的真实堆栈 OCID。
* **`sleep 120`**: 延时参数。千万不可设置过低，120 秒（2分钟）是防止触发 Oracle WAF (Web 应用防火墙) 导致账号被风控的最佳实践阈值。

```bash
#!/bin/bash

# ================= 配置区 =================
# [重点修改项]: 将此处替换为您实际的堆栈 OCID (格式: ocid1.ormstack.oc1...)
STACK_OCID="ocid1.ormstack.oc1.us-sanjose-1.amaaaaaapzrp4tiajhsw7keeytrwgdoqn3j2oxfjv3q6evh3j2sfnf36b5nn"
# ==========================================

echo "开始自动执行堆栈抢机任务..."

while true; do
  current_time=$(date "+%Y-%m-%d %H:%M:%S")
  
  # 核心业务逻辑：调用 oci cli 向堆栈发送自动批准(AUTO_APPROVED)的运行作业(Job)
  result=$(oci resource-manager job create-apply-job \
    --stack-id "$STACK_OCID" \
    --execution-plan-strategy "AUTO_APPROVED" \
    2>&1)
    
  if [[ "$result" == *"Job"* ]]; then
      echo "[$current_time] 🚀 堆栈应用请求已成功发送并进入排队状态。"
  else
      # 注: 若网页端 Job 列表产生记录，此处的告警为文本不匹配导致的假报警，可忽略。
      echo "[$current_time] ⚠️ 请求发送失败或配额受限，继续重试..."
  fi
  
  # [重点安全项]: 强制休眠 120 秒，严格控制 API 请求速率避免账号封禁
  sleep 120
done

```

---

## 5. 避坑总结 (Lessons Learned)

1. **OCI CLI 安装死循环陷阱：**
若系统残留了旧的安装目录，脚本会询问 `Remove this directory? (y/N)`。默认选项是 N。若不仔细看直接狂按回车，会导致安装程序无限循环询问。**必须手动输入小写 `y` 并回车**才能破局。
2. **API 密钥密码阻碍自动化：**
在执行 `oci setup config` 生成密钥对时，系统会询问 `Enter a passphrase for your private key`。为了实现无人值守的挂机，**绝对不能设置密码**。必须直接按回车，或输入 `N/A` 确认跳过。否则脚本每次运行都会阻塞等待人工输入密码。
3. **前/后台运行环境错位：**
在使用 `tmux` 时，切忌将含有脚本运行命令（`./arm_stack.sh`）的多行代码一次性粘贴进终端。这会导致 tmux 退出后台后，脚本在主系统的前台裸跑。**正确做法是：进入 tmux -> 手动输入运行命令 -> Ctrl+B, D 退出后台**。
4. **Oracle 告警邮件被国内邮箱拦截：**
使用国内邮箱（如 139、QQ 等）订阅 Oracle 的 Events（事件）通知时，由于反垃圾策略，大概率会发生静默丢信。**必须使用 Gmail 等海外主流邮箱** 接收“Instance - Launch End”开机成功通知。
5. **正确理解“Failed”状态：**
自动化运行期间，网页端“作业 (Jobs)”列表中产生大量状态为 `失败 (Failed)` 的记录是**完全正常的符合预期的现象**。这证明请求已经成功穿透至 Oracle 后台，仅仅是因为物理服务器无货。不要因此怀疑脚本逻辑出错。