> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # 將 Mastra 部署至 Kubernetes 在多個 [Kubernetes](https://kubernetes.io/) pod 上執行 Mastra 應用程式,讓它可在負載平衡器後方橫向擴展。由於每個 pod 都是獨立程序,各 pod 必須共用發佈/訂閱後端及資料庫,否則在其中一個 pod 啟動的工作,其他 pod 將無法得知。 > **資訊:** 本指南涵蓋如何部署 [Mastra 伺服器](https://mastra.zisheng.pro/zh-HK/docs/server/mastra-server)。如你使用[伺服器適配器](https://mastra.zisheng.pro/zh-HK/docs/server/server-adapters)或[網頁框架](https://mastra.zisheng.pro/zh-HK/docs/deployment/web-framework),請依照該框架慣常的方式部署。 > **注意:** 多 pod 支援依賴目前仍處於 **beta** 階段的[持久 Agent](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents)。API 可能會在次要版本中變更。在正式環境採用前,請先閱讀[已知限制](#known-limitations)。 ## 開始之前 你需要: - 一個 [Mastra 應用程式](https://mastra.zisheng.pro/zh-HK/guides/getting-started/quickstart) - 一個 [Kubernetes](https://kubernetes.io/docs/setup/) 叢集及 [`kubectl`](https://kubernetes.io/docs/tasks/tools/) - 一個叢集可從中提取映像檔的容器登錄檔 - 一個所有 pod 均可連線的共享 [Redis](https://redis.io/) 執行個體 - 一個所有 pod 均可連線的共享 [PostgreSQL](https://www.postgresql.org/) 資料庫 ## 為何多個 pod 需要共享基礎設施 單一 pod 會將執行狀態保留在自己的記憶體內。只有一個 pod 時並無問題,因為每個請求都會到達同一程序。但跨 pod 時便會失效:瀏覽器可能正從 pod A 串流,而使用者的下一個請求卻被路由至 pod B;pod B 並沒有 pod A 上該次執行的記錄。 Redis 和 Postgres 可填補這個缺口: - **發佈/訂閱**會在 pod 之間傳送事件。當事件在一個 pod 上發佈,其他 pod 都會收到。Mastra 使用 [`RedisStreamsPubSub`](https://mastra.zisheng.pro/zh-HK/reference/pubsub/redis-streams),它亦提供按對話串租用的機制,確保同一時間只有一個 pod 擁有某段對話。請參閱 [PubSub](https://mastra.zisheng.pro/zh-HK/docs/server/pubsub)。 - **儲存空間**會保存執行狀態。[持久 Agent](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents) 會將每次執行儲存為 Workflow 快照,因此重新啟動後,或請求被路由至其他位置時,任何 pod 都可從資料庫恢復執行。 ## 設定共享基礎設施 讓 `Mastra` 執行個體指向 Redis 和 Postgres。從環境變數讀取連線資料,令同一映像檔可在每個 pod 中執行。 安裝後端依賴套件: **npm**: ```bash npm install @mastra/redis-streams @mastra/pg @mastra/redis ioredis ``` **pnpm**: ```bash pnpm add @mastra/redis-streams @mastra/pg @mastra/redis ioredis ``` **Yarn**: ```bash yarn add @mastra/redis-streams @mastra/pg @mastra/redis ioredis ``` **Bun**: ```bash bun add @mastra/redis-streams @mastra/pg @mastra/redis ioredis ``` 在 `Mastra` 執行個體上設定發佈/訂閱、儲存空間及共享快取: ```typescript import { Mastra } from '@mastra/core' import { RedisStreamsPubSub } from '@mastra/redis-streams' import { RedisServerCache } from '@mastra/redis' import { PostgresStore } from '@mastra/pg' import Redis from 'ioredis' export const mastra = new Mastra({ // Carries events between pods, and provides // per-thread leases so one pod owns a conversation at a time. pubsub: new RedisStreamsPubSub({ url: process.env.REDIS_URL!, }), // Persists run state so any pod can resume a run. storage: new PostgresStore({ id: 'mastra-storage', connectionString: process.env.DATABASE_URL!, }), // Shared event cache so a reconnecting client can replay missed chunks // from any pod, not only the one that started the run. cache: new RedisServerCache({ client: new Redis(process.env.REDIS_URL!) }), }) ``` `cache` 令可恢復的串流能夠跨 pod 運作。重新連線的用戶端會從此快取重播錯過的事件,因此它必須共用。預設的記憶體內快取只可在同一程序內提供重播。 ## 使用持久 Agent 一般 [`Agent`](https://mastra.zisheng.pro/zh-HK/docs/agents/overview) 會將串流及核准狀態保留在一個 pod 的記憶體內,因此請求落在另一個 pod 時,這些狀態無法保留。[持久 Agent](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents) 會在 Workflow 內執行 Agent 迴圈並保存其狀態,讓任何 pod 都可觀察或恢復同一次執行。 使用 `createDurableAgent()` 包裝 Agent: ```typescript import { Agent } from '@mastra/core/agent' import { createDurableAgent } from '@mastra/core/agent/durable' const agent = new Agent({ id: 'assistant', name: 'Assistant', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5.6-sol', }) export const durableAssistant = createDurableAgent({ agent }) ``` 在上述 `Mastra` 執行個體註冊持久 Agent。其執行狀態現會存放於 Postgres,而事件則透過 Redis 傳送,因此每個 pod 都可存取該次執行。 ## 部署 1. 建置 Mastra 伺服器並將它容器化,然後把映像檔推送至你的登錄檔。請依照 [Mastra 伺服器](https://mastra.zisheng.pro/zh-HK/docs/server/mastra-server)指南進行建置,並確保伺服器讀取 `process.env.PORT` 及監聽 `0.0.0.0`。 2. 將共享連線字串儲存為 Secret: ```bash kubectl create secret generic mastra-secrets \ --from-literal=REDIS_URL='redis://redis:6379' \ --from-literal=DATABASE_URL='postgresql://user:pass@postgres:5432/mastra' ``` 3. 套用 Deployment,讓它執行映像檔並讀取共享 Secret。先以一個副本開始,讓第一個 pod 自行建立資料庫結構,然後在下一步擴展: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: mastra spec: replicas: 1 selector: matchLabels: app: mastra template: metadata: labels: app: mastra spec: containers: - name: mastra image: your-registry/mastra:latest ports: - containerPort: 8080 env: - name: PORT value: '8080' envFrom: - secretRef: name: mastra-secrets readinessProbe: tcpSocket: port: 8080 livenessProbe: tcpSocket: port: 8080 resources: requests: cpu: 500m memory: 512Mi ``` 下方 HorizontalPodAutoscaler 需要 `resources.requests.cpu` 值。Kubernetes 以使用量除以請求量來計算 CPU 使用率;若沒有 CPU 請求,自動擴展器便無法計算目標,亦不會擴展。 ```bash kubectl apply -f deployment.yaml ``` 第一個 pod 準備就緒後,進行擴展: ```bash kubectl wait --for=condition=available deployment/mastra kubectl scale deployment/mastra --replicas=3 ``` > **備註:** 每個副本都執行同一映像檔,並連線至同一 Redis 和 Postgres。令執行可跨 pod 的關鍵是共享基礎設施,而非 pod 數量。 4. 使用 Service 公開 Deployment: ```yaml apiVersion: v1 kind: Service metadata: name: mastra spec: selector: app: mastra ports: - port: 80 targetPort: 8080 ``` ```bash kubectl apply -f service.yaml ``` 5. 使用 HorizontalPodAutoscaler 自動擴展副本: ```yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: mastra spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: mastra minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 ``` ```bash kubectl apply -f hpa.yaml ``` > **備註:** 以 CPU 為基礎的自動擴展需要叢集內執行 [metrics-server](https://github.com/kubernetes-sigs/metrics-server)。GKE、EKS 和 AKS 等託管叢集已包含它;kind 和 minikube 等本機叢集則沒有,因此請先啟用它(例如 `minikube addons enable metrics-server`)。 6. 確認 pod 正在執行: ```bash kubectl get pods -l app=mastra ``` 在一個終端機轉送服務。此命令會持續在前景執行: ```bash kubectl port-forward service/mastra 8080:80 ``` 在另一個終端機呼叫 API: ```bash curl http://localhost:8080/api/agents ``` 若回傳 Agent 的 JSON 清單,即表示部署已開始提供服務。 > **注意:** 公開端點前,請先設定[驗證](https://mastra.zisheng.pro/zh-HK/docs/server/auth)。 ## 串流與重新連線 持久 Agent 會透過共享發佈/訂閱,把串流區塊發佈至每次執行專屬的主題。中斷連線的用戶端可使用執行 ID 呼叫 `observe()` 重新連線,並從共享快取重播錯過的區塊: ```typescript const { output, cleanup } = await durableAssistant.observe(runId) for await (const chunk of output.fullStream) { // Chunks from the run, including any missed while disconnected } cleanup() ``` 由於執行狀態位於 Postgres,而事件位於 Redis,重新連線的請求可由任何 pod 處理,不限於啟動該次執行的 pod。請參閱[可恢復串流](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents)。 多個用戶端可同時觀察同一次執行。每次 `observe()` 呼叫都會收到完整串流,因此無論一名使用者從兩部裝置觀看,還是兩人追蹤同一次執行,都會保持同步。 ## 跨 pod 核准 Tool 持久 Agent 會在呼叫 Tool 時暫停,直至有人核准。由於已暫停的執行儲存於 Postgres,核准可到達任何 pod,不限於啟動該次執行的 pod。 啟動需要核准的執行: ```typescript const { runId } = await durableAssistant.stream('Delete the archived records', { requireToolApproval: true, memory: { thread: 'thread-1', resource: 'user-1' }, }) ``` 執行會在 Tool 運行前暫停。稍後可從任何 pod 核准: ```typescript await durableAssistant.resume(runId, { approved: true }) ``` 處理核准的 pod 會從 Postgres 載入已暫停的執行,然後執行已核准的 Tool,並透過共享發佈/訂閱發佈結果,讓觀察該次執行的用戶端收到後續內容。請參閱 [Tool 核准](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents)。 ## 已知限制 - 預設的程序內設定會將執行狀態保留在一個 pod 的記憶體內,不會在 pod 之間共享。請配合共享 Redis 和 Postgres 使用[持久 Agent](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents),令串流、核准及重新連線可跨 pod 運作。 - 跨 pod 的串流、核准及重新連線需要使用持久 Agent 路徑。一般 Agent 會將執行狀態保留於記憶體,無法在另一個 pod 上恢復。 - 多個 pod 同時針對尚未初始化的資料庫啟動時,可能會爭相建立結構,令其中一個 pod 無法啟動。先以一個副本開始,讓結構只建立一次,然後再擴展。 - 如要採用更嚴格的設定,請在應用程式外初始化結構(例如使用一次性的 Kubernetes Job),並在每個 pod 的 `PostgresStore` 上設定 `disableInit: true`。 ## 相關內容 - [PubSub](https://mastra.zisheng.pro/zh-HK/docs/server/pubsub) - [持久 Agent](https://mastra.zisheng.pro/zh-HK/docs/long-running-agents/durable-agents) - [Worker](https://mastra.zisheng.pro/zh-HK/docs/deployment/workers):在 Kubernetes 上將背景處理拆分至獨立容器 - [Worker 部署指南](https://mastra.zisheng.pro/zh-HK/guides/deployment/mastra-workers):用於編排、排程器及背景工作 Worker 的完整 Kubernetes manifest - [Mastra 伺服器](https://mastra.zisheng.pro/zh-HK/docs/server/mastra-server) - [部署概覽](https://mastra.zisheng.pro/zh-HK/docs/deployment/overview)