初始化提交

This commit is contained in:
chengcheng
2026-07-09 19:29:46 +08:00
commit 821ffe9e70
25 changed files with 2713 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-memory
labels:
app.kubernetes.io/name: agent-memory
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: agent-memory
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: agent-memory
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 45
containers:
- name: agent-memory
image: registry.cn-shanghai.aliyuncs.com/easyaigc/agent-memory:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 3004
- name: tcp
containerPort: 4004
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: MEMORY_AI_BASE_URL
value: http://easyai-server:3001
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: agent-memory
labels:
app.kubernetes.io/name: agent-memory
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: agent-memory
ports:
- name: http
port: 3004
targetPort: http
- name: tcp
port: 4004
targetPort: tcp
+92
View File
@@ -0,0 +1,92 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-asg
labels:
app.kubernetes.io/name: easyai-asg
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: easyai-asg
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: easyai-asg
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 45
containers:
- name: easyai-asg
image: registry.cn-shanghai.aliyuncs.com/easyaigc/agent-governance:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 3003
- name: tcp
containerPort: 4003
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: ASG_TCP_HOST
value: 0.0.0.0
- name: ASG_TCP_PORT
value: "4003"
- name: ASG_MAIN_BACKEND_URL
value: http://easyai-server:3001
volumeMounts:
- name: pm2
mountPath: /app/.pm2
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
volumes:
- name: pm2
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: easyai-asg
labels:
app.kubernetes.io/name: easyai-asg
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: easyai-asg
ports:
- name: http
port: 3003
targetPort: http
- name: tcp
port: 4003
targetPort: tcp
+133
View File
@@ -0,0 +1,133 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-server
labels:
app.kubernetes.io/name: easyai-server
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: easyai-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: easyai-server
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 60
containers:
- name: easyai-server
image: registry.cn-shanghai.aliyuncs.com/comfy-ai/comfy-server:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 3001
- name: tcp-inbound
containerPort: 4001
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: CONFIG_INSTANCE_ID
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: CONFIG_VIDEO_EDIT_API_URL
value: http://video-edit:8000
- name: SANDBOX_SERVICE_BASE_URL
value: http://sandbox:8000
- name: ASG_TCP_HOST
value: easyai-asg
- name: ASG_TCP_PORT
value: "4003"
- name: MEMORY_TCP_HOST
value: agent-memory
- name: MEMORY_TCP_PORT
value: "4004"
- name: GATEWAY_INBOUND_ENABLED
value: "true"
- name: GATEWAY_INBOUND_TCP_LISTEN_HOST
value: 0.0.0.0
- name: GATEWAY_INBOUND_TCP_PORT
value: "4001"
- name: WS_GATEWAY_TCP_HOST
value: ws-gateway
- name: WS_GATEWAY_TCP_PORT
value: "4002"
volumeMounts:
- name: shared-files
mountPath: /app/upload
subPath: upload
- name: shared-files
mountPath: /app/backups
subPath: backups
- name: shared-files
mountPath: /app/restores
subPath: restores
- name: app-tmp
mountPath: /app/tmp
- name: tmp
mountPath: /tmp
startupProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 30
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /health
port: http
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: "2"
memory: 2500Mi
volumes:
- name: shared-files
emptyDir: {}
- name: app-tmp
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: easyai-server
labels:
app.kubernetes.io/name: easyai-server
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: easyai-server
ports:
- name: http
port: 3001
targetPort: http
- name: tcp-inbound
port: 4001
targetPort: tcp-inbound
+77
View File
@@ -0,0 +1,77 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-web
labels:
app.kubernetes.io/name: easyai-web
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: easyai-web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: easyai-web
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 30
containers:
- name: easyai-web
image: registry.cn-shanghai.aliyuncs.com/comfy-ai/one-ai:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 3010
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: NUXT_PUBLIC_BASE_SSRURL
value: http://easyai-server:3001
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: "1"
memory: 1500Mi
---
apiVersion: v1
kind: Service
metadata:
name: easyai-web
labels:
app.kubernetes.io/name: easyai-web
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: easyai-web
ports:
- name: http
port: 3010
targetPort: http
+15
View File
@@ -0,0 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service-account.yaml
- easyai-web.yaml
- easyai-server.yaml
- ws-gateway.yaml
- video-edit.yaml
- sandbox.yaml
- easyai-asg.yaml
- agent-memory.yaml
commonLabels:
app.kubernetes.io/part-of: easyai
+139
View File
@@ -0,0 +1,139 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: sandbox
labels:
app.kubernetes.io/name: sandbox
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: sandbox
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: sandbox
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 30
containers:
- name: sandbox
image: registry.cn-shanghai.aliyuncs.com/easyaigc/sandbox:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8000
- name: jupyter
containerPort: 8888
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: NODE_PATH
value: /app/node_modules:/app/node_modules_extra/node_modules
- name: NODE_MODULES_EXTRA
value: /app/node_modules_extra
- name: NODE_MODULES_EXTRA_PATH
value: /app/node_modules_extra/node_modules
- name: SANDBOX_TMPDIR
value: /app/tmp
- name: PIP_CACHE_DIR
value: /app/tmp/.pip
- name: TMPDIR
value: /app/tmp
- name: NPM_CONFIG_CACHE
value: /app/tmp/.npm
- name: PYTHON_EXTRA_DIR
value: /root/.local/lib/python3.12/site-packages
- name: PYTHON_EXTRA_PATH
value: /root/.local/lib/python3.12/site-packages
- name: JUPYTER_DATA_DIR
value: /app/tmp/jupyter_data
- name: JUPYTER_RUNTIME_DIR
value: /app/tmp/jupyter_runtime
- name: JUPYTER_CONFIG_DIR
value: /app/tmp/jupyter_config
- name: JUPYTER_TOKEN
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: SANDBOX_JUPYTER_TOKEN
volumeMounts:
- name: data
mountPath: /app/data
- name: local-packages
mountPath: /app/local_packages
- name: python-packages
mountPath: /root/.local
- name: node-modules-extra
mountPath: /app/node_modules_extra
- name: app-tmp
mountPath: /app/tmp
- name: tmp
mountPath: /tmp
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 45
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
securityContext:
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
volumes:
- name: data
emptyDir: {}
- name: local-packages
emptyDir: {}
- name: python-packages
emptyDir: {}
- name: node-modules-extra
emptyDir: {}
- name: app-tmp
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: sandbox
labels:
app.kubernetes.io/name: sandbox
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: sandbox
ports:
- name: http
port: 8000
targetPort: http
- name: jupyter
port: 8888
targetPort: jupyter
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: easyai-workload
labels:
app.kubernetes.io/name: easyai-workload
+97
View File
@@ -0,0 +1,97 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: video-edit
labels:
app.kubernetes.io/name: video-edit
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: video-edit
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: video-edit
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 60
containers:
- name: video-edit
image: registry.cn-shanghai.aliyuncs.com/easyaigc/videoedit:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8000
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: PYTHONUNBUFFERED
value: "1"
- name: OMP_NUM_THREADS
value: "4"
- name: OPENBLAS_NUM_THREADS
value: "4"
volumeMounts:
- name: temp
mountPath: /app/temp
- name: dshm
mountPath: /dev/shm
readinessProbe:
httpGet:
path: /docs
port: http
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /docs
port: http
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 4Gi
securityContext:
capabilities:
add:
- SYS_ADMIN
volumes:
- name: temp
emptyDir: {}
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 3Gi
---
apiVersion: v1
kind: Service
metadata:
name: video-edit
labels:
app.kubernetes.io/name: video-edit
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: video-edit
ports:
- name: http
port: 8000
targetPort: http
+107
View File
@@ -0,0 +1,107 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ws-gateway
labels:
app.kubernetes.io/name: ws-gateway
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/name: ws-gateway
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: ws-gateway
spec:
serviceAccountName: easyai-workload
terminationGracePeriodSeconds: 45
containers:
- name: ws-gateway
image: registry.cn-shanghai.aliyuncs.com/easyaigc/wsgateway:latest
imagePullPolicy: Always
ports:
- name: websocket
containerPort: 3002
- name: tcp-events
containerPort: 4002
envFrom:
- configMapRef:
name: easyai-app-config
- secretRef:
name: easyai-app-secret
env:
- name: GATEWAY_CLUSTER_NODE_ID
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: CONFIG_TCP_HOST
value: 0.0.0.0
- name: CONFIG_TCP_PORT
value: "4002"
- name: GATEWAY_INBOUND_ENABLED
value: "true"
- name: GATEWAY_INBOUND_TCP_HOST
value: easyai-server
- name: GATEWAY_INBOUND_TCP_PORT
value: "4001"
volumeMounts:
- name: pm2
mountPath: /app/.pm2
- name: tmp
mountPath: /tmp
readinessProbe:
tcpSocket:
port: websocket
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
tcpSocket:
port: websocket
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
volumes:
- name: pm2
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: ws-gateway
labels:
app.kubernetes.io/name: ws-gateway
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: ws-gateway
ports:
- name: websocket
port: 3002
targetPort: websocket
- name: tcp-events
port: 4002
targetPort: tcp-events
+426
View File
@@ -0,0 +1,426 @@
# EasyAI 本地 kind 部署指南
本目录用于在本机通过 kind 部署 EasyAI,验证 Kubernetes YAML 是否可以正常渲染、创建资源、拉起 Pod,并完成前端和核心接口访问。
本地部署会在 kind 集群中同时启动以下依赖:
| 依赖 | 说明 |
| --- | --- |
| MongoDB | 主服务本地业务数据 |
| Redis | 队列、缓存、WebSocket 集群状态 |
| RabbitMQ | 本地消息队列 |
| PostgreSQL/pgvector | Agent 治理和记忆服务数据库 |
本地数据使用 `emptyDir`,删除 Pod 或集群后数据可能丢失。本地部署只用于验证,不代表生产高可用方案。
## 1. 本机准备
以下命令均在仓库根目录执行。如果当前已经在仓库根目录,可以跳过这一步;如果当前在本 README 所在目录,执行:
```bash
cd ../../..
```
确认 Docker 正在运行:
```bash
docker version
```
确认已有 `kubectl`
```bash
kubectl version --client
```
安装 kind
```bash
brew install kind
```
确认 kind 可用:
```bash
kind version
```
建议本机至少预留:
| 资源 | 建议 |
| --- | --- |
| CPU | 4 核以上 |
| 内存 | 12 GB 以上 |
| 磁盘 | 20 GB 以上 |
如果本机是 Apple Silicon,且某些镜像没有 arm64 版本,可能出现 `ImagePullBackOff``exec format error` 或 Pod 无法启动。遇到这种情况,先查看失败镜像和 Pod 事件,生产环境请使用 amd64 节点池或多架构镜像。
## 2. 创建 kind 集群
如果本机还没有 `easyai` 集群,执行:
```bash
kind create cluster --name easyai
```
如果之前已经创建过同名集群,并且希望从干净环境重新部署,执行:
```bash
kind delete cluster --name easyai
kind create cluster --name easyai
```
切换到 kind 集群:
```bash
kubectl config use-context kind-easyai
```
确认当前 context 和节点:
```bash
kubectl config current-context
kubectl get nodes -o wide
```
当前 context 应该是:
```text
kind-easyai
```
## 3. 部署前检查
渲染本地 YAML
```bash
kubectl kustomize k8s/overlays/local > /tmp/easyai-local.yaml
```
检查资源类型:
```bash
grep '^kind:' /tmp/easyai-local.yaml
```
准备 dry-run 需要的 namespace
```bash
kubectl create namespace easyai-local --dry-run=client -o yaml | kubectl apply -f -
```
执行服务端 dry-run
```bash
kubectl apply --dry-run=server -f /tmp/easyai-local.yaml
```
如果只想检查 YAML 是否能被本地解析,也可以执行:
```bash
kubectl apply --dry-run=client -f /tmp/easyai-local.yaml
```
## 4. 部署 EasyAI
执行部署:
```bash
kubectl apply -k k8s/overlays/local
```
查看 namespace
```bash
kubectl get ns easyai-local
```
查看资源:
```bash
kubectl -n easyai-local get deploy,svc,pods
```
等待依赖和应用启动:
```bash
for d in mongo redis rabbitmq easyai-pgvector easyai-server easyai-web ws-gateway video-edit sandbox easyai-asg agent-memory; do
kubectl -n easyai-local rollout status deploy/$d --timeout=15m
done
```
确认 Pod 状态:
```bash
kubectl -n easyai-local get pods -o wide
```
所有核心 Pod 都应进入 `Running`,并且 `READY` 数量正常。
## 5. 本地端口转发
本地前端配置使用 `127.0.0.1`,因此需要在本机打开端口转发。
建议打开 5 个终端窗口,并分别保持以下命令运行。
终端 1
```bash
kubectl -n easyai-local port-forward svc/easyai-web 3010:3010
```
终端 2
```bash
kubectl -n easyai-local port-forward svc/easyai-server 3001:3001
```
终端 3
```bash
kubectl -n easyai-local port-forward svc/ws-gateway 3002:3002
```
终端 4
```bash
kubectl -n easyai-local port-forward svc/easyai-asg 3003:3003
```
终端 5
```bash
kubectl -n easyai-local port-forward svc/agent-memory 3004:3004
```
端口被占用时,先查看占用进程:
```bash
lsof -iTCP:3010 -sTCP:LISTEN
lsof -iTCP:3001 -sTCP:LISTEN
lsof -iTCP:3002 -sTCP:LISTEN
lsof -iTCP:3003 -sTCP:LISTEN
lsof -iTCP:3004 -sTCP:LISTEN
```
停止占用进程后,重新执行对应的 `port-forward`
## 6. 访问验证
确认主服务:
```bash
curl -i http://127.0.0.1:3001/health
```
确认 ASG
```bash
curl -i http://127.0.0.1:3003/health
```
确认 Agent Memory
```bash
curl -i http://127.0.0.1:3004/health
```
打开前端:
```bash
open http://127.0.0.1:3010
```
本地默认管理员账号:
```text
admin / 123456
```
如果页面可以打开,但接口失败,请先确认 `3001``3002``3003``3004``port-forward` 仍在运行。
## 7. 查看状态和日志
查看 Service
```bash
kubectl -n easyai-local get svc
```
查看 Endpoints
```bash
kubectl -n easyai-local get endpoints easyai-web easyai-server ws-gateway easyai-asg agent-memory mongo redis rabbitmq easyai-pgvector
```
查看应用日志:
```bash
kubectl -n easyai-local logs deploy/easyai-server --tail=200
kubectl -n easyai-local logs deploy/ws-gateway --tail=200
kubectl -n easyai-local logs deploy/easyai-asg --tail=200
kubectl -n easyai-local logs deploy/agent-memory --tail=200
```
查看集群事件:
```bash
kubectl -n easyai-local get events --sort-by=.lastTimestamp | tail -80
```
## 8. 更新本地部署
如果代码仓库或镜像更新后需要重新部署,执行:
```bash
git pull
kubectl apply -k k8s/overlays/local
kubectl -n easyai-local rollout restart \
deploy/easyai-web \
deploy/easyai-server \
deploy/ws-gateway \
deploy/video-edit \
deploy/sandbox \
deploy/easyai-asg \
deploy/agent-memory
for d in easyai-server easyai-web ws-gateway video-edit sandbox easyai-asg agent-memory; do
kubectl -n easyai-local rollout status deploy/$d --timeout=15m
done
```
说明:应用镜像使用 `latest`,远端镜像更新后需要 `rollout restart` 才会重新创建 Pod 并拉取镜像。
## 9. 常见问题
### kubectl 连接不到集群
检查 context
```bash
kubectl config get-contexts
kubectl config current-context
```
切换回本地 kind 集群:
```bash
kubectl config use-context kind-easyai
```
### Pod 一直 Pending
查看原因:
```bash
kubectl -n easyai-local describe pod <PodName>
```
常见原因:
- 本机 CPU 或内存不足。
- Docker 没有足够可用资源。
- 镜像架构和本机架构不匹配。
### ImagePullBackOff
查看具体镜像:
```bash
kubectl -n easyai-local get pod <PodName> -o jsonpath='{.spec.containers[*].image}'
```
查看事件:
```bash
kubectl -n easyai-local describe pod <PodName>
```
常见原因:
- 本机网络无法访问 `registry.cn-shanghai.aliyuncs.com`
- 镜像 tag 不存在。
- 镜像没有当前 CPU 架构版本。
### CrashLoopBackOff
查看日志:
```bash
kubectl -n easyai-local logs <PodName> --all-containers --previous --tail=200
kubectl -n easyai-local logs <PodName> --all-containers --tail=200
```
常见原因:
- 依赖服务还没 Ready。
- MongoDB、Redis、RabbitMQ 或 PostgreSQL 初始化较慢。
- 镜像启动时执行数据库迁移失败。
可以先等依赖 Ready,再重启应用 Pod:
```bash
kubectl -n easyai-local rollout restart deploy/easyai-server deploy/easyai-asg deploy/agent-memory
```
### easyai-server Mongo 认证失败
如果 `easyai-server` 日志出现:
```text
MongoServerError: Authentication failed
UserNotFound: Could not find user "username" for db "admin"
```
通常是 MongoDB 首次初始化账号过程中被重启,导致 `/data/db` 已经非空但 root 用户没有创建完成。本地 overlay 使用 `emptyDir`,可以直接重建 Mongo Pod,让它按当前 Secret 重新初始化:
```bash
kubectl -n easyai-local delete pod -l app.kubernetes.io/name=mongo
kubectl -n easyai-local wait --for=condition=Ready pod -l app.kubernetes.io/name=mongo --timeout=5m
kubectl -n easyai-local rollout restart deploy/easyai-server deploy/easyai-web
```
### 端口转发断开
`kubectl port-forward` 会受到本地网络、终端关闭和 Pod 重启影响,断开后重新执行即可。
如果重新执行仍失败,先确认 Service 有 endpoints
```bash
kubectl -n easyai-local get endpoints easyai-web easyai-server ws-gateway easyai-asg agent-memory
```
### 前端打开但接口不通
确认所有 `port-forward` 正在运行:
```bash
lsof -iTCP:3010 -sTCP:LISTEN
lsof -iTCP:3001 -sTCP:LISTEN
lsof -iTCP:3002 -sTCP:LISTEN
lsof -iTCP:3003 -sTCP:LISTEN
lsof -iTCP:3004 -sTCP:LISTEN
```
重新验证接口:
```bash
curl -i http://127.0.0.1:3001/health
curl -i http://127.0.0.1:3003/health
curl -i http://127.0.0.1:3004/health
```
## 10. 清理本地环境
删除 EasyAI 本地部署:
```bash
kubectl delete -k k8s/overlays/local
```
如果不再需要本地 kind 集群:
```bash
kind delete cluster --name easyai
```
+91
View File
@@ -0,0 +1,91 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: easyai-app-config
data:
NUXT_PUBLIC_BASE_APIURL: http://127.0.0.1:3001
NUXT_PUBLIC_BASE_SOCKETURL: ws://127.0.0.1:3002
NUXT_PUBLIC_SG_APIURL: http://127.0.0.1:3003
NUXT_APP_CDN_URL: ""
MALLOC_ARENA_MAX: "2"
MALLOC_TRIM_THRESHOLD_: "131072"
MALLOC_MMAP_THRESHOLD_: "131072"
MALLOC_TOP_PAD_: "131072"
SHARP_CACHE_ENABLED: "false"
SHARP_CONCURRENCY: "1"
CONFIG_COMFYUI_QUENE_REDIS_HOST: redis
CONFIG_COMFYUI_QUENE_REDIS_PORT: "6379"
CONFIG_COMFYUI_QUENE_REDIS_USERNAME: ""
CONFIG_COMFYUI_QUENE_REDIS_DB: "6"
CONFIG_COMFYUI_CACHE_REDIS_DB: "11"
LOG_LEVEL: log,error,warn,debug
WS_GATEWAY_LOG_LEVEL: log,error,warn
CONFIG_TOKEN_EXPIRE: "1800"
CONFIG_PROXY_URL: ""
CONFIG_DOCS_DISABLE: "false"
CONFIG_MQ_PROTOCOL: amqp
CONFIG_MQ_HOST: rabbitmq
CONFIG_MQ_PORT: "5672"
CONFIG_MQ_VHOST: /
CONFIG_TCP_HOST: 0.0.0.0
CONFIG_TCP_PORT: "4002"
GATEWAY_CLUSTER_REDIS_ENABLED: "true"
GATEWAY_CLUSTER_REDIS_CHANNEL: easyai:wsgateway:cluster
GATEWAY_CLUSTER_REDIS_ROUTE_PREFIX: easyai:wsgateway:route
GATEWAY_CLUSTER_REDIS_ROUTE_TTL_SEC: "120"
GATEWAY_CLUSTER_REDIS_RECONNECT_INTERVAL_MS: "5000"
GATEWAY_CLUSTER_REDIS_URL: ""
GATEWAY_CLUSTER_REDIS_HOST: redis
GATEWAY_CLUSTER_REDIS_PORT: "6379"
GATEWAY_CLUSTER_REDIS_USERNAME: ""
GATEWAY_CLUSTER_REDIS_DB: "0"
WS_GATEWAY_TCP_EVENT_PATTERN: gateway.event.publish
WS_GATEWAY_TCP_TIMEOUT_MS: "1500"
GATEWAY_INBOUND_TCP_PATTERN: gateway.inbound.command
GATEWAY_INBOUND_TIMEOUT_MS: "5000"
WS_AUTH_REQUIRED: "false"
WS_AUTH_TIMEOUT_MS: "6000"
WS_AUTH_METHODS: none,bearer
WS_AUTH_WS_TICKETS: ""
ASG_REDIS_HOST: redis
ASG_REDIS_PORT: "6379"
ASG_REDIS_DB: "8"
ASG_PORT: "3003"
ASG_TCP_HOST: 0.0.0.0
ASG_TCP_PORT: "4003"
ASG_DOCS_DISABLE: "false"
ASG_MAIN_BACKEND_URL: http://easyai-server:3001
AMS_PORT: "3004"
MEMORY_AI_BASE_URL: http://easyai-server:3001
MEMORY_EMBEDDINGS_PATH: /v1/embeddings
MEMORY_EMBEDDING_MODELS_PATH: /v1/embeddings/models
MEMORY_EMBEDDING_DIMENSION: "1024"
MEMORY_EMBEDDING_MODEL: Qwen3-Embedding-v4
MEMORY_SCORE_CONFIDENCE_BASE: "0.6"
MEMORY_SCORE_CONFIDENCE_GAIN: "0.4"
MEMORY_SCORE_IMPORTANCE_BASE: "0.7"
MEMORY_SCORE_IMPORTANCE_GAIN: "0.3"
MEMORY_DEDUP_MIN_SCORE: "0.92"
MEMORY_TEXT_DEDUP_MIN_SCORE: "0.9"
MEMORY_CHAT_COMPLETIONS_PATH: /v1/chat/completions
MEMORY_CHAT_MODELS_PATH: /v1/models
MEMORY_CHAT_MODEL: qwen-plus
MEMORY_COMPRESSION_ENABLED: "true"
MEMORY_COMPRESSION_MIN_LENGTH: "80"
MEMORY_MAINTENANCE_ENABLED: "true"
MEMORY_MAINTENANCE_DRY_RUN: "false"
MEMORY_MAINTENANCE_BATCH_SIZE: "200"
MEMORY_MAINTENANCE_LLM_ENABLED: "true"
MEMORY_MAINTENANCE_LLM_MAX_PAIRS: "20"
MEMORY_DOCS_DISABLE: "false"
OSS_REGION: us-east-1
OSS_DOMAIN: ""
+38
View File
@@ -0,0 +1,38 @@
apiVersion: v1
kind: Secret
metadata:
name: easyai-app-secret
type: Opaque
stringData:
CONFIG_DB_MONGO_URI: mongodb://mongo:27017
CONFIG_DB_MONGO_USERNAME: username
CONFIG_DB_MONGO_PASSWORD: password
MONGO_INITDB_ROOT_USERNAME: username
MONGO_INITDB_ROOT_PASSWORD: password
CONFIG_COMFYUI_QUENE_REDIS_PASSWORD: ""
GATEWAY_CLUSTER_REDIS_PASSWORD: ""
ASG_REDIS_PASSWORD: ""
CONFIG_MQ_USER: admin
CONFIG_MQ_PASSWORD: easyai2025
CONFIG_JWT_SECRET: this is a very secret secret
CONFIG_TOKEN_SIGN_SK: easyai2025easyai
WS_AUTH_BEARER_TOKENS: ""
ASG_DATABASE_URL: postgresql://easyai:easyai2025@easyai-pgvector:5432/agent_governance?schema=public
MEMORY_DATABASE_URL: postgresql://easyai:easyai2025@easyai-pgvector:5432/easyai_memory?schema=public
ASG_POSTGRES_USER: easyai
ASG_POSTGRES_PASSWORD: easyai2025
ASG_POSTGRES_DB: agent_governance
ASG_ADMIN_USERNAME: admin
ASG_ADMIN_PASSWORD: "123456"
MEMORY_AI_API_KEY: ""
SANDBOX_JUPYTER_TOKEN: easyaiisbest
OSS_ENDPOINT: ""
OSS_ACCESS_KEY_ID: ""
OSS_ACCESS_KEY_SECRET: ""
OSS_BUCKET: ""
+365
View File
@@ -0,0 +1,365 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.conf: |
port 6379
replicaof no one
daemonize no
appendonly yes
dir /data
timeout 300
maxclients 10000
tcp-keepalive 60
save ""
tcp-backlog 511
replica-read-only no
maxmemory 2gb
maxmemory-policy noeviction
databases 16
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
slowlog-log-slower-than 10000
slowlog-max-len 128
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pgvector-init
data:
02-init-pgvector.sql: |
\c agent_governance
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE DATABASE easyai_memory;
GRANT ALL PRIVILEGES ON DATABASE easyai_memory TO easyai;
\c easyai_memory
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
labels:
app.kubernetes.io/name: mongo
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: mongo
template:
metadata:
labels:
app.kubernetes.io/name: mongo
spec:
containers:
- name: mongo
image: registry.cn-shanghai.aliyuncs.com/comfy-ai/mongo-aliyun:latest
imagePullPolicy: IfNotPresent
args:
- mongod
- --wiredTigerCacheSizeGB
- "1.5"
ports:
- name: mongo
containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: MONGO_INITDB_ROOT_USERNAME
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: MONGO_INITDB_ROOT_PASSWORD
volumeMounts:
- name: data
mountPath: /data/db
readinessProbe:
tcpSocket:
port: mongo
initialDelaySeconds: 20
periodSeconds: 10
startupProbe:
tcpSocket:
port: mongo
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 60
livenessProbe:
tcpSocket:
port: mongo
initialDelaySeconds: 60
periodSeconds: 30
resources:
requests:
cpu: 250m
memory: 1Gi
limits:
cpu: "1"
memory: 2500Mi
volumes:
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: mongo
labels:
app.kubernetes.io/name: mongo
spec:
selector:
app.kubernetes.io/name: mongo
ports:
- name: mongo
port: 27017
targetPort: mongo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app.kubernetes.io/name: redis
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: redis
template:
metadata:
labels:
app.kubernetes.io/name: redis
spec:
containers:
- name: redis
image: registry.cn-shanghai.aliyuncs.com/comfy-ai/redis-aliyun:latest
imagePullPolicy: IfNotPresent
command:
- redis-server
- /etc/redis/redis.conf
ports:
- name: redis
containerPort: 6379
volumeMounts:
- name: config
mountPath: /etc/redis/redis.conf
subPath: redis.conf
readOnly: true
- name: data
mountPath: /data
readinessProbe:
tcpSocket:
port: redis
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: redis
initialDelaySeconds: 30
periodSeconds: 30
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi
volumes:
- name: config
configMap:
name: redis-config
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app.kubernetes.io/name: redis
spec:
selector:
app.kubernetes.io/name: redis
ports:
- name: redis
port: 6379
targetPort: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rabbitmq
labels:
app.kubernetes.io/name: rabbitmq
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: rabbitmq
template:
metadata:
labels:
app.kubernetes.io/name: rabbitmq
spec:
containers:
- name: rabbitmq
image: registry.cn-shanghai.aliyuncs.com/easyaigc/mq:latest
imagePullPolicy: IfNotPresent
ports:
- name: amqp
containerPort: 5672
- name: management
containerPort: 15672
env:
- name: RABBITMQ_DEFAULT_USER
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: CONFIG_MQ_USER
- name: RABBITMQ_DEFAULT_PASS
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: CONFIG_MQ_PASSWORD
volumeMounts:
- name: data
mountPath: /var/lib/rabbitmq
readinessProbe:
tcpSocket:
port: amqp
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
tcpSocket:
port: amqp
initialDelaySeconds: 60
periodSeconds: 30
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
volumes:
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
labels:
app.kubernetes.io/name: rabbitmq
spec:
selector:
app.kubernetes.io/name: rabbitmq
ports:
- name: amqp
port: 5672
targetPort: amqp
- name: management
port: 15672
targetPort: management
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-pgvector
labels:
app.kubernetes.io/name: easyai-pgvector
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-pgvector
template:
metadata:
labels:
app.kubernetes.io/name: easyai-pgvector
spec:
containers:
- name: postgres
image: registry.cn-shanghai.aliyuncs.com/easyaigc/pgvector:0.8.2-pg18-trixie
imagePullPolicy: IfNotPresent
ports:
- name: postgres
containerPort: 5432
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: ASG_POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: ASG_POSTGRES_PASSWORD
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: easyai-app-secret
key: ASG_POSTGRES_DB
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
- name: init
mountPath: /docker-entrypoint-initdb.d/02-init-pgvector.sql
subPath: 02-init-pgvector.sql
readOnly: true
readinessProbe:
exec:
command:
- /bin/sh
- -c
- pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
exec:
command:
- /bin/sh
- -c
- pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
initialDelaySeconds: 60
periodSeconds: 30
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
volumes:
- name: data
emptyDir: {}
- name: init
configMap:
name: pgvector-init
---
apiVersion: v1
kind: Service
metadata:
name: easyai-pgvector
labels:
app.kubernetes.io/name: easyai-pgvector
spec:
selector:
app.kubernetes.io/name: easyai-pgvector
ports:
- name: postgres
port: 5432
targetPort: postgres
+48
View File
@@ -0,0 +1,48 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: easyai-local
resources:
- namespace.yaml
- ../../base
- app-config.yaml
- app-secret.yaml
- dependencies.yaml
patches:
- target:
kind: Deployment
name: easyai-web
patch: |-
- op: replace
path: /spec/replicas
value: 2
- target:
kind: Deployment
name: easyai-server
patch: |-
- op: replace
path: /spec/replicas
value: 2
- target:
kind: Deployment
name: ws-gateway
patch: |-
- op: replace
path: /spec/replicas
value: 1
- target:
kind: Deployment
name: easyai-asg
patch: |-
- op: replace
path: /spec/replicas
value: 1
- target:
kind: Deployment
name: agent-memory
patch: |-
- op: replace
path: /spec/replicas
value: 1
+7
View File
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: easyai-local
labels:
app.kubernetes.io/name: easyai-local
app.kubernetes.io/part-of: easyai
+91
View File
@@ -0,0 +1,91 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: easyai-app-config
data:
NUXT_PUBLIC_BASE_APIURL: /api
NUXT_PUBLIC_BASE_SOCKETURL: wss://easyai.example.com/socket.io
NUXT_PUBLIC_SG_APIURL: /asg-api
NUXT_APP_CDN_URL: ""
MALLOC_ARENA_MAX: "2"
MALLOC_TRIM_THRESHOLD_: "131072"
MALLOC_MMAP_THRESHOLD_: "131072"
MALLOC_TOP_PAD_: "131072"
SHARP_CACHE_ENABLED: "false"
SHARP_CONCURRENCY: "1"
CONFIG_COMFYUI_QUENE_REDIS_HOST: CHANGE_ME_REDIS_HOST
CONFIG_COMFYUI_QUENE_REDIS_PORT: "6379"
CONFIG_COMFYUI_QUENE_REDIS_USERNAME: ""
CONFIG_COMFYUI_QUENE_REDIS_DB: "6"
CONFIG_COMFYUI_CACHE_REDIS_DB: "11"
LOG_LEVEL: log,error,warn
WS_GATEWAY_LOG_LEVEL: log,error,warn
CONFIG_TOKEN_EXPIRE: "1800"
CONFIG_PROXY_URL: ""
CONFIG_DOCS_DISABLE: "true"
CONFIG_MQ_PROTOCOL: amqp
CONFIG_MQ_HOST: CHANGE_ME_RABBITMQ_HOST
CONFIG_MQ_PORT: "5672"
CONFIG_MQ_VHOST: /
CONFIG_TCP_HOST: 0.0.0.0
CONFIG_TCP_PORT: "4002"
GATEWAY_CLUSTER_REDIS_ENABLED: "true"
GATEWAY_CLUSTER_REDIS_CHANNEL: easyai:wsgateway:cluster
GATEWAY_CLUSTER_REDIS_ROUTE_PREFIX: easyai:wsgateway:route
GATEWAY_CLUSTER_REDIS_ROUTE_TTL_SEC: "120"
GATEWAY_CLUSTER_REDIS_RECONNECT_INTERVAL_MS: "5000"
GATEWAY_CLUSTER_REDIS_URL: ""
GATEWAY_CLUSTER_REDIS_HOST: CHANGE_ME_REDIS_HOST
GATEWAY_CLUSTER_REDIS_PORT: "6379"
GATEWAY_CLUSTER_REDIS_USERNAME: ""
GATEWAY_CLUSTER_REDIS_DB: "0"
WS_GATEWAY_TCP_EVENT_PATTERN: gateway.event.publish
WS_GATEWAY_TCP_TIMEOUT_MS: "1500"
GATEWAY_INBOUND_TCP_PATTERN: gateway.inbound.command
GATEWAY_INBOUND_TIMEOUT_MS: "5000"
WS_AUTH_REQUIRED: "false"
WS_AUTH_TIMEOUT_MS: "6000"
WS_AUTH_METHODS: none,bearer
WS_AUTH_WS_TICKETS: ""
ASG_REDIS_HOST: CHANGE_ME_REDIS_HOST
ASG_REDIS_PORT: "6379"
ASG_REDIS_DB: "8"
ASG_PORT: "3003"
ASG_TCP_HOST: 0.0.0.0
ASG_TCP_PORT: "4003"
ASG_DOCS_DISABLE: "true"
ASG_MAIN_BACKEND_URL: http://easyai-server:3001
AMS_PORT: "3004"
MEMORY_AI_BASE_URL: http://easyai-server:3001
MEMORY_EMBEDDINGS_PATH: /v1/embeddings
MEMORY_EMBEDDING_MODELS_PATH: /v1/embeddings/models
MEMORY_EMBEDDING_DIMENSION: "1024"
MEMORY_EMBEDDING_MODEL: Qwen3-Embedding-v4
MEMORY_SCORE_CONFIDENCE_BASE: "0.6"
MEMORY_SCORE_CONFIDENCE_GAIN: "0.4"
MEMORY_SCORE_IMPORTANCE_BASE: "0.7"
MEMORY_SCORE_IMPORTANCE_GAIN: "0.3"
MEMORY_DEDUP_MIN_SCORE: "0.92"
MEMORY_TEXT_DEDUP_MIN_SCORE: "0.9"
MEMORY_CHAT_COMPLETIONS_PATH: /v1/chat/completions
MEMORY_CHAT_MODELS_PATH: /v1/models
MEMORY_CHAT_MODEL: qwen-plus
MEMORY_COMPRESSION_ENABLED: "true"
MEMORY_COMPRESSION_MIN_LENGTH: "80"
MEMORY_MAINTENANCE_ENABLED: "true"
MEMORY_MAINTENANCE_DRY_RUN: "false"
MEMORY_MAINTENANCE_BATCH_SIZE: "200"
MEMORY_MAINTENANCE_LLM_ENABLED: "true"
MEMORY_MAINTENANCE_LLM_MAX_PAIRS: "20"
MEMORY_DOCS_DISABLE: "true"
OSS_REGION: us-east-1
OSS_DOMAIN: ""
+38
View File
@@ -0,0 +1,38 @@
apiVersion: v1
kind: Secret
metadata:
name: easyai-app-secret
type: Opaque
stringData:
CONFIG_DB_MONGO_URI: mongodb://CHANGE_ME_MONGO_HOST:27017
CONFIG_DB_MONGO_USERNAME: CHANGE_ME_MONGO_USERNAME
CONFIG_DB_MONGO_PASSWORD: CHANGE_ME_MONGO_PASSWORD
MONGO_INITDB_ROOT_USERNAME: CHANGE_ME_MONGO_USERNAME
MONGO_INITDB_ROOT_PASSWORD: CHANGE_ME_MONGO_PASSWORD
CONFIG_COMFYUI_QUENE_REDIS_PASSWORD: CHANGE_ME_REDIS_PASSWORD
GATEWAY_CLUSTER_REDIS_PASSWORD: CHANGE_ME_REDIS_PASSWORD
ASG_REDIS_PASSWORD: CHANGE_ME_REDIS_PASSWORD
CONFIG_MQ_USER: CHANGE_ME_RABBITMQ_USERNAME
CONFIG_MQ_PASSWORD: CHANGE_ME_RABBITMQ_PASSWORD
CONFIG_JWT_SECRET: CHANGE_ME_LONG_RANDOM_JWT_SECRET
CONFIG_TOKEN_SIGN_SK: CHANGE_ME_LONG_RANDOM_TOKEN_SIGN_KEY
WS_AUTH_BEARER_TOKENS: ""
ASG_DATABASE_URL: postgresql://CHANGE_ME_POSTGRES_USER:CHANGE_ME_POSTGRES_PASSWORD@CHANGE_ME_POSTGRES_HOST:5432/agent_governance?schema=public
MEMORY_DATABASE_URL: postgresql://CHANGE_ME_POSTGRES_USER:CHANGE_ME_POSTGRES_PASSWORD@CHANGE_ME_POSTGRES_HOST:5432/easyai_memory?schema=public
ASG_POSTGRES_USER: CHANGE_ME_POSTGRES_USER
ASG_POSTGRES_PASSWORD: CHANGE_ME_POSTGRES_PASSWORD
ASG_POSTGRES_DB: agent_governance
ASG_ADMIN_USERNAME: admin
ASG_ADMIN_PASSWORD: CHANGE_ME_EASYAI_ADMIN_PASSWORD
MEMORY_AI_API_KEY: ""
SANDBOX_JUPYTER_TOKEN: CHANGE_ME_DISABLE_PUBLIC_JUPYTER_OR_SET_TOKEN
OSS_ENDPOINT: ""
OSS_ACCESS_KEY_ID: ""
OSS_ACCESS_KEY_SECRET: ""
OSS_BUCKET: ""
+137
View File
@@ -0,0 +1,137 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: easyai-web
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: easyai-web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: easyai-server
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: easyai-server
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
behavior:
scaleDown:
stabilizationWindowSeconds: 300
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ws-gateway
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ws-gateway
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: video-edit
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: video-edit
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 600
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: easyai-asg
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: easyai-asg
minReplicas: 2
maxReplicas: 8
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: agent-memory
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: agent-memory
minReplicas: 2
maxReplicas: 8
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
+126
View File
@@ -0,0 +1,126 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: easyai-web
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
spec:
ingressClassName: nginx
tls:
- hosts:
- easyai.example.com
secretName: easyai-tls
rules:
- host: easyai.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: easyai-web
port:
number: 3010
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: easyai-api
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/proxy-body-size: 100m
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1200"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1200"
spec:
ingressClassName: nginx
tls:
- hosts:
- easyai.example.com
secretName: easyai-tls
rules:
- host: easyai.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: easyai-server
port:
number: 3001
- path: /asg-api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: easyai-asg
port:
number: 3003
- path: /ams-api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: agent-memory
port:
number: 3004
- path: /sandbox(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: sandbox
port:
number: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: easyai-ws
annotations:
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
spec:
ingressClassName: nginx
tls:
- hosts:
- easyai.example.com
secretName: easyai-tls
rules:
- host: easyai.example.com
http:
paths:
- path: /socket.io
pathType: Prefix
backend:
service:
name: ws-gateway
port:
number: 3002
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: easyai-mcp
annotations:
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
spec:
ingressClassName: nginx
tls:
- hosts:
- easyai.example.com
secretName: easyai-tls
rules:
- host: easyai.example.com
http:
paths:
- path: /mcp
pathType: Prefix
backend:
service:
name: easyai-server
port:
number: 3001
+107
View File
@@ -0,0 +1,107 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: easyai
resources:
- namespace.yaml
- ../../base
- app-config.yaml
- app-secret.yaml
- shared-pvc.yaml
- ingress.yaml
- hpa.yaml
- pdb.yaml
images:
- name: registry.cn-shanghai.aliyuncs.com/comfy-ai/one-ai
newTag: latest
- name: registry.cn-shanghai.aliyuncs.com/comfy-ai/comfy-server
newTag: latest
- name: registry.cn-shanghai.aliyuncs.com/easyaigc/wsgateway
newTag: latest
- name: registry.cn-shanghai.aliyuncs.com/easyaigc/videoedit
newTag: latest
- name: registry.cn-shanghai.aliyuncs.com/easyaigc/sandbox
newTag: latest
- name: registry.cn-shanghai.aliyuncs.com/easyaigc/agent-governance
newTag: latest
- name: registry.cn-shanghai.aliyuncs.com/easyaigc/agent-memory
newTag: latest
patches:
- target:
kind: Deployment
name: easyai-server
patch: |-
- op: replace
path: /spec/template/spec/volumes/0
value:
name: shared-files
persistentVolumeClaim:
claimName: easyai-shared-files
- target:
kind: Deployment
name: easyai-web
patch: |-
- op: add
path: /spec/template/spec/topologySpreadConstraints
value:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: easyai-web
- target:
kind: Deployment
name: easyai-server
patch: |-
- op: add
path: /spec/template/spec/topologySpreadConstraints
value:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: easyai-server
- target:
kind: Deployment
name: ws-gateway
patch: |-
- op: add
path: /spec/template/spec/topologySpreadConstraints
value:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: ws-gateway
- target:
kind: Deployment
name: easyai-asg
patch: |-
- op: add
path: /spec/template/spec/topologySpreadConstraints
value:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: easyai-asg
- target:
kind: Deployment
name: agent-memory
patch: |-
- op: add
path: /spec/template/spec/topologySpreadConstraints
value:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: agent-memory
+7
View File
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: easyai
labels:
app.kubernetes.io/name: easyai
app.kubernetes.io/part-of: easyai
+49
View File
@@ -0,0 +1,49 @@
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: easyai-web
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-web
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: easyai-server
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-server
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: ws-gateway
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: ws-gateway
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: easyai-asg
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-asg
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: agent-memory
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: agent-memory
+13
View File
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: easyai-shared-files
labels:
app.kubernetes.io/name: easyai-shared-files
spec:
accessModes:
- ReadWriteMany
storageClassName: CHANGE_ME_RWX_STORAGE_CLASS
resources:
requests:
storage: 100Gi