Files
taiji-AI-PAD/k8s/prod/mcp-server.yaml
T
chenchenandClaude Opus 4.8 b754af8ba1 fix(mcp-server): device-code 一次性作废失效修复(consume 集群 Redis 删除未生效)
初版 consume_device_code 用裸 redis_client.delete() 且吞异常,在集群 Azure
Redis 上删除未生效,导致一个 device_code 换发 token 后仍能在每次 >interval
的轮询继续换发新 token —— 违反 RFC 8628 一次性语义与验收「换一次后再用→拒绝」。

初测二次轮询都在 slow_down 窗口内(<5s)被限流响应遮住,未暴露;>5s 公网
真实轮询复测才暴露。

修复:consume 改用已验证可靠的 _set_keepttl 置 status=consumed(token 端点
签发前硬检查 consumed → expired_token),并 best-effort 删除 device_code +
device_user_code 两个 key。即使集群删除失败,状态位硬拦截。

复测(公网 APIM 真实路径,间隔 >5s):首 poll 签发 → 二/三次 poll 均
expired_token,不再重复签发。

镜像 device-code-fix2-20260722-arm64 @sha256:716c2e2d 已部署生产 3/3 Running。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:24:27 +08:00

309 lines
7.8 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MCP Server Deployment for Azure AKS
# 生产环境配置 - PostgreSQL 使用 postgres 数据库,Redis 使用 Azure Cache for Redis
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server
namespace: taiji-ai
labels:
app: mcp-server
version: v1
environment: production
spec:
replicas: 2
selector:
matchLabels:
app: mcp-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: mcp-server
version: v1
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8000"
prometheus.io/path: "/metrics"
spec:
containers:
- name: mcp-server
image: taiji.azurecr.io/mcp-server:device-code-fix2-20260722-arm64
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
protocol: TCP
env:
# 应用环境配置
- name: ENVIRONMENT
value: "production"
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: taiji-config
key: APP_ENV
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: taiji-config
key: LOG_LEVEL
# 数据库配置 (Azure Database for PostgreSQL - 生产库 postgres)
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: taiji-secrets
key: database-url
- name: ASYNC_DATABASE_URL
valueFrom:
secretKeyRef:
name: taiji-secrets
key: async-database-url
# Redis配置 (Azure Cache for Redis with SSL)
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: taiji-secrets
key: redis-url
# NATS配置 (K8s内部服务)
- name: NATS_URL
valueFrom:
configMapKeyRef:
name: taiji-config
key: NATS_URL
# LiteLLM网关配置
- name: LITELLM_URL
valueFrom:
configMapKeyRef:
name: taiji-config
key: LITELLM_URL
- name: LLM_BASE_URL
valueFrom:
configMapKeyRef:
name: taiji-config
key: LITELLM_URL
- name: LITELLM_MASTER_KEY
valueFrom:
secretKeyRef:
name: taiji-secrets
key: litellm-master-key
- name: LITELLM_API_KEY
valueFrom:
secretKeyRef:
name: taiji-secrets
key: litellm-master-key
# Agent Manager 配置 (AKS内部服务)
- name: AGENT_MANAGER_URL
valueFrom:
configMapKeyRef:
name: taiji-config
key: AGENT_MANAGER_URL
- name: AGENT_K8S_NAMESPACE
valueFrom:
configMapKeyRef:
name: taiji-config
key: AGENT_K8S_NAMESPACE
# 服务令牌:调 agent-manager 鉴权(契约 §2.1,= agent-manager 的 AGNET_RUNTIME_SERVICE_TOKEN)
- name: AGENT_MANAGER_SERVICE_TOKEN
valueFrom:
secretKeyRef:
name: taiji-secrets
key: agent-manager-service-token
# JWT配置
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: taiji-secrets
key: jwt-secret
- name: JWT_SECRET_KEY
valueFrom:
secretKeyRef:
name: taiji-secrets
key: jwt-secret
- name: JWT_ALGORITHM
valueFrom:
configMapKeyRef:
name: taiji-config
key: JWT_ALGORITHM
- name: JWT_EXPIRE_MINUTES
valueFrom:
configMapKeyRef:
name: taiji-config
key: JWT_EXPIRE_MINUTES
# SMTP邮箱配置
- name: SMTP_SERVER
valueFrom:
configMapKeyRef:
name: taiji-config
key: SMTP_SERVER
- name: SMTP_PORT
valueFrom:
configMapKeyRef:
name: taiji-config
key: SMTP_PORT
- name: SMTP_EMAIL
valueFrom:
configMapKeyRef:
name: taiji-config
key: SMTP_EMAIL
- name: SMTP_USE_SSL
valueFrom:
configMapKeyRef:
name: taiji-config
key: SMTP_USE_SSL
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: taiji-secrets
key: smtp-password
# Heicode magic-link 邮箱登录:本服务对外公网基址(§11 终态=APIM)
- name: MAGIC_LINK_PUBLIC_BASE_URL
valueFrom:
configMapKeyRef:
name: taiji-config
key: MAGIC_LINK_PUBLIC_BASE_URL
# 发信总闸(默认 false=mock);D-5 签字后改 configmap 的 MAGIC_LINK_EMAIL_ENABLED=true
- name: MAGIC_LINK_EMAIL_ENABLED
valueFrom:
configMapKeyRef:
name: taiji-config
key: MAGIC_LINK_EMAIL_ENABLED
# PayPal 支付配置 (生产环境)
- name: PAYPAL_CLIENT_ID
valueFrom:
secretKeyRef:
name: taiji-secrets
key: paypal-client-id
- name: PAYPAL_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: taiji-secrets
key: paypal-client-secret
- name: PAYPAL_ENVIRONMENT
value: "production"
- name: PAYPAL_WEBHOOK_ID
valueFrom:
secretKeyRef:
name: taiji-secrets
key: paypal-webhook-id
# 健康检查
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 5
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 5
# 资源限制
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "1Gi"
cpu: "1000m"
# 挂载卷
volumeMounts:
- name: logs
mountPath: /app/logs
# 卷定义
volumes:
- name: logs
emptyDir: {}
# 重启策略
restartPolicy: Always
# ACR 镜像拉取凭据
imagePullSecrets:
- name: acr-secret
# 服务账户(如果需要访问K8s API)
# serviceAccountName: mcp-server-sa
---
# MCP Server Service
apiVersion: v1
kind: Service
metadata:
name: mcp-server
namespace: taiji-ai
labels:
app: mcp-server
spec:
type: ClusterIP
selector:
app: mcp-server
ports:
- name: http
port: 8000
targetPort: 8000
protocol: TCP
---
# HorizontalPodAutoscaler - 自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: mcp-server-hpa
namespace: taiji-ai
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mcp-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
---
# PodDisruptionBudget - 确保高可用
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: mcp-server-pdb
namespace: taiji-ai
spec:
minAvailable: 1
selector:
matchLabels:
app: mcp-server