添加qiming-rcoder模块

This commit is contained in:
Codex
2026-06-01 13:54:52 +08:00
parent 8092c4b1f8
commit 4b1a580132
539 changed files with 151650 additions and 0 deletions

View File

@@ -0,0 +1,282 @@
# JuiceFS + MinIO + PostgreSQL 部署指南
## 架构
```
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ JuiceFS CSI Driver │ │
│ │ (StorageClass: juicefs-sc) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ rcoder 主服务 │ │ Agent Runner │ │
│ │ Pod (Deployment)│ │ Pod (动态创建) │ │
│ └────────┬───────┘ └────────┬───────┘ │
│ │ │ │
│ └──────────┬───────────┘ │
│ ↓ │
│ ┌──────────────┐ │
│ │ JuiceFS 卷 │ ← 共享文件系统 (RWX) │
│ └───────┬──────┘ │
└──────────────────────┼────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────┐
│ MinIO (S3) ←──── 数据存储 │
│ PostgreSQL ← 元数据存储 │
└───────────────────────────────────────────────────────────────┘
```
## 文件结构
```
manifests/
├── 00-namespace.yaml # Namespace
├── 01-storage/ # 存储层
│ ├── postgresql-deployment.yaml
│ ├── minio-deployment.yaml
│ ├── minio-init-job.yaml
│ ├── juicefs-secret.yaml
│ ├── juicefs-storageclass.yaml
│ └── juicefs-pvc.yaml
├── 02-rcoder/ # 应用层
│ ├── serviceaccount.yaml
│ ├── rcoder-configmap.yaml
│ ├── rcoder-deployment.yaml
│ ├── rcoder-service.yaml
│ ├── rcoder-networkpolicy.yaml
│ └── rcoder-pdb.yaml
└── _deprecated/nfs/ # 废弃的 NFS 配置
```
## 部署顺序
### 第一步:部署 JuiceFS CSI Driver
```bash
# 使用 Helm 部署
helm repo add juicefs https://juicefs.github.io/charts
helm repo update
helm install juicefs-csi-driver juicefs/juicefs-csi-driver \
--namespace kube-system \
--set webhook.enabled=false \
--set csiSidecarImage.registry=docker.io \
--set csiSidecarImage.repository=juicedata/csi-sidecar \
--set csiSidecarImage.tag=v1.3.8 \
--set image.registry=docker.io \
--set image.repository=juicedata/juicefs-csi-driver \
--set image.tag=v1.1.0 \
--set nodeDaemonImage.registry=docker.io \
--set nodeDaemonImage.repository=juicedata/juicefs-csi-driver \
--set nodeDaemonImage.tag=v1.1.0
```
验证:
```bash
kubectl get pods -n kube-system | grep juicefs
# 预期juicefs-csi-driver-xxx 运行正常
```
---
### 第二步:部署 PostgreSQL
```bash
kubectl apply -f manifests/01-storage/postgresql-deployment.yaml
```
验证:
```bash
kubectl get pods -n nuwax-rcoder | grep postgresql
kubectl logs -n nuwax-rcoder -l app=postgresql --tail=50
```
---
### 第三步:部署 MinIO
```bash
kubectl apply -f manifests/01-storage/minio-deployment.yaml
```
验证:
```bash
kubectl get pods -n nuwax-rcoder | grep minio
# 访问 MinIO Console: http://<minio-ip>:9001
```
---
### 第四步:初始化 MinIO Bucket
```bash
kubectl apply -f manifests/01-storage/minio-init-job.yaml
# 等待完成
kubectl wait --for=condition=complete job/minio-init -n nuwax-rcoder --timeout=120s
# 验证
kubectl exec -it -n nuwax-rcoder deploy/minio -- mc ls myminio/
```
---
### 第五步:创建 JuiceFS Secret
```bash
kubectl apply -f manifests/01-storage/juicefs-secret.yaml
```
---
### 第六步:创建 JuiceFS StorageClass
```bash
kubectl apply -f manifests/01-storage/juicefs-storageclass.yaml
```
验证:
```bash
kubectl get sc | grep juicefs
```
---
### 第七步:部署 RCoder 相关资源
```bash
# 部署 rcoder PVC (使用 JuiceFS)
kubectl apply -f manifests/01-storage/juicefs-pvc.yaml
# 验证 PVC
kubectl get pvc -n nuwax-rcoder
# 状态应为 Bound
# 部署其他 rcoder 资源
kubectl apply -f manifests/00-namespace.yaml
kubectl apply -f manifests/02-rcoder/serviceaccount.yaml
kubectl apply -f manifests/02-rcoder/rcoder-configmap.yaml
kubectl apply -f manifests/02-rcoder/rcoder-deployment.yaml
kubectl apply -f manifests/02-rcoder/rcoder-service.yaml
kubectl apply -f manifests/02-rcoder/rcoder-networkpolicy.yaml
kubectl apply -f manifests/02-rcoder/rcoder-pdb.yaml
```
---
### 第八步:验证整个系统
```bash
# 检查所有 Pod
kubectl get pods -n nuwax-rcoder
# 查看 JuiceFS 挂载情况
kubectl exec -it -n nuwax-rcoder deploy/rcoder -- df -h | grep juicefs
# 测试写入
kubectl exec -it -n nuwax-rcoder deploy/rcoder -- sh -c "echo 'test' > /app/project_workspace/test.txt"
# 查看日志
kubectl logs -n nuwax-rcoder -l app=rcoder --tail=50
```
---
## 存储结构
部署后,数据存储结构如下:
```
PostgreSQL (元数据):
├── juicefs database
│ ├── inodes
│ ├── chunks
│ ├── del-files
│ └── sessions
MinIO (S3 数据):
├── juicefs bucket
│ └── juicefs/
│ ├── juicefs.db ← JuiceFS 内部数据库
│ └── chunk-xxx ← 数据块
```
---
## 卸载顺序
```bash
# 1. 删除 rcoder 资源
kubectl delete -f manifests/02-rcoder/rcoder-deployment.yaml
kubectl delete -f manifests/02-rcoder/rcoder-configmap.yaml
kubectl delete -f manifests/01-storage/juicefs-pvc.yaml
# 2. 删除 JuiceFS 相关
kubectl delete -f manifests/01-storage/juicefs-storageclass.yaml
kubectl delete -f manifests/01-storage/juicefs-secret.yaml
# 3. 删除存储层
kubectl delete -f manifests/01-storage/minio-deployment.yaml
kubectl delete -f manifests/01-storage/postgresql-deployment.yaml
# 4. 删除 JuiceFS CSI Driver (可选)
helm uninstall juicefs-csi-driver -n kube-system
```
---
## 常见问题
### 1. PVC 一直 Pending
```bash
# 检查 JuiceFS CSI Driver 状态
kubectl get pods -n kube-system | grep juicefs
# 检查 StorageClass
kubectl get sc juicefs-sc -o yaml
# 检查 Secret
kubectl get secret juicefs-secret -n nuwax-rcoder -o yaml
```
### 2. MinIO Bucket 创建失败
```bash
# 确认 MinIO 运行正常
kubectl logs -n nuwax-rcoder -l app=minio --tail=20
# 手动进入 Pod 测试
kubectl exec -it -n nuwax-rcoder deploy/minio -- sh
mc alias set myminio http://localhost:9000 minioadmin minioadmin
mc mb myminio/juicefs
```
### 3. JuiceFS 挂载失败
```bash
# 查看 Node Pod 日志
kubectl get pods -n kube-system -o wide | grep juicefs
# 查看挂载详情
kubectl describe pod -n kube-system -l app=juicefs-csi-driver-node
```
---
## 资源需求
| 组件 | CPU | Memory | Storage |
|------|-----|--------|---------|
| PostgreSQL | 500m | 1Gi | 20Gi |
| MinIO | 500m | 1Gi | 100Gi+ |
| JuiceFS CSI | 100m | 128Mi | - |
总计:约 2 核 + 2.5Gi + 120Gi 存储

View File

@@ -0,0 +1,106 @@
# ============================================================
# NFS Server (内建模式)
# 集群内自建 NFS Server数据持久化到 local-path PV
#
# ⚠️ 注意: OrbStack/Mac 桌面 K8s 环境不支持此方式,请使用外部 NFS Server
#
# 如使用外部 NFS Server跳过此文件直接部署 nfs-subdir-provisioner.yaml
# ============================================================
---
apiVersion: v1
kind: Namespace
metadata:
name: nfs-storage
---
apiVersion: v1
kind: Service
metadata:
name: nfs-server
namespace: nuwax-nfs-storage
spec:
clusterIP: None
selector:
app: nfs-server
ports:
- name: nfs
port: 2049
targetPort: 2049
- name: mountd
port: 20048
targetPort: 20048
- name: rpcbind
port: 111
targetPort: 111
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nfs-server
namespace: nuwax-nfs-storage
spec:
serviceName: nfs-server
replicas: 1
selector:
matchLabels:
app: nfs-server
template:
metadata:
labels:
app: nfs-server
spec:
# 亲和性: NFS Server 调度到有 local-path 存储的节点
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: Exists
containers:
- name: nfs-server
image: itsthenetwork/nfs-server-alpine:latest
env:
- name: SHARED_DIRECTORY
value: "/exports"
- name: SYNC
value: "true"
ports:
- name: nfs
containerPort: 2049
protocol: TCP
- name: mountd
containerPort: 20048
protocol: TCP
- name: rpcbind
containerPort: 111
protocol: TCP
securityContext:
runAsUser: 0
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
volumeMounts:
- name: nfs-data
mountPath: /exports
volumes:
- name: nfs-data
persistentVolumeClaim:
claimName: nfs-server-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-server-pvc
namespace: nuwax-nfs-storage
labels:
app: nfs-server
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: local-path
resources:
requests:
storage: 100Gi

View File

@@ -0,0 +1,135 @@
# ============================================================
# NFS Subdir External Provisioner + StorageClass
#
# 两种使用方式:
# 模式一(内建 NFS): nfs-server.yaml 部署后,使用此文件
# 模式二(外部 NFS): 直接修改 NFS_SERVER/NFS_PATH 环境变量指向外部 NFS
#
# 参考: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
# ============================================================
---
apiVersion: v1
kind: Namespace
metadata:
name: nfs-storage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: nuwax-nfs-storage
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-cluster-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["csinodeinfos"]
verbs: ["get", "list", "watch"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner-cluster-runner-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nfs-client-provisioner-cluster-runner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: nuwax-nfs-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: nuwax-nfs-storage
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-provisioner
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: rcoder-nfs
# ⚠️ 修改此处指向外部 NFS Server
# 内建模式: nfs-server.nfs-storage.svc.cluster.local (nfs-server.yaml 部署后)
# 外部模式: 替换为客户提供的 NFS 地址,如 192.168.1.100
- name: NFS_SERVER
value: nfs-server.nfs-storage.svc.cluster.local
- name: NFS_PATH
value: /exports
- name: NFS_MOUNT_OPTIONS
value: "vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2"
- name: ON_DELETE_POLICY
value: "delete"
- name: ARCHIVE_ON_DELETE
value: "false"
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "256Mi"
volumes:
- name: nfs-provisioner
nfs:
# ⚠️ 修改此处指向外部 NFS Server
server: nfs-server.nfs-storage.svc.cluster.local
path: /exports
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rcoder-nfs
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: rcoder-nfs
parameters:
pathPattern: "${.PVC.namespace}/${.PVC.name}"
onDelete: "delete"
archiveOnDelete: "false"
mountOptions:
- vers=4.1
- rsize=1048576
- wsize=1048576
- hard
- timeo=600
- retrans=2
- noresvport
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

View File

@@ -0,0 +1,10 @@
# Kustomize base - 基础配置
# 使用方式: kubectl apply -k manifests/base
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- storage
- rcoder

View File

@@ -0,0 +1,5 @@
# Namespace for RCoder
apiVersion: v1
kind: Namespace
metadata:
name: nuwax-rcoder

View File

@@ -0,0 +1,15 @@
# RCoder application layer - 应用层配置
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 注意:
# - rcoder-configmap.yaml 由各环境 overlay 提供storage_class 需随环境变化)
# - ClusterRoleBinding 由各环境 overlay 提供(避免集群级命名冲突)
resources:
- serviceaccount.yaml
- rcoder-deployment.yaml
- rcoder-service.yaml
- rcoder-networkpolicy.yaml
- rcoder-pdb.yaml

View File

@@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: rcoder
namespace: nuwax-rcoder
spec:
replicas: 1
selector:
matchLabels:
app: rcoder
component: rcoder-main
template:
metadata:
labels:
app: rcoder
component: rcoder-main
spec:
# Graceful shutdown: allow 60s for containers to clean up
terminationGracePeriodSeconds: 60
serviceAccountName: rcoder-pods-sa
containers:
- name: rcoder
image: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest
# IfNotPresent: 节点已缓存就直接用,避免每次启动都去 registry 验 token/manifest
# 缺点: latest tag 内容更新后需 kubectl rollout restart 才会拉新 image
imagePullPolicy: IfNotPresent
command: ["/app/bin/rcoder"]
args: ["--port", "8087"]
ports:
- containerPort: 8087
env:
- name: CONTAINER_RUNTIME
value: "kubernetes"
- name: RCODER_K8S_NAMESPACE
value: "nuwax-rcoder"
- name: RUST_LOG
value: "info"
# JuiceFS 存储配置 (StorageClass 名称由各环境 overlay 覆盖)
- name: RCODER_K8S_STORAGE_CLASS
value: "juicefs-sc-placeholder"
- name: RCODER_DOCKER_IMAGE
value: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
- name: RCODER_DOCKER_IMAGE_COMPUTER
value: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
# Health probes for K8s liveness/readiness detection
livenessProbe:
httpGet:
path: /health
port: 8087
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 8087
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 2
volumeMounts:
- name: rcoder-config
mountPath: /app/config.yml
subPath: config.yml
- name: project-workspace
mountPath: /app/project_workspace
subPath: project_workspace
- name: project-workspace
mountPath: /app/computer-project-workspace
subPath: computer_workspace
volumes:
- name: rcoder-config
configMap:
name: rcoder-config
- name: project-workspace
persistentVolumeClaim:
claimName: rcoder-workspace

View File

@@ -0,0 +1,70 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rcoder-network-policy
namespace: nuwax-rcoder
spec:
podSelector:
matchLabels:
app: rcoder
policyTypes:
- Ingress
- Egress
ingress:
# 允许来自同 namespace 的流量
- from:
- podSelector: {}
ports:
- protocol: TCP
port: 8087
- protocol: TCP
port: 8088
egress:
# DNS 解析
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
# K8s API Server
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
kubernetes.io/service-name: kubernetes
ports:
- protocol: TCP
port: 443
# PostgreSQL 访问
- to:
- podSelector:
matchLabels:
app: postgresql
ports:
- protocol: TCP
port: 5432
# MinIO 访问
- to:
- podSelector:
matchLabels:
app: minio
ports:
- protocol: TCP
port: 9000
- protocol: TCP
port: 9001
# Agent Pod gRPC 访问 (rcoder -> agent 通信)
# 用 managed-by: rcoder-runtime 标签同时匹配两类动态创建的 pod
# - service_type=rcoder (legacy /chat 创建的 rcoder-agent pod)
# - service_type=computer-agent-runner (/computer/chat 创建的 computer-agent-runner pod)
- to:
- podSelector:
matchLabels:
managed-by: rcoder-runtime
ports:
- protocol: TCP
port: 50051
- protocol: TCP
port: 8086

View File

@@ -0,0 +1,10 @@
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: rcoder-pdb
namespace: nuwax-rcoder
spec:
maxUnavailable: 0
selector:
matchLabels:
app: rcoder

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: rcoder
namespace: nuwax-rcoder
spec:
type: NodePort
# 用 component=rcoder-main 把动态创建的 rcoder-agent / computer-agent-runner pod
# (它们也带 app=rcoder 标签)排除在外,避免 NodePort 把流量路由到不监听 8087 的 agent pod
selector:
app: rcoder
component: rcoder-main
ports:
# nodePort 由各环境 overlay 指定(避免同集群下 dev/prod 冲突)
- port: 8087
targetPort: 8087

View File

@@ -0,0 +1,35 @@
# ServiceAccount + ClusterRole for RCoder to manage Pods
# 注意: ClusterRoleBinding 由各环境 overlay 提供(避免集群级命名冲突)
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: rcoder-pods-sa
namespace: nuwax-rcoder
---
# ClusterRole for Pod management集群共享dev/prod 可复用同一个 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: rcoder-pods-clusterrole
rules:
# Pod 管理
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
# Pod 日志
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "list"]
# Pod 执行命令(用于调试)
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
# Pod 状态
- apiGroups: [""]
resources: ["pods/status"]
verbs: ["get"]
# PVC 管理(动态创建/删除工作空间存储)
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "delete"]

View File

@@ -0,0 +1,19 @@
# ============================================================
# RCoder JuiceFS PVC
# 替代原来的 NFS PVC
# ============================================================
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rcoder-workspace
namespace: nuwax-rcoder
labels:
app: rcoder
spec:
# ReadWriteMany: 支持 K8s 多节点同时读写 (JuiceFS 特性)
accessModes: ["ReadWriteMany"]
# storageClassName 由各环境 overlay 覆盖dev: juicefs-sc-dev, prod: juicefs-sc-prod
storageClassName: juicefs-sc-placeholder
resources:
requests:
storage: 50Gi

View File

@@ -0,0 +1,15 @@
# Storage layer - 存储层配置
# 注意:
# - juicefs-secret 由各环境 overlay 提供 (dev/prod)
# - juicefs-storageclass 由各环境 overlay 提供(集群级资源需按环境独立命名,避免冲突)
# - 不再使用 juicefs-init JobJuiceFS CSI driver 首次挂载时会用 Secret 里的
# name/metaurl/storage/bucket/access-key/secret-key 自动执行 formatJob 是冗余的
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- postgresql-deployment.yaml
- minio-deployment.yaml
- minio-init-job.yaml
- juicefs-pvc.yaml

View File

@@ -0,0 +1,112 @@
# ============================================================
# MinIO for JuiceFS Data Storage
# JuiceFS S3 兼容对象存储
# ============================================================
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: minio-pvc
namespace: nuwax-rcoder
labels:
app: minio
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-path" # 单节点环境使用 local-path
resources:
requests:
storage: 30Gi # 单节点环境使用较小存储
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
namespace: nuwax-rcoder
spec:
serviceName: minio
replicas: 1
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: minio/minio:latest
ports:
- containerPort: 9000
name: api
- containerPort: 9001
name: console
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: rcoder-credentials
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: rcoder-credentials
key: MINIO_ROOT_PASSWORD
args:
- server
- /data
- --console-address
- ":9001"
livenessProbe:
httpGet:
path: /minio/health/live
port: 9000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /minio/health/ready
port: 9000
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: minio-data
mountPath: /data
volumes:
- name: minio-data
persistentVolumeClaim:
claimName: minio-pvc
---
apiVersion: v1
kind: Service
metadata:
name: minio
namespace: nuwax-rcoder
spec:
selector:
app: minio
ports:
- name: api
port: 9000
targetPort: 9000
- name: console
port: 9001
targetPort: 9001
clusterIP: None # Headless service for StatefulSet
---
# Service for K8s internal access (ClusterIP)
apiVersion: v1
kind: Service
metadata:
name: minio-service
namespace: nuwax-rcoder
spec:
selector:
app: minio
ports:
- name: api
port: 9000
targetPort: 9000
- name: console
port: 9001
targetPort: 9001

View File

@@ -0,0 +1,47 @@
# ============================================================
# MinIO Bucket 初始化 Job
# 创建 JuiceFS 所需的 bucket
# ============================================================
apiVersion: batch/v1
kind: Job
metadata:
name: minio-init
namespace: nuwax-rcoder
spec:
ttlSecondsAfterFinished: 300 # Job 完成后 5 分钟自动清理
template:
spec:
restartPolicy: OnFailure
containers:
- name: mc
image: minio/mc:latest
command:
- /bin/sh
- -c
- |
# 等待 MinIO 就绪
echo "Waiting for MinIO to be ready..."
until mc alias set myminio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD}; do
echo "MinIO not ready, retrying..."
sleep 2
done
echo "MinIO is ready, creating bucket..."
# 创建 JuiceFS 专用 bucket
mc mb myminio/juicefs --ignore-existing
# 验证
mc ls myminio/
echo "MinIO initialization completed!"
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: rcoder-credentials
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: rcoder-credentials
key: MINIO_ROOT_PASSWORD

View File

@@ -0,0 +1,97 @@
# ============================================================
# PostgreSQL for JuiceFS Metadata
# JuiceFS 元数据存储
# ============================================================
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgresql-pvc
namespace: nuwax-rcoder
labels:
app: postgresql
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-path" # 单节点环境使用 local-path
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
namespace: nuwax-rcoder
spec:
serviceName: postgresql
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
initContainers:
- name: cleanup
image: postgres:16-alpine
command: ["rm", "-rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
containers:
- name: postgresql
image: postgres:16-alpine
ports:
- containerPort: 5432
name: postgres
env:
- name: POSTGRES_DB
value: "juicefs"
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: rcoder-credentials
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: rcoder-credentials
key: POSTGRES_PASSWORD
livenessProbe:
exec:
command:
- pg_isready
- -U
- juicefs
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- pg_isready
- -U
- juicefs
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: postgresql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: postgresql
namespace: nuwax-rcoder
spec:
selector:
app: postgresql
ports:
- name: postgres
port: 5432
targetPort: 5432

View File

@@ -0,0 +1,17 @@
# ============================================================
# ClusterRoleBinding - Dev 环境专用
# 把 base 里共享的 ClusterRole 绑定到 dev namespace 的 ServiceAccount
# 集群级资源独立命名,避免与 prod 冲突
# ============================================================
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: rcoder-pods-crb-dev
subjects:
- kind: ServiceAccount
name: rcoder-pods-sa
namespace: nuwax-rcoder-dev
roleRef:
kind: ClusterRole
name: rcoder-pods-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,16 @@
# ============================================================
# 存储层凭据 Secret - Dev 环境
# 维护 PostgreSQL / MinIO 账号密码
# 注意:同步维护 juicefs-secret.yaml 里的 metaurl / MINIO_ACCESS_KEY 等字段
# ============================================================
apiVersion: v1
kind: Secret
metadata:
name: rcoder-credentials
namespace: nuwax-rcoder-dev
type: Opaque
stringData:
POSTGRES_USER: "juicefs"
POSTGRES_PASSWORD: "juicefs_password"
MINIO_ROOT_USER: "minioadmin"
MINIO_ROOT_PASSWORD: "minioadmin"

View File

@@ -0,0 +1,28 @@
# ============================================================
# JuiceFS Secret - Dev 环境专用
# 覆盖 base 中的 juicefs-secret
# ============================================================
apiVersion: v1
kind: Secret
metadata:
name: juicefs-secret
namespace: nuwax-rcoder-dev
type: Opaque
stringData:
# JuiceFS CE 必需字段(小写键名)
name: "rcoder-juicefs"
metaurl: "postgres://juicefs:juicefs_password@postgresql.nuwax-rcoder-dev:5432/juicefs"
storage: "minio"
bucket: "http://minio-service.nuwax-rcoder-dev:9000/juicefs"
access-key: "minioadmin"
secret-key: "minioadmin"
# 兼容字段(保留给现有脚本/日志使用)
METAURL: "postgres://juicefs:juicefs_password@postgresql.nuwax-rcoder-dev:5432/juicefs"
MINIO_ACCESS_KEY: "minioadmin"
MINIO_SECRET_KEY: "minioadmin"
MINIO_ADDRESS: "minio-service.nuwax-rcoder-dev:9000"
# 其他配置
APPEND_FSYNC: "1"
CACHE_SIZE: "1024"

View File

@@ -0,0 +1,24 @@
# ============================================================
# JuiceFS StorageClass - Dev 环境专用
# 集群级资源独立命名,避免与 prod 冲突
# ============================================================
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: juicefs-sc-dev
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: csi.juicefs.com
parameters:
csi.storage.k8s.io/provisioner-secret-name: juicefs-secret
csi.storage.k8s.io/provisioner-secret-namespace: nuwax-rcoder-dev
csi.storage.k8s.io/controller-expand-secret-name: juicefs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: nuwax-rcoder-dev
csi.storage.k8s.io/node-publish-secret-name: juicefs-secret
csi.storage.k8s.io/node-publish-secret-namespace: nuwax-rcoder-dev
juicefs/controllerQuotaSet: "false"
juicefs/mountImage: "juicedata/mount:ce-v1.3.1"
juicefs/mountOptions: "cache-size=1024,allow-other"
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate

View File

@@ -0,0 +1,90 @@
# Dev environment overlay
# 使用方式: kubectl apply -k manifests/overlays/dev
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: nuwax-rcoder-dev
resources:
- ../../base
# dev 独立的集群级资源(避免与 prod 冲突)
- juicefs-storageclass.yaml
- clusterrolebinding.yaml
# dev 独立的 namespace 内资源
- rcoder-configmap.yaml
- credentials.yaml
- juicefs-secret.yaml
# 开发环境标签
# - includeSelectors 必须保持 false否则 environment label 会被注入到
# NetworkPolicy 的 egress podSelector误伤 K8s API Server 和动态创建的 Agent Runner Pod。
# - includeTemplates: true 让 Pod 模板也带上 environment label方便 kubectl 按环境筛选。
labels:
- pairs:
environment: dev
includeSelectors: false
includeTemplates: true
# 开发环境副本数
replicas:
- name: rcoder
count: 1
# 开发环境镜像 tag
images:
- name: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder
newName: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/nuwax-test/rcoder-k8s
newTag: latest
- name: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner
newName: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/nuwax-test/rcoder-computer-agent-runner
newTag: latest
patches:
# NodePort: 30080dev 专用)
- patch: |-
apiVersion: v1
kind: Service
metadata:
name: rcoder
spec:
ports:
- port: 8087
targetPort: 8087
nodePort: 30080
target:
kind: Service
name: rcoder
# PVC 指向 dev 专属 StorageClass
- patch: |-
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rcoder-workspace
spec:
storageClassName: juicefs-sc-dev
target:
kind: PersistentVolumeClaim
name: rcoder-workspace
# rcoder deployment 指向 dev 环境的 namespace 和 StorageClass
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: rcoder
spec:
template:
spec:
containers:
- name: rcoder
env:
- name: RCODER_K8S_NAMESPACE
value: nuwax-rcoder-dev
- name: RCODER_K8S_STORAGE_CLASS
value: juicefs-sc-dev
target:
kind: Deployment
name: rcoder

View File

@@ -0,0 +1,71 @@
# ============================================================
# RCoder ConfigMap - Dev 环境专用
# storage_class 指向 juicefs-sc-dev
# ============================================================
apiVersion: v1
kind: ConfigMap
metadata:
name: rcoder-config
data:
config.yml: |
# RCoder 配置文件
default_agent: "Claude"
projects_dir: "/app/project_workspace"
port: 8087
cleanup_config:
enabled: true
idle_timeout_seconds: 600
cleanup_interval_seconds: 300
docker_stop_timeout_seconds: 30
proxy_config:
listen_port: 8088
default_backend_port: 8087
backend_host: "127.0.0.1"
port_param: "port"
health_check:
enabled: true
interval_seconds: 5
timeout_seconds: 1
healthy_threshold: 2
unhealthy_threshold: 3
docker_config:
multi_image_config:
global_defaults:
registry_prefix: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev"
services:
rcoder:
service_type: "RCoder"
arm64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
amd64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
default_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
image_tag_prefix: "rcoder"
enabled: true
computer-agent-runner:
service_type: "ComputerAgentRunner"
arm64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
amd64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
default_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
image_tag_prefix: "rcoder-computer-agent-runner"
enabled: true
selection_strategy: "ServiceOnly"
cache_config:
enabled: true
ttl_seconds: 3600
max_entries: 50
network_base_name: "agent-network"
network_mode: "bridge"
work_dir: "/app"
auto_cleanup: true
container_ttl_seconds: 3600
api_key_auth:
enabled: false
api_key: "YOUR_API_KEY_HERE"
kubernetes_config:
storage_class: "juicefs-sc-dev"

View File

@@ -0,0 +1,14 @@
# ClusterRoleBinding - 本地测试环境
# 把 base 里共享的 ClusterRole 绑定到 local namespace 的 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: rcoder-pods-crb-local
subjects:
- kind: ServiceAccount
name: rcoder-pods-sa
namespace: rcoder-local
roleRef:
kind: ClusterRole
name: rcoder-pods-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,12 @@
# 存储层凭据 Secret - 本地测试环境
apiVersion: v1
kind: Secret
metadata:
name: rcoder-credentials
namespace: rcoder-local
type: Opaque
stringData:
POSTGRES_USER: "juicefs"
POSTGRES_PASSWORD: "juicefs_password"
MINIO_ROOT_USER: "minioadmin"
MINIO_ROOT_PASSWORD: "minioadmin"

View File

@@ -0,0 +1,91 @@
# Local overlay - OrbStack 本地测试
# 用法: kubectl apply -k k8s/manifests/overlays/local
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: rcoder-local
resources:
- ../../base
- clusterrolebinding.yaml
- credentials.yaml
- rcoder-configmap.yaml
labels:
- pairs:
environment: local
includeSelectors: false
includeTemplates: true
replicas:
- name: rcoder
count: 1
images:
- name: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder
newName: rcoder-local
newTag: latest
- name: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner
newName: rcoder-agent-runner-local
newTag: latest
patches:
# PVC 使用 local-pathOrbStack 默认 StorageClass
# local-path 只支持 ReadWriteOnce本地测试改为单节点读写
- patch: |-
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rcoder-workspace
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
target:
kind: PersistentVolumeClaim
name: rcoder-workspace
# Deployment 环境变量适配
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: rcoder
spec:
template:
spec:
containers:
- name: rcoder
env:
- name: RCODER_K8S_NAMESPACE
value: rcoder-local
- name: RCODER_K8S_STORAGE_CLASS
value: local-path
- name: RCODER_K8S_PVC_ACCESS_MODE
value: ReadWriteOnce
- name: RUST_LOG
value: "debug"
- name: RCODER_DOCKER_IMAGE
value: "rcoder-local:latest"
- name: RCODER_DOCKER_IMAGE_COMPUTER
value: "rcoder-agent-runner-local:latest"
target:
kind: Deployment
name: rcoder
# Service 使用 NodePort本地访问
- patch: |-
apiVersion: v1
kind: Service
metadata:
name: rcoder
spec:
type: NodePort
ports:
- port: 8087
targetPort: 8087
nodePort: 30087
target:
kind: Service
name: rcoder

View File

@@ -0,0 +1,50 @@
# RCoder ConfigMap - 本地测试环境
apiVersion: v1
kind: ConfigMap
metadata:
name: rcoder-config
data:
config.yml: |
default_agent: "Claude"
projects_dir: "/app/project_workspace"
port: 8087
cleanup_config:
enabled: true
idle_timeout_seconds: 600
cleanup_interval_seconds: 300
docker_stop_timeout_seconds: 30
docker_config:
multi_image_config:
global_defaults:
registry_prefix: ""
services:
rcoder:
service_type: "RCoder"
arm64_image: "rcoder-local:latest"
amd64_image: "rcoder-local:latest"
default_image: "rcoder-local:latest"
image_tag_prefix: "rcoder"
enabled: true
computer-agent-runner:
service_type: "ComputerAgentRunner"
arm64_image: "rcoder-agent-runner-local:latest"
amd64_image: "rcoder-agent-runner-local:latest"
default_image: "rcoder-agent-runner-local:latest"
image_tag_prefix: "rcoder-agent-runner"
enabled: true
selection_strategy: "ServiceOnly"
network_base_name: "agent-network"
network_mode: "bridge"
work_dir: "/app"
auto_cleanup: true
container_ttl_seconds: 3600
api_key_auth:
enabled: false
kubernetes_config:
storage_class: "local-path"

View File

@@ -0,0 +1,17 @@
# ============================================================
# ClusterRoleBinding - Prod 环境专用
# 把 base 里共享的 ClusterRole 绑定到 prod namespace 的 ServiceAccount
# 集群级资源独立命名,避免与 dev 冲突
# ============================================================
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: rcoder-pods-crb-prod
subjects:
- kind: ServiceAccount
name: rcoder-pods-sa
namespace: nuwax-rcoder-prod
roleRef:
kind: ClusterRole
name: rcoder-pods-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,16 @@
# ============================================================
# 存储层凭据 Secret - Prod 环境
# ⚠️ 上线前必须替换为真实强密码,并同步修改 juicefs-secret.yaml 的 metaurl / MINIO_ACCESS_KEY 等字段
# 推荐做法:不把真实密码提交到 git改用 SealedSecret / ExternalSecret / 部署时注入
# ============================================================
apiVersion: v1
kind: Secret
metadata:
name: rcoder-credentials
namespace: nuwax-rcoder-prod
type: Opaque
stringData:
POSTGRES_USER: "juicefs"
POSTGRES_PASSWORD: "prodPg2024"
MINIO_ROOT_USER: "minioadmin"
MINIO_ROOT_PASSWORD: "prodMinio2024"

View File

@@ -0,0 +1,29 @@
# ============================================================
# JuiceFS Secret - Prod 环境专用
# ⚠️ 上线前必须把 metaurl/access-key/secret-key/MINIO_* 的明文密码
# 替换为 credentials.yaml 中设置的真实密码,保持两处一致。
# ============================================================
apiVersion: v1
kind: Secret
metadata:
name: juicefs-secret
namespace: nuwax-rcoder-prod
type: Opaque
stringData:
# JuiceFS CE 必需字段(小写键名)
name: "rcoder-juicefs"
metaurl: "postgres://juicefs:prodPg2024@postgresql.nuwax-rcoder-prod:5432/juicefs"
storage: "minio"
bucket: "http://minio-service.nuwax-rcoder-prod:9000/juicefs"
access-key: "minioadmin"
secret-key: "prodMinio2024"
# 兼容字段(保留给现有脚本/日志使用)
METAURL: "postgres://juicefs:prodPg2024@postgresql.nuwax-rcoder-prod:5432/juicefs"
MINIO_ACCESS_KEY: "minioadmin"
MINIO_SECRET_KEY: "prodMinio2024"
MINIO_ADDRESS: "minio-service.nuwax-rcoder-prod:9000"
# 其他配置
APPEND_FSYNC: "1"
CACHE_SIZE: "1024"

View File

@@ -0,0 +1,24 @@
# ============================================================
# JuiceFS StorageClass - Prod 环境专用
# 集群级资源独立命名,避免与 dev 冲突
# ============================================================
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: juicefs-sc-prod
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: csi.juicefs.com
parameters:
csi.storage.k8s.io/provisioner-secret-name: juicefs-secret
csi.storage.k8s.io/provisioner-secret-namespace: nuwax-rcoder-prod
csi.storage.k8s.io/controller-expand-secret-name: juicefs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: nuwax-rcoder-prod
csi.storage.k8s.io/node-publish-secret-name: juicefs-secret
csi.storage.k8s.io/node-publish-secret-namespace: nuwax-rcoder-prod
juicefs/controllerQuotaSet: "false"
juicefs/mountImage: "juicedata/mount:ce-v1.3.1"
juicefs/mountOptions: "cache-size=1024,allow-other"
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate

View File

@@ -0,0 +1,87 @@
# Production environment overlay
# 使用方式: kubectl apply -k manifests/overlays/prod
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: nuwax-rcoder-prod
resources:
- ../../base
# prod 独立的集群级资源(避免与 dev 冲突)
- juicefs-storageclass.yaml
- clusterrolebinding.yaml
# prod 独立的 namespace 内资源
- rcoder-configmap.yaml
- credentials.yaml
- juicefs-secret.yaml
# 生产环境标签(含义同 dev 注释)
labels:
- pairs:
environment: production
includeSelectors: false
includeTemplates: true
# 生产环境副本数
replicas:
- name: rcoder
count: 2
# 生产环境镜像 tag
images:
- name: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder
newName: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/nuwax-test/rcoder-k8s
newTag: latest
- name: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner
newName: nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/nuwax-test/rcoder-computer-agent-runner
newTag: latest
patches:
# NodePort: 30081prod 专用,与 dev 30080 错开)
- patch: |-
apiVersion: v1
kind: Service
metadata:
name: rcoder
spec:
ports:
- port: 8087
targetPort: 8087
nodePort: 30081
target:
kind: Service
name: rcoder
# PVC 指向 prod 专属 StorageClass
- patch: |-
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rcoder-workspace
spec:
storageClassName: juicefs-sc-prod
target:
kind: PersistentVolumeClaim
name: rcoder-workspace
# rcoder deployment 指向 prod 环境的 namespace 和 StorageClass
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: rcoder
spec:
template:
spec:
containers:
- name: rcoder
env:
- name: RCODER_K8S_NAMESPACE
value: nuwax-rcoder-prod
- name: RCODER_K8S_STORAGE_CLASS
value: juicefs-sc-prod
target:
kind: Deployment
name: rcoder

View File

@@ -0,0 +1,71 @@
# ============================================================
# RCoder ConfigMap - Prod 环境专用
# storage_class 指向 juicefs-sc-prod
# ============================================================
apiVersion: v1
kind: ConfigMap
metadata:
name: rcoder-config
data:
config.yml: |
# RCoder 配置文件
default_agent: "Claude"
projects_dir: "/app/project_workspace"
port: 8087
cleanup_config:
enabled: true
idle_timeout_seconds: 600
cleanup_interval_seconds: 300
docker_stop_timeout_seconds: 30
proxy_config:
listen_port: 8088
default_backend_port: 8087
backend_host: "127.0.0.1"
port_param: "port"
health_check:
enabled: true
interval_seconds: 5
timeout_seconds: 1
healthy_threshold: 2
unhealthy_threshold: 3
docker_config:
multi_image_config:
global_defaults:
registry_prefix: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev"
services:
rcoder:
service_type: "RCoder"
arm64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
amd64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
default_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest"
image_tag_prefix: "rcoder"
enabled: true
computer-agent-runner:
service_type: "ComputerAgentRunner"
arm64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
amd64_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
default_image: "nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder-agent-runner:latest"
image_tag_prefix: "rcoder-computer-agent-runner"
enabled: true
selection_strategy: "ServiceOnly"
cache_config:
enabled: true
ttl_seconds: 3600
max_entries: 50
network_base_name: "agent-network"
network_mode: "bridge"
work_dir: "/app"
auto_cleanup: true
container_ttl_seconds: 3600
api_key_auth:
enabled: false
api_key: "YOUR_API_KEY_HERE"
kubernetes_config:
storage_class: "juicefs-sc-prod"