Files
CFDivePlatform/docs/analysis/2026-10-29-k8s-local-simulation-todo.md
T
a620906209 7bd96ef092
Run Tests / test (pull_request) Successful in 36s
docs(analysis): 新增 K8s 本機模擬待辦記錄
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-29 12:57:13 +08:00

7.3 KiB
Raw Blame History

CFDivePlatform K8s 本機模擬待辦

記錄日期:2026-10-29 狀態:僅記錄,尚未規劃、尚未動工(Hank 指示「先記待辦」)。 範圍:在本機以 Docker Desktop Kubernetes 模擬部署,驗證 manifest 與流程;docker-compose.yml 維持本地開發用,不更動。 實作原則:涉及行為或部署流程變更,先走 OpenSpec(/opsx:propose);本文的決策與清單是規劃輸入,不是 spec。 搭配閱讀:docs/analysis/2026-10-14-project-review-todo.md(M6、M8 與本項有相依)。


已做的決策(2026-10-29 討論)

項目 決策 理由
模擬環境 Docker Desktop 內建 Kubernetes,Kubeadm(單節點)模式 目的是驗證 manifest 與部署流程,不需要多節點;設定最簡單
與 Compose 的關係 Compose 照舊作為本地開發環境,K8s 另放獨立目錄(暫定 k8s/) 兩邊互不影響,避免動到現有 deploy.yml
image 沿用現有 Dockerfile 的 app、web 兩個 target 與正式環境的 compose(不含 compose.override.yml)同一種形態,落差最小
隔離 每個專案一個 namespace 另一個 .NET 專案會一起模擬
上機器的時機 本機模擬驗證完成後,再決定實際叢集 VPS 資源不足,見下節

為什麼不直接在現有 VPS 上裝 K3s

2026-10-29 實測:2 核、1.9GB RAM(可用約 770MB)、磁碟剩 9.2GB(72%),且已跑 13 個容器(含 Gitea、Gitea runner、Nginx Proxy Manager)。 K3s 單節點自身約需 0.5–1GB,會讓 OOM 風險落在現有正式站與 CI。若之後要上實體叢集,建議另租至少 2 核 4GB、40GB 磁碟的機器。


總覽

# 項目 依賴 是否走 OpenSpec
K1 決定 Ingress controller — 否(決策)
K2 盤點 CFDive 的 K8s 資源清單 — 否(盤點)
K3 撰寫 CFDive manifest(k8s/) K1、K2 是
K4 本機部署與驗證 K3 是(含驗證項目)
K5 另一個 .NET 專案納入同一叢集 K1、K4 另案(該專案的 repo)
K6 上傳檔案切 S3/R2 外部帳號 是(既有暫緩項目)
K7 上實體叢集前的差距清單 K4 否(文件)

K1 決定 Ingress controller

現況 Docker Desktop 沒有內建 Ingress。K3s 預設是 Traefik;原本考慮的 ingress-nginx,據我所知 Kubernetes 社群已宣布它在 2026 年 3 月退役,此點為記憶,尚未查證。

待辦

  • 查證 ingress-nginx 目前的維護狀態(官方公告)
  • 在 Traefik 與 Gateway API 實作之間決定(暫定傾向 Traefik:與 K3s 預設一致,之後搬 K3s 的 manifest 改動最少)
  • 確認 Reverb(WebSocket)在所選 Ingress 上的路由與逾時設定

K2 盤點 CFDive 的 K8s 資源清單

現況(依 docker-compose.yml 服務名稱,2026-10-29 核對) app、nginx、frontend、db、scheduler、queue-worker、redis、reverb。volumes 為 mysql-data、redis-data、storage-app-public。

暫定對應(未驗證)

  • app、nginx、frontend、queue-worker、reverb:各一個 Deployment+必要的 Service
  • scheduler:Deployment,副本固定 1(多副本會讓排程重複執行)
  • migration/cache/swagger:目前在 deploy.yml,需改為 Job(或 initContainer)
  • .env:拆成 ConfigMap(非機密)與 Secret(機密);env_file: 在 K8s 沒有對等物
  • db、redis:本機模擬時先決定放叢集內,或沿用 Compose 容器經 host.docker.internal 連線

待辦

  • 逐一核對各服務的 port、healthcheck、啟動指令、依賴順序
  • 決定 MySQL/Redis 放叢集內還是沿用 Compose(叢集內較貼近正式環境,Compose 較省事)
  • 注意 tests/bootstrap.php 的覆蓋清單:擴大環境變數注入範圍時需同步檢查(見專案記憶中 env_file 事件)

K3 撰寫 CFDive manifest

待辦

  • 目錄結構(k8s/ 下用 Kustomize 或純 YAML,擇一)
  • 各 Deployment 的探針(readiness/liveness)對應現有 healthcheck
  • 加上 requests/limits,總量抓接近目標機器(例如 4GB 節點),避免本機資源充裕而漏掉 OOM 問題
  • Secret 結構與正式環境相同,本機只用假值
  • 環境值用正式設定:APP_ENV=production、APP_DEBUG=false、MySQL 8.0、Redis alpine
  • 不帶入 compose.override.yml 的 bind mount

K4 本機部署與驗證

待辦

  • Docker Desktop 啟用 Kubernetes(Kubeadm 模式),確認 kubectl 指向正確 context
  • 本機 build app、web、frontend image,imagePullPolicy 設為 IfNotPresent(或 Never)
  • 驗證:登入、預約、評價主流程;Reverb 即時訊息(WebSocket 經 Ingress);queue job 實際被消化;scheduler 只有一個實例
  • 驗證:migration Job 失敗時的行為(不應讓新版本 Pod 起來)
  • 驗證:滾動更新與回滾(kubectl rollout)
  • 記錄與 Compose 行為不一致之處

K5 另一個 .NET 專案納入同一叢集

注意事項(屬該專案 repo,這裡只記備忘)

  • ASP.NET Core(.NET 8 以後)官方 image 預設非 root、監聽 8080,Service 的 targetPort 要對
  • 巢狀設定以環境變數覆蓋時用雙底線,例如 ConnectionStrings__Default
  • 需自行提供健康檢查端點供探針使用
  • EF migration 用 Job,不要在應用啟動時跑
  • 多副本時需處理 Data Protection 金鑰共用,否則副本間 cookie/antiforgery 互相無法解密

待辦

  • 兩個專案用不同 namespace 與 hostname(例如 cfdive.localhost、other.localhost),共用同一個 Ingress controller

K6 上傳檔案切 S3/R2

現況 storage:migrate-to-s3 指令與 FILESYSTEM_DISK 設定已完成(PR #55、#56),但 R2/S3 帳號尚未申請,VPS 仍是 FILESYSTEM_DISK=local,上傳檔案存在具名 volume storage-app-public。 多副本時 ReadWriteMany 儲存是最大阻礙;本機 hostpath 單機無法代表這個問題,所以這項要在上實體叢集前完成。

待辦

  • 取得 S3 相容服務帳號後,另開 OpenSpec change 接續(不要回頭改已歸檔的 cloud-ready-s3-storage)

K7 上實體叢集前的差距清單

本機模擬無法驗證的項目,上實體叢集後需另外確認:

項目 原因
多節點調度、節點故障 Kubeadm 模式為單節點
檔案儲存的 ReadWriteMany 本機 hostpath 僅單機
TLS/憑證、真實網域 本機用 *.localhost,無 Let's Encrypt
真實流量與資源競爭 本機資源充裕
Gitea Actions 到叢集的部署流程 需等有目標叢集;另需 image registry(目前 image 在 VPS 上 build,是否有 registry 未確認)

待辦

  • 確認 VPS 現行部署是否有 image registry;沒有的話,上叢集前要決定放哪裡
  • 決定實體叢集(另租 K3s 機器,或雲端託管)

開放問題

  • 本機機器規格(Docker Desktop 分配給 WSL2 的記憶體)未確認;兩個專案加 MySQL/Redis 同時跑,建議 8GB 以上
  • Kubeadm 模式下本機 image 是否可直接被 Pod 使用,依記憶判斷為可,尚未在實際版本驗證
  • Ingress 最終選哪個(K1)