メインコンテンツまでスキップ

CloudEdge 自律ラボ (cloudedge-labctl)

cloudedge-labctl のラボライフサイクル、スモークとフェイルオーバーアクション、エビデンス収集、dry-run デフォルト、TTL タグ、teardown ガードの流れ

実験的機能(CloudEdge)。エージェントが人間の Runbook 確認なしに CloudEdge Selective Address Mobility (SAM) フェイルオーバーラボを実行できる、単一コマンドのハーネスです。インターフェースを固定し、クラウド以外のロジック(run-id/タグ規約、TTL + teardown コストガード、障害プリミティブ、接続マトリクス、エビデンス組み立て)をすべて実装しています。実際のプロバイダーごとのプロビジョニングは、既存の examples/cloudedge-mobility-demo/ パッケージをラップするか、Terraform/CLI 連携用に TODO(lab-operator) としてマークされています。

ハーネスは scripts/cloudedge-labctl.sh で、2 つのヘルパーがあります:

  • scripts/cloudedge-connectivity-matrix.sh — 方向付き ping+ssh マトリクス + アサーション。
  • scripts/cloudedge-evidence-schema.json — ランエビデンスの JSON スキーマ。

--help、dry パス、down --expired にはクラウド認証情報は不要です。

全体を繰り返さずに収束を観測する​

SAMはprovider Readyを待ってから通信を判定します。1回のvalidation内で、既存のprovider収束予算900秒を通信観測と共有します。失敗・欠落した必須項目だけを、各項目最大3回まで再取得します。成功項目と同一のcloud-ingress flowは、そのvalidationと同じ障害状態の中で証拠を共有します。成功flowではtracerouteを実行しません。管理SSHの実行完了を確認できない場合は、製品ping失敗と分けて OBSERVATION_INCONCLUSIVE(終了コード3)にします。回復前の失敗を含む原本は matrix/<label>/flows.*/ に残します。

L2 の取得失敗・指標欠落は未判定とし stdout/stderr を保存します。数値ゼロは取得成功後だけ有効です。gateway の unchanged は各フローの送信元で通信直前・直後の経路を比較し、展開全体の基準ではありません。failover の action は今回の障害開始時刻・アドレス・standby に一致する必要があります。復旧時間には coordinator/API/SSH/poll の時間も含まれ、この上限超過だけで製品退行とは判定しません。60秒の目標は維持します。netns の失敗・cleanup 失敗では作業ディレクトリと cleanup log を保存します。FreeBSD の同一スタック VXLAN ping は WireGuard 経由の転送を実証せず、設定・handshake・所有権・restart の証跡と転送未実証を報告します。IPC 取得は既存の待機予算内で要求ごとに期限を設け、取得不能は exit 3 です。bus の遅い subscriber 試験は throughput 条件を使わず停止検出の watchdog を使います。

診断採取と受入判定は分離します。収束待ちループで doctor sam を連打せず、診断時に1回採取します。同じ診断スナップショット内のstatus・適用済みBGP経路・global RIBは各1回取得し、保存応答から要約を作ります。診断採取の失敗で通信の判定を変更しません。

retained ARPでは、監視HTTPの80ms timeout、100ms counter周期、400ms連続coverage、全区間controller進行は診断用の制約であり、受入条件ではありません。診断失敗でpcapやsender採取を止めません。完全なself ARP捕捉、実target commandとpacketの対応、新鮮な要求とTTL、完了した通信、process identityは維持し、必要証拠の欠落は不成立として区別します。既存の時刻・target・command sequence・provider resource IDを原本に残し、対応付けに使います。

cleanup inventoryではlifecycle変化とidentity不整合を区別します。AWS/OCIのidentityが一致し状態観測だけが異なる場合、同じinventory実行内で該当providerだけを最大2回追加観測し、各回の原本を保持します。identity・tag・accountの不一致、不正な応答、通信失敗を不在と扱いません。他providerのinventoryは継続し、不成立scopeはcountをnullにして資源ゼロ判定を通しません。既存の資源回収・削除ガードは維持します。

次の有料試験の前に、tools/release-qa-labs/tests/ の test_sam_observation.py、test_inventory_resources.py、test_inventory_driver.py で該当する保存応答・負例を再現します。資源は作成しません。実matrix/profile呼出し経路は make cloudedge-representative-redundancy-offline-test で確認します。これらの成功はクラウド実機試験の実施を意味しません。

ライフサイクル​

scripts/cloudedge-labctl.sh up --profile full --provider aws,oci,azure,onprem --ttl 4h
scripts/cloudedge-labctl.sh deploy --commit HEAD # または --build <dist path>
scripts/cloudedge-labctl.sh smoke --matrix d3 --out /tmp/matrix.json
scripts/cloudedge-labctl.sh failover --provider aws --fault stop-active
scripts/cloudedge-labctl.sh smoke --matrix d3 --out /tmp/matrix-after.json
scripts/cloudedge-labctl.sh evidence collect --out evidence/<run-id> --matrix-json /tmp/matrix-after.json
scripts/cloudedge-labctl.sh down --run-id <run-id> --force

up は run-id を stdout に出力します。これをキャプチャして後続のコマンドに渡してください。クラウドへの変更操作はデフォルトで DRY(CE_DRY_RUN=1)です。認証情報と予算の承認後に CE_DRY_RUN=0 を設定して実際に実行します。

プロファイル​

プロファイルサイト数用途
minimalon-prem + クラウド 1最安のスモーク、インターフェース/CI の検証
provider1 プロバイダーの A/B ルーター + クライアントプロバイダーパリティ(AWS/OCI/Azure seize)
fullon-prem + AWS + OCI + Azure4 サイト /24 12 フローデモ
soakTTL 全期間稼働させる full ラン長時間の再収束チェック

soak は運用上は長い --ttl で維持する full ランです(TTL まで down を実行しないでください)。BFD/BGP 再収束の検証に使います。

TTL とコストポリシー​

すべてのクラウドリソースは以下のタグを必ず付与します(ヘルパー cloudedge_tags() が出力し、up がスタンプします):

routerd.cloudedge.run_id <UTCdate>T<time>-cloudedge-<scenario>
routerd.cloudedge.owner
routerd.cloudedge.ttl_expires_at 絶対 UTC RFC3339
routerd.cloudedge.provider
routerd.cloudedge.purpose

コストガードルール:

  • up --ttl <dur> で ttl_expires_at をスタンプします。ランに適した最短の TTL を選んでください。
  • down --run-id <id> は 1 つのランを teardown します。down --expired は TTL を過ぎたすべてのランを teardown します(ラボがない場合は安全に no-op — exit 0)。
  • up は --ttl を事前に検証し、不正な期間ではハードフェイル(非ゼロ終了)します。壊れた/すでに期限切れのコストガードでラボが起動されることはありません。
  • ハーネスの EXIT トラップは、up が中断されたり、プロバイダーが起動途中で失敗した場合にランを teardown します(進行中の期間のみ有効化され、正常完了時に解除されます。正常な up はラボを明示的な down または TTL まで存続させます)。up --keep を指定すると、調査用に部分状態を残します。
  • 失敗時も含め、毎回のラン後に必ず down(または janitor からの down --expired)を実行してください。TTL 超過のラボは run-id なしでクリーンアップ可能です。

障害プリミティブ (failover --fault)​

障害意味初期配線
stop-activeアクティブルーター VM/インスタンスを停止プロバイダー stop CLI(reset-lab.sh 参照)
drainアクティブの MobilityPool で maintenance.drain=truerun-demo.sh の *-drain.yaml を再利用
routerd-bgp-stoprouterd-bgp を停止(BGP セッション切断)ssh systemctl stop routerd-bgp
executor-failプロバイダーアクション executor 拒否(識別情報のスコープダウン)識別情報ポリシー
stale-replay古い pathSig アクションをリプレイ。フェンスされる必要ありprobe_stale_gate_on_aws_b

障害を注入してから smoke と evidence collect を再実行し、復旧を証明します。

エビデンススキーマ​

evidence collect --out <dir> は <dir>/result.json を出力します。scripts/cloudedge-evidence-schema.json に対して検証され、summary.md と(指定されていれば)接続マトリクス JSON も出力されます。形式:

{
"runId": "20260601T031500Z-cloudedge-aws-failover",
"commit": "<sha>",
"scenario": "aws-active-stop-seize",
"result": "pass",
"providers": {
"aws": {"dataplane": "pass", "providerState": "pass"},
"oci": {"dataplane": "pass", "providerState": "pass"},
"azure": {"dataplane": "pass", "providerState": "pass"},
"onprem": {"dataplane": "pass", "providerState": "pass"}
},
"assertions": [
{"name": "ownership_epoch_bumped", "result": "pass"},
{"name": "allow_reassignment_maintained_until_success", "result": "pass"},
{"name": "source_ip_preserved", "result": "pass"},
{"name": "default_gateway_unchanged", "result": "pass"},
{"name": "old_holder_residue_absent", "result": "pass"},
{"name": "stale_action_fenced", "result": "pass"}
],
"costGuard": {"ttlHours": 4, "teardown": "completed"}
}

データプレーンのチェックと source_ip_preserved / default_gateway_unchanged は接続マトリクスから自動的に導出されます。seize/フェンシングアサーション(ownership_epoch_bumped、allow_reassignment_maintained_until_success、old_holder_residue_absent、stale_action_fenced)と providerState は最初 na で、ラボ運用者がプロバイダーインベントリ、BGP mobility パス、プロバイダー trap アクションプラン、アクションジャーナルから取り込みます(collect-evidence.sh 参照)。ランが PASS となるのは result == pass かつすべての必須アサーションがパスした場合のみです。

接続マトリクス​

cloudedge-connectivity-matrix.sh は共有 /24 上のすべての方向付き src -> dst フローを実行し、フローごとに以下をアサートします:

  • source-IP-preserved — 宛先がクライアントサイトの実際のソース IP(mobility /32)をピアアドレスとして認識する(NAT なし)。
  • default-gw-unchanged — ソースクライアントのデフォルトゲートウェイが変更されていない。
  • no-NAT — ping が宛先に到達し、SSH のピア IP がソース IP と一致する。

実行は MATRIX_RUNNER の間接指定を通じて行われるため、マトリクスはオフラインで単体実行可能です(MATRIX_RUNNER にスタブを設定)。実際のラボでは、デフォルトのランナーがデモ環境に対して ssh/ping を使います。出力はフローごとの JSON で、evidence collect --matrix-json で取り込めます。

自律性チャーター(概要)​

エージェントはラボ起動 -> デプロイ -> 障害注入 -> データプレーン検証 -> エビデンス -> teardown -> issue/PR 更新のフルループを所有し、人間が Runbook を読むことなく実行します。クラウドアクションはデフォルトで dry であり、明示的な認証情報/予算の承認でゲートされています。エージェントは常にラボを teardown 済みか TTL コストガード内の状態にしなければならず、PASS には必ずスキーマ有効なエビデンスバンドルを添付する必要があります。

人間のゲート​

以下のみ人間が必要です。それ以外はすべて自動化されています:

  1. 予算 — 支出の承認 / TTL または予算上限の引き上げ。
  2. 認証情報/権限 — クラウド認証情報と executor が使用する最小権限の識別情報/ロールの付与(秘密はコミットされず、プラグインにも渡されません)。
  3. マージ — PR の最終承認。
  4. 本番 — 本番ロールアウト(ラボハーネスでは一切実行されません)。

注意事項​

  • これはラボハーネスであり、本番用のターンキーソリューションではありません。
  • 初期実装: 実際のプロバイダーごとの割り当て/teardown/ノードプッシュは TODO(lab-operator) のスタブか、デモパッケージの薄いラッパーです — run-id タグでフィルタリングした Terraform/OpenTofu またはプロバイダー CLI を接続してください。
  • 実際のアカウント ID / サブスクリプション ID / OCID / ENI/VNIC ID / 秘密情報 / 秘密鍵は決してコミットしないでください。env.example のようにプレースホルダーの論理アドレスを使用してください。

ゲスト準備の証跡​

provider CLI の導入は OpenTofu cloud-init と SAM 準備に分かれています。 AWS は既存の代替導入を維持し、Azure/OCI は既存の cloud-init installer を使います。 コマンド列は失敗時に停止します。準備は cloud-init の状態・出力を保存し、 routerd 配置前に root のサービス PATH で必須 CLI を実行します。操作ホストの CLI や起動完了マーカーだけでは、ゲストの依存を確認できません。

収束・warm-up の各試行は stdout/stderr、終了コード、UTC 時刻を保存します。 診断は sudo で journal を読み、WireGuard の公開フィールドを採取します。 GoBGP がない場合は JSON 解析せず取得不能を記録します。既存試験群の前提対応表は tools/release-qa-labs/test-prerequisites.md にあります。

共通の cloud-init CLI 準備は各試行を保存します。取得には curl の一時障害再試行を使い、既知のネットワーク・パッケージロックによる導入失敗だけを最大3回まで局所再試行します。恒久エラーや再試行枯渇では失敗を保存して準備を停止します。クライアントの APT 準備は既存の4回を維持し、既知の一時障害に限って再試行します。シナリオ全体は繰り返しません。

performance の局所再試行は、server/client の各試行の生出力・退出コード・時刻を保存します。既存の3回とメトリクス用ファイル名は維持し、後続の成功で失敗試行を消しません。