Files
qiming/qiming-rcoder/specs/k8s-runtime-support/research.md
2026-06-01 13:54:52 +08:00

4.7 KiB
Raw Permalink Blame History

Research: Kubernetes Runtime Support

Date: 2026-04-16
Feature: K8s Runtime Support

Research 1: K8s Service DNS vs Pod IP

Decision

使用 K8s Service DNS 作为服务发现机制。

Rationale

  • Pod IP 不稳定: Pod 重启后 IP 会变化,直接使用 Pod IP 会导致 gRPC 通信失败
  • Service DNS 稳定: 即使 Pod 重启Service IP 保持不变ClusterIP Service
  • K8s 标准做法: 社区推荐使用 Service 进行服务发现

Alternatives Considered

方案 优点 缺点
Pod IP 简单直接 Pod 重启后失效
Headless Service 可直接解析 Pod IP 仍依赖 Pod DNS不稳定
Ingress 支持外部访问 增加复杂度,不需要
ExternalName Service 简单 不适合内部服务

Service DNS 格式

{service_name}.{namespace}.svc.cluster.local

对于 RCoder:

  • RCoder Pod: rcoder-agent-{project_id}.{namespace}.svc.cluster.local
  • ComputerAgent Pod: computer-agent-runner-{user_id}.{namespace}.svc.cluster.local

Implementation

fn pod_dns_name(project_id: &str, user_id: Option<&str>, namespace: &str) -> String {
    let prefix = match user_id {
        Some(uid) => format!("computer-agent-runner-{}", uid),
        None => format!("rcoder-agent-{}", project_id),
    };
    format!("{}.{}.svc.cluster.local", prefix, namespace)
}

Research 2: kube-rs 最佳实践

kube-rs 版本

当前使用: kube 0.98

推荐的 API 使用模式

1. Client 初始化

// 推荐:从 Config::infer() 自动检测 in-cluster vs local
let kube_config = Config::infer().await?;
let client = Client::try_from(kube_config)?;

2. API 访问模式

// 推荐:使用 Api::namespaced() 访问 namespaced 资源
let pods: Api<Pod> = Api::namespaced(client, &namespace);

// 使用 ListParams 过滤
let lp = ListParams::default().labels(&format!("project_id={}", project_id));
let pods = pods.list(&lp).await?;

3. 错误处理

match pods.get(&pod_name).await {
    Ok(pod) => { /* found */ }
    Err(kube::Error::Api(ae)) if ae.code == 404 => { /* not found */ }
    Err(e) => return Err(e),
}

Research 3: K8s 健康检查 (Readiness Probe)

问题

Docker 模式使用 HTTP 轮询检查服务健康:

async fn wait_for_service_ready(service_url: &str) {
    loop {
        if http::get(service_url).is_ok() {
            return Ok(());
        }
        sleep().await;
    }
}

K8s 模式应该使用 K8s 原生的 Readiness Probe 概念。

分析

  • K8s Readiness Probe: K8s 自动管理,决定 Pod 是否接收流量
  • 当前实现: 应用层轮询,与 K8s 概念不匹配

解决方案

仍然使用应用层健康检查(保持兼容性),但针对 K8s 环境优化:

  • 使用 DNS 解析代替 IP
  • 增加超时时间K8s Pod 启动通常需要 30-60s
  • 复用容器运行时层的健康检查接口

K8s Probe 配置(未来可能需要)

readinessProbe:
  httpGet:
    path: /health
    port: 8086
  initialDelaySeconds: 10
  periodSeconds: 5
  timeoutSeconds: 3
  failureThreshold: 3

Research 4: K8s 存储 (Workspace 处理)

问题

Docker 模式下使用 bind mount 共享文件系统:

volumes:
  - /host/path:/container/path

K8s 中如何处理?

分析

K8s 存储方案 适用场景 缺点
EmptyDir 临时存储 Pod 删除后数据丢失
HostPath 节点文件 安全性差,需要特权
PVC 持久存储 需要预先配置 StorageClass
NFS/CIFS 共享存储 需要外部存储服务
ConfigMap 配置文件 不适合大文件

RCoder 场景

RCoder 的 workspace 需要:

  1. 持久化(用户代码、项目文件)
  2. 跨容器共享rcoder 主容器和 agent_runner 容器)

解决方案

  • 开发环境: 使用 PVC with ReadWriteMany (如果存储支持)
  • 生产环境: 使用 NFS 或云存储
  • 简化方案: 对于 K8s 支持,暂时不处理 workspace 挂载(使用容器内置存储)

实现计划

Phase 1 中暂时跳过 workspace 存储问题,标记为 [NEEDS CLARIFICATION: workspace 存储策略]


Summary

Key Decisions

  1. Service DNS: 使用 {prefix}-{id}.{namespace}.svc.cluster.local
  2. kube-rs: 使用 Api::namespaced() + ListParams 过滤
  3. 健康检查: 保持应用层检查,增加超时
  4. 存储: 标记为待解决问题

Open Questions

  1. [NEEDS CLARIFICATION]: K8s 环境中 rcoder 主服务如何与 agent_runner Pod 通信?(同 namespace 直连?)
  2. [NEEDS CLARIFICATION]: workspace 存储使用 PVC 还是其他方案?
  3. [NEEDS CLARIFICATION]: K8s Service Account 和 RBAC 权限如何预配置?