11 KiB
AWOOOI Ansible 運作模型
最後更新:2026-05-12(台北時間) 範圍:說明 Ansible 在 110 / 120 / 121 / 188 的運維、冷啟動恢復、監控與部署安全中扮演的角色。
產品架構定位
Ansible 是主機狀態收斂層,負責 Kubernetes 與 Docker 映像之外的主機狀態,包括檔案、套件、systemd units、cron、nginx 設定、node-exporter textfile monitor,以及主機層資源護欄。
Ansible 不取代下列系統:
k8s/之下的 Kubernetes manifests- 各服務目錄自己管理的 Docker Compose application 定義
- 資料庫恢復決策
- AI 自動修復執行
- 緊急 console fsck
目標控制流程是:
Git repo
-> Ansible 驗證並收斂主機狀態
-> Prometheus 觀測 host/app gate
-> Alertmanager 發出告警
-> AWOOOI/AwoooP AI 進行診斷與分流
-> 涉及有狀態或高風險修復時交由人工批准
目前納管範圍
| 範圍 | 事實來源 | Runtime 目標 |
|---|---|---|
| 主機 inventory | infra/ansible/inventory/hosts.yml |
記錄 110 / 120 / 121 / 188 / 112 |
| 188 public nginx routes | infra/ansible/roles/nginx/templates/* + playbooks/nginx-sync.yml |
/etc/nginx/sites-enabled/* |
| 110 Ollama proxy | 110-ollama-proxy.conf.j2 |
/etc/nginx/sites-enabled/110-ollama-proxy.conf |
| 110 cold-start monitor | roles/cold-start-monitor |
/home/wooo/scripts、cron、node-exporter textfile |
| 110 runner guardrails | roles/runner-guardrails |
actions.runner.* systemd drop-ins |
| 110/188 Docker/systemd/storage/backup textfile exporters | roles/host-textfile-exporters |
/home/*/node_exporter_textfiles/docker_stats.prom、storage_health.prom、backup_health.prom、110 systemd_units.prom |
| 110 Sentry backup / integrity drill | 110-devops.yml --tags backup_jobs |
/backup/scripts/backup-sentry.sh、check-backup-integrity.sh、weekly/monthly cron |
| 主機健康描述 | 110-devops.yml、188-ai-web.yml |
只讀檢查與有限度主機狀態修復 |
必要流程
相關檔案變更後,Gitea workflow .gitea/workflows/ansible-lint.yml 會在 self-hosted runner 上執行 scripts/ops/ansible-validate.sh 與 ansible-lint。本地仍需先跑驗證,避免把明顯壞掉的 Ansible 變更推進 CI。
1. 本地驗證
任何 Ansible 變更前先執行:
bash scripts/ops/bootstrap-ansible-validation-env.sh --recreate
PATH="${ANSIBLE_VALIDATION_VENV:-/tmp/awoooi-ansible-venv}/bin:$PATH" \
bash scripts/ops/ansible-validate.sh
bootstrap-ansible-validation-env.sh 會建立 pinned 驗證工具鏈:ansible-core==2.17.14、ansible-lint==24.12.2。如果本機沒有 ansible-playbook,ansible-validate.sh 仍會驗證 YAML 與 shell syntax,並明確提示已跳過 Ansible syntax-check;但重開機 SOP、CI 與接手稽核應使用 bootstrap venv,避免只做半套驗證。
若要稽核整個重開機恢復包是否齊全:
bash scripts/reboot-recovery/reboot-recovery-readiness-audit.sh --live --no-color
若要確認是否可以釋放 P3 高負載工作:
bash scripts/reboot-recovery/p3-controlled-release-gate.sh --no-color
2. 演練(--check)
從 repo root 執行:
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/site.yml --check
針對單一變更時:
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/nginx-sync.yml --tags 188 --check
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags cold_start_monitor --check
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags runner_guardrails --check
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags textfile_exporters --check
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags backup_jobs --check
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/188-ai-web.yml --tags textfile_exporters --check
3. 套用
只套用最小必要 tag:
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/nginx-sync.yml --tags 188
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags cold_start_monitor
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags runner_guardrails
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags textfile_exporters
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/110-devops.yml --tags backup_jobs
ansible-playbook -i infra/ansible/inventory/hosts.yml infra/ansible/playbooks/188-ai-web.yml --tags textfile_exporters
4. 事後驗證
Ansible apply 不等於完成;runtime gate 變綠才算完成:
SSH_BATCH_MODE=yes bash scripts/reboot-recovery/full-stack-cold-start-check.sh --send-alert-test
curl -kLsS -o /dev/null -w '%{http_code}\n' https://awoooi.wooo.work/api/v1/health
curl -kLsS -o /dev/null -w '%{http_code}\n' https://mo.wooo.work/health
冷啟動整合
重開機恢復時:
- 主機卡在 initramfs 時,先用 console/fsck 讓主機乾淨開機。
- 只在必要時人工恢復依賴鏈:188 data layer、110 registry/observability、K3s、public routes。
- Stack 可達後,用 Ansible 把 live state 收回 repo/IaC。
- 執行 cold-start gate。
- Gate 變綠前,AI auto-repair 維持 observe-only。
Cold-start monitor 由下列 role/playbook 管理:
infra/ansible/roles/cold-start-monitor
infra/ansible/playbooks/110-devops.yml --tags cold_start_monitor
它會寫入:
/home/wooo/node_exporter_textfiles/cold_start_recovery.prom
/home/wooo/reboot-recovery/cold-start-last.log
Dirty Reboot 與檔案系統防線
110 與 188 曾在重開機後停在 initramfs manual fsck,這一類問題不能只靠網站健康檢查發現。roles/host-textfile-exporters 現在也會部署 storage-health-textfile-exporter.py,每分鐘輸出:
/home/wooo/node_exporter_textfiles/storage_health.prom
/home/ollama/node_exporter_textfiles/storage_health.prom
這個 exporter 只讀取 /proc/mounts、/proc/stat、journalctl -k 與 fsck logs,不會修復、不會重啟、不會寫資料庫。它提供 root filesystem 是否 read-only、目前 boot 是否有 storage/kernel error、上一個 boot 是否留下 dirty reboot/fsck 證據。Prometheus 的 host_storage_health_alerts 只告警與阻擋放量,所有 fsck/資料恢復仍需人工批准。
備份健康與設定檔備份
roles/host-textfile-exporters 也管理 backup-health-textfile-exporter.py。它每 10 分鐘輸出:
/home/wooo/node_exporter_textfiles/backup_health.prom
/home/ollama/node_exporter_textfiles/backup_health.prom
這個 exporter 只讀取 cron、script path、restic snapshot metadata 與既有 textfile,不會執行備份或還原。它用來確認:
- 110 的
/backup/scripts/backup-all.sh、AWOOOI 高頻備份、/backup/configs設定檔備份都存在且新鮮。 - 110 的
/backup/sentry專屬資料層備份新鮮,並且 weeklyrestic check/ monthly restore drill 有成功證據。 - 188 的
backup-from-110與 momo PostgreSQL daily backup 都新鮮。 - 120 的 Velero schedule、latest Completed backup、
backup-restore-testCronJob/Job 狀態可查。 - 預期 script 不缺、cron 不缺、最近 aggregate backup 沒有失敗項目。
設定檔備份由 /backup/scripts/backup-configs.sh 負責,納入每日 backup-all.sh。它會把 nginx、systemd、cron、Docker Compose、K3s manifests、K8s Secret/ConfigMap/RBAC、certs 與 runtime scripts 放進加密 restic repo /backup/configs。Secrets 只允許進加密備份,不得出現在 repo、log、Prometheus label 或告警訊息。
Sentry 資料層備份由 /backup/scripts/backup-sentry.sh 負責,納入每日 backup-all.sh。它會輸出 Sentry Postgres logical dump,並把 ClickHouse、Kafka、Redis、SeaweedFS、Taskbroker、Vroom、Symbolicator 等必要 state 放入加密 restic repo /backup/sentry。這是備份行為,不做 restore,也不停止 production stack。
備份可用性由 /backup/scripts/check-backup-integrity.sh 負責:
- 每週
--mode check:對預期 restic repos 執行restic check --read-data-subset=1%。 - 每月
--mode restore-drill:從每個 repo 抽一個小檔案restic dump latest <sample>到 0700 暫存目錄,驗證 snapshot 可讀。 - 執行狀態寫入
/backup/integrity/check.status與/backup/integrity/restore-drill.status,由backup-health-textfile-exporter.py轉成 Prometheus metrics。
下一批納入 Ansible 的項目
| 優先級 | 項目 | 原因 |
|---|---|---|
| P0 | 110 runner guardrails | roles/runner-guardrails 已建立;下一步是在有 Ansible 的 ops host 做 live dry-run/apply 與 CI syntax-check |
| P0 | Sentry 專屬備份與 restic integrity drill | backup_jobs 已納入 110 playbook;下一步累積 nightly/weekly/monthly 成功證據 |
| P0 | 188 nginx HTTPS route ownership | 避免 public tool routes 在事故後或同步後再次漂移 |
| P1 | certbot/snap certbot 標準化 | 目前 apt certbot/OpenSSL 路徑脆弱,renewal 需要統一路徑 |
| P1 | 110/188 Docker/systemd/storage/backup textfile exporters | roles/host-textfile-exporters 已建立;下一步是在 ops host 上 dry-run/apply,並確認 docker_stats.prom / storage_health.prom / backup_health.prom / systemd_units.prom freshness |
| P1 | node-exporter/cAdvisor caps | 監控元件本身不能變成負載來源 |
| P2 | K3s diagnostic-only host tasks | 只驗證 containerd/kubelet 狀態,不做破壞性修復 |
| P2 | 112 Kali inventory only | 先記錄,不掃描、不修復 |
安全規則
- 預設先跑
--check。 - 用 tags 控制範圍;事故中避免直接套用完整
site.yml。 - 不把密碼寫進 repo、cron、inventory 或 group vars。
- 不讓 Ansible 執行 DB/ClickHouse/Kafka 的破壞性恢復。
- Ansible 只做可預期的主機狀態收斂,不處理未知資料修復。
- 任何有狀態 restart 或 quarantine 仍需人工批准。
- Runner guardrail role 預設不重啟 units;只有在計畫維護窗才設定
runner_guardrails_restart_units=true。
完成定義
Ansible 管理的變更必須全部符合下列條件,才算完成:
scripts/ops/ansible-validate.sh通過。- 目標 playbook dry run 成功,或有文件化原因說明為何略過 dry run。
- 目標 apply 成功。
- 影響 runtime 的變更,
full-stack-cold-start-check.sh --send-alert-test必須變綠。 - 相關 public routes 或 service health endpoints 通過。
docs/LOGBOOK.md記錄套用範圍與驗證結果。