はじめに
Oracle Cloud Infrastructure (OCI) の Always Free インフラ、特にAMD/Armインスタンスを運用するエンジニアにとって最大の敵は、リソース未使用による「インスタンスの自動停止」です。
本記事で紹介するのは、単なる「リソース浪費」のためのハックではありません。「運用しているPOP3アカウントのセキュリティ対策(ClamAV)」という実務的なワークロードを課すことで、システムを健全に稼働させつつ、OCIの非情なアイドル判定を正攻法でパスする実践的な方法論です。
1. 自動停止の判定基準としきい値
OCIは、以下の基準を7日間連続で下回ったインスタンスを「アイドル」と判定し、回収(停止・削除)の対象とします。
| 指標 | 判定基準 (7日間平均) | 備考 |
|---|---|---|
| CPU使用率 | 10%未満 | 95パーセンタイル値で判定 |
| メモリ使用率 | 10%未満 | Arm(A1)では2.4GB以上の継続利用が必要 |
| ネットワーク | 10%未満 | 送受信合計スループット |
特に Arm (A1) インスタンス は、一度失うと再確保が極めて困難なプラチナ・リソースです。24GB RAMという巨大な枠ゆえに、メモリ使用率10%(2.4GB)の壁が最大の障壁となります。
2. 実効的な回避メソッド:ClamAVによる検疫
「無意味な演算」は規約違反や異常挙動としてマークされるリスクがありますが、**「受信データのウィルススキャン」**はインフラとして極めて正当なアクティビティです。
- セキュリティの大義名分: 運用しているPOP3アカウントから受信したデータの検疫。
- リソース消費の制御: スキャン範囲や頻度を調整し、CPU/メモリの使用率を安全圏(10〜15%)に定着させる。
- 実利: クラウド経由で受信するメールの安全性を高め、マルウェアの拡散を未然に防ぐ。
3. Arm (A1) インスタンス向けの最適化
Armインスタンスでは、以下の手法を組み合わせ、2.4GB RAMの壁を突破します。
tmpfs(RAMディスク)による物理メモリ占有
スキャン用の一時ディレクトリを物理メモリ上に配置し、OSレベルで使用中メモリとして認識させます。
# /etc/fstab への定義例(3GBを確保)
tmpfs /var/mail/quarantine tmpfs size=3G,mode=0755 0 0
マルチスレッド・スキャンの実行
4つのOCPUを効率的に稼働させるため、並列プロセスでのスキャンを実施し、平均CPU負荷を底上げします。
4. 実践:生存維持を兼ねた検疫スクリプト
以下に、システム常駐を前提とした監視・検疫スクリプトの実装例を示します。
import subprocess
import time
import logging
import os
# 判定回避のための設定
SCAN_TARGET = "/var/mail/quarantine"
INTERVAL_SEC = 600 # 10分サイクル
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def run_quarantine_cycle():
"""
生存戦略としての検疫実行
- freshclamによるネットワーク・スループットの確保
- clamscanによるCPU/メモリ/IOの活性化
"""
try:
# 1. ウイルス定義更新(ネットワーク負荷の生成)
logging.info("Updating virus definitions...")
subprocess.run(["/usr/bin/freshclam"], check=False, capture_output=True)
# 2. 検疫実行(CPU/メモリ負荷の生成)
# Arm環境ではtmpfs上のディレクトリを対象に負荷をスパイクさせる
logging.info(f"Starting scan on {SCAN_TARGET}...")
result = subprocess.run(
["/usr/bin/clamscan", "-r", "--infected", SCAN_TARGET],
check=False,
capture_output=True,
text=True
)
if "Infected files: 0" not in result.stdout:
logging.warning("Threat detected!")
# ここに通知ロジック(スマホエージェント等)を実装
except Exception as e:
logging.error(f"Survival cycle failed: {e}")
if __name__ == "__main__":
logging.info("OCI Survival Agent started.")
while True:
run_quarantine_cycle()
time.sleep(INTERVAL_SEC)
5. Systemdによるデーモン化
スクリプトを永続化させるためのユニットファイル定義です。
[Unit]
Description=OCI Survival and Mail Quarantine Agent
After=network.target
[Service]
ExecStart=/usr/bin/python3 /usr/local/bin/oci-survival-agent.py
Restart=always
User=root
[Install]
WantedBy=multi-user.target
結論
クラウドの無料枠は「放置するもの」ではなく、「設計によって維持するもの」です。
1/8 OCPUや24GB RAMという特殊な制約に対し、「ClamAVによる検疫」という実務的な業務を割り当てることで、BANのリスクを排除しつつ、永続的に稼働する堅牢なノードを構築可能となります。