Mastra 작업자 배포
달리다Mastra workers별도의 프로세스로 분리되어 API와 독립적으로 오케스트레이션, 예약 및 백그라운드 작업을 확장할 수 있습니다. 이 가이드에서는 Docker Compose 또는 Kubernetes를 사용하여 완전히 분할된 배포를 안내합니다.
이 가이드에서는 작업자를 자체 컨테이너로 분할하는 방법을 다룹니다. API와 함께 프로세스 내에서 실행할 작업자만 필요한 경우 다음을 참조하세요.Workers. No extra setup is required.
시작하기 전에시작하기 전에에 대한 직접 링크
다음이 필요합니다.
- 에이Mastra application
- 도커그리고Docker Compose, or a Kubernetes cluster with
kubectl - 분산형 PubSub 백엔드:Redis for
RedisStreamsPubSub, or a Google Cloud project forGoogleCloudPubSub - 모든 컨테이너에서 연결할 수 있는 공유 데이터베이스입니다. 보다supported storage backends for the full list.
기본 인Memory PubSub는 프로세스 전체에 이벤트를 전달할 수 없습니다. 작업자를 별도의 컨테이너로 분할하기 전에 분산형 PubSub 백엔드를 구성해야 합니다.
공유 인프라 구성공유 인프라 구성에 대한 직접 링크
포인트Mastra 인스턴스가 분산 PubSub 백엔드와 공유 데이터베이스를 가리키도록 설정하세요. 모든 컨테이너에서 동일한 이미지가 실행되도록 환경 변수를 사용하세요.
- Redis Streams + PostgreSQL
- Google Cloud Pub/Sub + LibSQL
import { Mastra } from '@mastra/core/mastra'
import { RedisStreamsPubSub } from '@mastra/redis-streams'
import { PostgresStore } from '@mastra/pg'
export const mastra = new Mastra({
storage: new PostgresStore({
connectionString: process.env.DATABASE_URL!,
}),
pubsub: new RedisStreamsPubSub({
url: process.env.REDIS_URL!,
}),
})
import { Mastra } from '@mastra/core/mastra'
import { GoogleCloudPubSub } from '@mastra/google-cloud-pubsub'
import { LibSQLStore } from '@mastra/libsql'
export const mastra = new Mastra({
storage: new LibSQLStore({
url: process.env.DATABASE_URL!,
}),
pubsub: new GoogleCloudPubSub({
projectId: process.env.GCP_PROJECT_ID!,
}),
})
어느supported storage backend 를 사용할 수 있습니다. 스토리지 어댑터는 원하는 데이터베이스에 맞는 것으로 교체하세요.
배포배포에 대한 직접 링크
Mastra 애플리케이션을 구축하세요. 출력은 모든 컨테이너에서 실행됩니다.
mastra build이는 독립형을 생성합니다.
.mastra/output/directory. See Deploy a Mastra server for details on the build output.사전 빌드된 출력을 복사하고 프로덕션 종속성을 설치하는 Dockerfile을 만듭니다.
app/DockerfileFROM node:22-alpineWORKDIR /appCOPY .mastra/output/package.json .mastra/output/.npmrc* ./RUN npm install --omit=devCOPY .mastra/output/ .EXPOSE 4111CMD ["node", "index.mjs"]완전히 분할된 토폴로지를 정의합니다. 설정에서는 데이터베이스, PubSub 백엔드, API 서버, 작업자 3개 등 6개의 서비스를 실행합니다. 각 작업자는 서로 다른 이미지로 동일한 이미지를 실행합니다.
MASTRA_WORKERSvalue to control which worker starts.API 세트
MASTRA_WORKERS: "false"로 설정하여 모든 이벤트 처리를 비활성화합니다. 오케스트레이션 워커는MASTRA_STEP_EXECUTION_URL를 설정하여 단계 실행 요청이 API의 내부 URL을 가리키도록 합니다. step execution URL for details.모든 서비스는
MASTRA_WORKER_AUTH_TOKEN. Worker는 API 요청에 이 토큰을 포함하므로 API는 호출자가 신뢰할 수 있는 내부 서비스인지 확인할 수 있습니다. worker authentication for details.- Docker Compose
- Kubernetes
docker-compose.ymlservices:postgres:image: postgres:16-alpineenvironment:POSTGRES_USER: mastraPOSTGRES_PASSWORD: ${POSTGRES_PASSWORD}POSTGRES_DB: mastraports:- '5432:5432'volumes:- pgdata:/var/lib/postgresql/datahealthcheck:test: ['CMD-SHELL', 'pg_isready -U mastra']interval: 5stimeout: 3sretries: 5redis:image: redis:7-alpineports:- '6379:6379'healthcheck:test: ['CMD', 'redis-cli', 'ping']interval: 5stimeout: 3sretries: 5api:build: ./appports:- '4111:4111'environment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: 'false'MASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:postgres:condition: service_healthyredis:condition: service_healthyhealthcheck:test: ['CMD', 'wget', '-qO-', 'http://localhost:4111/api/agents']interval: 5stimeout: 3sretries: 5orchestration-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: orchestrationMASTRA_STEP_EXECUTION_URL: http://api:4111/apiMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthyscheduler-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: schedulerMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthybackground-task-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: backgroundTasksMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthyvolumes:pgdata:만들기
.envfile next to yourdocker-compose.yml:.envPOSTGRES_PASSWORD=your-secure-passwordMASTRA_WORKER_AUTH_TOKEN=your-shared-secret-token:::참고 애플리케이션에 필요한 다른 환경 변수(예:model provider API key). :::
연결 문자열을 사용하여 네임스페이스와 비밀을 만듭니다.
k8s/namespace.yamlapiVersion: v1kind: Namespacemetadata:name: mastra-workerskubectl apply -f k8s/namespace.yamlkubectl create secret generic mastra-secrets -n mastra-workers \--from-literal=POSTGRES_PASSWORD='your-password' \--from-literal=DATABASE_URL='postgresql://mastra:your-password@postgres:5432/mastra' \--from-literal=REDIS_URL='redis://redis:6379' \--from-literal=MASTRA_WORKER_AUTH_TOKEN='your-shared-token':::참고 애플리케이션에 필요한 다른 환경 변수를 추가합니다(예:model provider API key) to the Secret or as additional
--from-literalentries. :::클러스터가 가져올 수 있는 레지스트리에 Docker 이미지를 빌드하고 푸시합니다.
docker build -t your-registry/mastra-workers:latest ./appdocker push your-registry/mastra-workers:latest데이터베이스, PubSub 백엔드, API, 작업자 3개에 배포 및 서비스를 적용합니다. 아래 예에서는 클러스터 내 Postgres 및 Redis를 사용합니다. 프로덕션에서는 관리형 서비스(예: Amazon RDS, Cloud SQL, ElastiCache, Memorystore)를 사용합니다.
k8s/postgres.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: postgresnamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: postgrestemplate:metadata:labels:app: postgresspec:containers:- name: postgresimage: postgres:16-alpineports:- containerPort: 5432env:- name: POSTGRES_USERvalue: mastra- name: POSTGRES_PASSWORDvalueFrom:secretKeyRef:name: mastra-secretskey: POSTGRES_PASSWORD- name: POSTGRES_DBvalue: mastravolumeMounts:- name: pgdatamountPath: /var/lib/postgresql/datavolumes:- name: pgdataemptyDir: {}---apiVersion: v1kind: Servicemetadata:name: postgresnamespace: mastra-workersspec:selector:app: postgresports:- port: 5432targetPort: 5432주의위의 Postgres 예제에서는 다음을 사용합니다.
emptyDir를 스토리지로 사용하므로 pod가 재시작되면 데이터가 손실됩니다. 프로덕션에서는 이를PersistentVolumeClaimor use a managed database service.k8s/redis.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: redisnamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- name: redisimage: redis:7-alpineargs: ['--appendonly', 'yes']ports:- containerPort: 6379---apiVersion: v1kind: Servicemetadata:name: redisnamespace: mastra-workersspec:selector:app: redisports:- port: 6379targetPort: 6379k8s/api.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: apinamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: apitemplate:metadata:labels:app: apispec:containers:- name: apiimage: your-registry/mastra-workers:latestports:- containerPort: 4111env:- name: MASTRA_WORKERSvalue: 'false'envFrom:- secretRef:name: mastra-secretsreadinessProbe:httpGet:path: /api/agentsport: 4111initialDelaySeconds: 10periodSeconds: 5livenessProbe:httpGet:path: /api/agentsport: 4111initialDelaySeconds: 15periodSeconds: 10resources:requests:cpu: 500mmemory: 512Mi---apiVersion: v1kind: Servicemetadata:name: apinamespace: mastra-workersspec:selector:app: apiports:- port: 4111targetPort: 4111k8s/orchestration-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: orchestration-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: orchestration-workertemplate:metadata:labels:app: orchestration-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: orchestration- name: MASTRA_STEP_EXECUTION_URLvalue: http://api:4111/apienvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mik8s/scheduler-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: scheduler-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: scheduler-workertemplate:metadata:labels:app: scheduler-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: schedulerenvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mik8s/background-task-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: background-task-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: background-task-workertemplate:metadata:labels:app: background-task-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: backgroundTasksenvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mi모든 매니페스트를 적용하고 API가 준비될 때까지 기다립니다.
kubectl apply -f k8s/kubectl wait -n mastra-workers --for=condition=ready pod -l app=api --timeout=90skubectl wait -n mastra-workers --for=condition=ready pod -l app=orchestration-worker --timeout=60skubectl wait -n mastra-workers --for=condition=ready pod -l app=scheduler-worker --timeout=60skubectl wait -n mastra-workers --for=condition=ready pod -l app=background-task-worker --timeout=60s스택이 실행 중이고 API가 응답하는지 확인합니다.
- Docker Compose
- Kubernetes
docker compose up -ddocker compose pscurl http://localhost:4111/api/agentskubectl get pods -n mastra-workerskubectl port-forward -n mastra-workers svc/api 4111:4111별도의 터미널에서:
curl http://localhost:4111/api/agentsAgent의 JSON 목록은 API와 작업자가 실행 중인지 확인합니다.
단계 실행 URL단계 실행 URL에 대한 직접 링크
완전히 분할된 배포에서 오케스트레이션 작업자는 API와 별도의 컨테이너에서 실행됩니다. Workflow 이벤트를 처리할 때 HTTP를 통해 단계 실행을 API에 위임합니다.
세트MASTRA_STEP_EXECUTION_URL to the API's internal URL, including the /api prefix:
MASTRA_STEP_EXECUTION_URL=http://api:4111/api
오케스트레이션 작업자가 다음을 보냅니다.POST request to ${MASTRA_STEP_EXECUTION_URL}/workflows/:workflowId/runs/:runId/steps/execute 를 각 단계마다 호출합니다. API는 Workflow를 확인하고 해당 단계를 로컬에서 실행합니다.
이 변수가 없으면 오케스트레이션 작업자는 진행 중인 단계를 실행하려고 시도합니다. 이는 작업자가 API와 함께 실행될 때 작동하지만 작업자가 전체 Mastra 런타임에 액세스할 수 없는 분할 배포에서는 실패합니다.
스케일링스케일링에 대한 직접 링크
오케스트레이션 및 백그라운드 작업 작업자는 수평으로 확장해도 안전합니다. PubSub 소비자 그룹은 인스턴스 전체에 이벤트를 배포하므로 각 이벤트는 한 번 처리됩니다.
- Docker Compose
- Kubernetes
docker compose up -d --scale orchestration-worker=3
docker compose up -d --scale background-task-worker=2
kubectl scale deployment/orchestration-worker -n mastra-workers --replicas=3
kubectl scale deployment/background-task-worker -n mastra-workers --replicas=2
자동 크기 조정을 위해 HorizonPodAutoscaler를 추가합니다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: orchestration-worker
namespace: mastra-workers
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: orchestration-worker
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
:::참고 CPU 기반 자동 확장에는 다음이 필요합니다.metrics-server 가 클러스터에서 실행되고 있어야 합니다. GKE, EKS, AKS 같은 관리형 클러스터에는 기본적으로 포함되어 있습니다. :::
API는 로드 밸런서 뒤에서 수평으로 확장할 수도 있습니다.
스케줄러 작업자를 확장하지 마세요.정확히 하나의 인스턴스를 실행합니다. 동일한 스토리지를 폴링하는 여러 스케줄러는 동일한 일정에 대해 중복 이벤트를 발생시킵니다.
충돌 복구충돌 복구에 대한 직접 링크
분산 PubSub 백엔드가 확인되지 않은 이벤트를 지속하므로 작업자가 충돌로부터 복구됩니다.
- 오케스트레이션 작업자: 대기 중인 이벤트는 PubSub 백엔드에 유지됩니다. 작업자가 다시 시작되면 중단된 부분부터 다시 시작됩니다.
- 스케줄러 작업자: 이벤트가 영구적으로 누락되지 않습니다. 스케줄러는 중단된 시점이 아닌 재시작 시 현재 시간부터 다음 실행 시간을 계산합니다.
- 단계 실행 중 API: 오케스트레이션 작업자의 HTTP 요청이 실패합니다. 이벤트가 취소되고 다음 시도에서 다시 전달됩니다.
단계가 이미 실행 중인 동안(예: 절전 모드 중) API가 충돌하면 해당 단계의 작업이 손실됩니다. Workflow 실행이 계속 중단될 수 있습니다.running 상태로 남습니다. Mastra는 아직 이 시나리오에 대한 시간 제한 기반 자동 복구를 지원하지 않습니다.
관련된관련된에 대한 직접 링크
- 노동자: 워커란 무엇이며 언제 사용해야 하는가
- 작업자 인증: 작업자와 API 간 통신 보안
- 근로자 참조: 모든 작업자 유형에 대한 구성 세부정보
- CLI 참조:
mastra worker buildandmastra worker start - PubSub: 이벤트 전달 백엔드
- Mastra 서버 배포: 빌드 출력 및 서버 구성
- Kubernetes에 Mastra 배포: 내구성 있는 Agent를 사용한 다중 포드 배포