Mastra を Kubernetes にデプロイする
Mastra アプリケーションを Kubernetes 上の複数 Pod で実行し、Load Balancer の背後で水平スケーリングします。各 Pod は独立したプロセスであるため、Pub/Sub Backend とデータベースを共有する必要があります。共有しない場合、1 つの Pod で開始した作業を他の Pod から確認できません。
このガイドでは、Mastra サーバーのデプロイについて説明します。Server Adapter または Web フレームワークを使用している場合は、そのフレームワークの通常の方法でデプロイしてください。
複数 Pod のサポートは、現在 Beta の Durable Agent に依存します。API は Minor Version で変更される可能性があります。本番環境で使用する前に、既知の制限を確認してください。
始める前に始める前にへの直接リンク
次のものが必要です。
- Mastra アプリケーション
- Kubernetes Cluster と
kubectl - Cluster から Pull できる Container Registry
- すべての Pod からアクセスできる共有 Redis インスタンス
- すべての Pod からアクセスできる共有 PostgreSQL データベース
複数 Pod に共有インフラストラクチャが必要な理由複数 Pod に共有インフラストラクチャが必要な理由への直接リンク
単一の Pod は Run の状態を自身のメモリに保持します。Pod が 1 つであれば、すべてのリクエストが同じプロセスに届くため問題ありません。複数 Pod では、ブラウザーが Pod A からストリーミングしている間に、ユーザーの次のリクエストが Pod B にルーティングされる可能性があります。Pod B には Pod A の Run に関する記録がありません。
Redis と Postgres がこの問題を解決します。
- Pub/Sub は Pod 間でイベントを転送します。1 つの Pod でイベントを Publish すると、他の Pod が受信します。Mastra は
RedisStreamsPubSubを使用します。これは、同時に 1 つの Pod だけが会話を所有するようにする Thread ごとの Lease も提供します。PubSub を参照してください。 - ストレージ は Run の状態を永続化します。Durable Agent は各 Run を Workflow Snapshot として保存するため、再起動後や別の場所にルーティングされた場合でも、どの Pod からでもデータベースから Run を再開できます。
共有インフラストラクチャを設定する共有インフラストラクチャを設定するへの直接リンク
Mastra インスタンスを Redis と Postgres に接続します。すべての Pod で同じイメージを実行できるように、接続情報を環境変数から読み取ります。
Backend をインストールします。
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/redis-streams @mastra/pg @mastra/redis ioredis
pnpm add @mastra/redis-streams @mastra/pg @mastra/redis ioredis
yarn add @mastra/redis-streams @mastra/pg @mastra/redis ioredis
bun add @mastra/redis-streams @mastra/pg @mastra/redis ioredis
Mastra インスタンスに Pub/Sub、ストレージ、共有 Cache を設定します。
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 間で動作します。再接続する Client は、この Cache から受信できなかったイベントを再生するため、Cache を共有する必要があります。デフォルトの In-memory Cache は、1 つのプロセス内でのみ再生に対応します。
Durable Agent を使用するDurable Agent を使用するへの直接リンク
通常の Agent はストリームと承認状態を 1 つの Pod のメモリに保持するため、リクエストが別の Pod に届くと維持できません。Durable Agent は Agent Loop を Workflow 内で実行して状態を永続化するため、どの Pod からでも同じ Run を確認または再開できます。
Agent を createDurableAgent() でラップします。
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 インスタンスに Durable Agent を登録します。Run の状態が Postgres に保存され、イベントが Redis を通過するため、すべての Pod から Run にアクセスできるようになります。
デプロイするデプロイするへの直接リンク
Mastra サーバーをビルドしてコンテナ化し、イメージを Registry にプッシュします。ビルドについては Mastra サーバーガイドに従い、サーバーが
process.env.PORTを読み取り、0.0.0.0で Listen することを確認してください。共有接続文字列を Secret として保存します。
kubectl create secret generic mastra-secrets \--from-literal=REDIS_URL='redis://redis:6379' \--from-literal=DATABASE_URL='postgresql://user:pass@postgres:5432/mastra'共有 Secret を読み取ってイメージを実行する Deployment を適用します。最初の Pod が単独でデータベース Schema を作成できるように、まず 1 つの Replica で開始し、次の Step でスケールアップします。
deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: mastraspec:replicas: 1selector:matchLabels:app: mastratemplate:metadata:labels:app: mastraspec:containers:- name: mastraimage: your-registry/mastra:latestports:- containerPort: 8080env:- name: PORTvalue: '8080'envFrom:- secretRef:name: mastra-secretsreadinessProbe:tcpSocket:port: 8080livenessProbe:tcpSocket:port: 8080resources:requests:cpu: 500mmemory: 512Mi後述の HorizontalPodAutoscaler では、
resources.requests.cpuの値が必要です。Kubernetes は使用量を要求量で割って CPU 使用率を計算するため、CPU Request がないと Autoscaler は目標値を計算できず、スケーリングしません。kubectl apply -f deployment.yaml最初の Pod の準備ができたら、スケールアップします。
kubectl wait --for=condition=available deployment/mastrakubectl scale deployment/mastra --replicas=3注記すべての Replica が同じイメージを実行し、同じ Redis と Postgres に接続します。Run が Pod をまたげるのは、Pod 数ではなくこの共有インフラストラクチャによるものです。
Deployment を Service として公開します。
service.yamlapiVersion: v1kind: Servicemetadata:name: mastraspec:selector:app: mastraports:- port: 80targetPort: 8080kubectl apply -f service.yamlHorizontalPodAutoscaler で Replica を自動的にスケーリングします。
hpa.yamlapiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata:name: mastraspec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: mastraminReplicas: 3maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 70kubectl apply -f hpa.yaml注記CPU ベースの自動スケーリングには、Cluster で metrics-server を実行する必要があります。GKE、EKS、AKS などのマネージド Cluster には含まれています。kind や minikube などのローカル Cluster には含まれないため、先に有効にしてください(
minikube addons enable metrics-serverなど)。Pod が実行されていることを確認します。
kubectl get pods -l app=mastra1 つのターミナルで Service を Port Forward します。このコマンドはフォアグラウンドで実行され続けます。
kubectl port-forward service/mastra 8080:802 つ目のターミナルから API を呼び出します。
curl http://localhost:8080/api/agentsAgent の一覧が JSON で返れば、デプロイから配信されています。
警告エンドポイントを公開する前に、認証を設定してください。
ストリーミングと再接続ストリーミングと再接続への直接リンク
Durable Agent は共有 Pub/Sub を介して、Run ごとの Topic にストリームチャンクを Publish します。切断した Client は Run ID とともに observe() を呼び出して再接続し、共有 Cache から受信できなかったチャンクを再生します。
const { output, cleanup } = await durableAssistant.observe(runId)
for await (const chunk of output.fullStream) {
// Chunks from the run, including any missed while disconnected
}
cleanup()
Run の状態が Postgres、イベントが Redis にあるため、再接続リクエストは Run を開始した Pod だけでなく、どの Pod でも処理できます。再開可能なストリームを参照してください。
複数の Client が同じ Run を同時に確認できます。各 observe() 呼び出しは完全なストリームを受信するため、1 人のユーザーが 2 台のデバイスから確認する場合も、2 人が同じ Run を追跡する場合も同期を維持できます。
Pod をまたぐ Tool 承認Pod をまたぐ Tool 承認への直接リンク
Durable Agent は人間が承認するまで Tool 呼び出しを一時停止します。中断された Run は Postgres に保存されるため、Run を開始した Pod だけでなく、どの Pod でも承認を受け取れます。
承認が必要な Run を開始します。
const { runId } = await durableAssistant.stream('Delete the archived records', {
requireToolApproval: true,
memory: { thread: 'thread-1', resource: 'user-1' },
})
Run は Tool の実行前に中断されます。後から任意の Pod で承認します。
await durableAssistant.resume(runId, { approved: true })
承認を処理する Pod が中断された Run を Postgres から読み込みます。その後、承認された Tool を実行して共有 Pub/Sub 経由で結果を Publish するため、Run を確認している Client が続きを受信します。Tool 承認を参照してください。
既知の制限既知の制限への直接リンク
- デフォルトの In-process 設定では、Run の状態を 1 つの Pod のメモリに保持し、Pod 間で共有しません。ストリーミング、承認、再接続を Pod 間で動作させるには、共有 Redis と Postgres を持つ Durable Agent を使用してください。
- Pod をまたぐストリーミング、承認、再接続には Durable Agent が必要です。通常の Agent は Run の状態をメモリに保持し、別の Pod では再開しません。
- 初期化されていないデータベースに対して複数の Pod を同時に起動すると、Schema 作成が競合して Pod の起動に失敗することがあります。まず 1 つの Replica で Schema を一度だけ作成し、その後スケールアップしてください。
- より厳密な構成では、アプリ外部で Schema を初期化し(1 回限りの Kubernetes Job など)、すべての Pod の
PostgresStoreにdisableInit: trueを設定します。
関連項目関連項目への直接リンク
- PubSub
- Durable Agent
- Worker:Kubernetes 上でバックグラウンド処理を別のコンテナに分離する
- Worker デプロイガイド:Orchestration、Scheduler、バックグラウンドタスク Worker 用の完全な Kubernetes Manifest
- Mastra サーバー
- Deployment の概要