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

349 lines
7.7 KiB
Markdown
Raw Permalink 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.
# Kubernetes RBAC Configuration
**Date**: 2026-04-16
**Feature**: K8s Runtime Support
---
## 概述
RCoder 在 Kubernetes 环境中运行时,需要通过 kube-rs 库调用 K8s API Server 来动态创建和管理 Pod。
本文档提供完整的 RBAC 配置清单,确保 RCoder 有足够的权限来创建、查询和删除 Pod。
---
## 最小权限需求
| 资源 | 操作 | 用途 |
|------|------|------|
| pods | create | 创建 agent_runner Pod |
| pods | delete | 删除已完成的 Pod |
| pods | get | 查询 Pod 状态 |
| pods | list | 列出 Pod |
| pods | watch | 监听 Pod 状态变化 |
| pods/log | get | 查看 Pod 日志(可选) |
---
## 完整 RBAC 配置
### 方案一ClusterRole适用于所有 Namespace
```yaml
# rcoder-rbac.yaml
---
# 1. ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: rcoder-pods-sa
# 如果 rcoder 运行在特定 namespace修改这里
# namespace: rcoder
---
# 2. 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"]
---
# 3. ClusterRoleBinding绑定到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: rcoder-pods-clusterrolebinding
subjects:
# 如果在特定 namespace 使用 Role/RoleBinding改为 kind: ServiceAccount
- kind: ServiceAccount
name: rcoder-pods-sa
# apiGroup 固定
apiGroup: ""
roleRef:
kind: ClusterRole
name: rcoder-pods-clusterrole
apiGroup: rbac.authorization.k8s.io
```
### 方案二Role + RoleBinding限定 Namespace
适用于多租户环境,限制 RCoder 只能操作特定 namespace。
```yaml
# rcoder-rbac-namespaced.yaml
---
# 1. ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: rcoder-pods-sa
namespace: rcoder # 指定 namespace
---
# 2. Role权限定义
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: rcoder-pods-role
namespace: rcoder # 指定 namespace
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods/status"]
verbs: ["get"]
---
# 3. RoleBinding绑定到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rcoder-pods-rolebinding
namespace: rcoder # 指定 namespace
subjects:
- kind: ServiceAccount
name: rcoder-pods-sa
namespace: rcoder
roleRef:
kind: Role
name: rcoder-pods-role
apiGroup: rbac.authorization.k8s.io
```
---
## 部署步骤
### 1. 创建配置(使用 ClusterRole 方案)
```bash
# 应用 RBAC 配置
kubectl apply -f rcoder-rbac.yaml
# 验证 ServiceAccount 创建成功
kubectl get sa rcoder-pods-sa
# 验证 Role 创建成功
kubectl get clusterrole rcoder-pods-clusterrole
# 验证 RoleBinding 创建成功
kubectl get clusterrolebinding rcoder-pods-clusterrolebinding
```
### 2. 修改 RCoder Deployment
将 RCoder Pod 关联到 ServiceAccount
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: rcoder
namespace: default # 或你的 namespace
spec:
replicas: 1
selector:
matchLabels:
app: rcoder
template:
metadata:
labels:
app: rcoder
spec:
# 添加 ServiceAccount 配置
serviceAccountName: rcoder-pods-sa
containers:
- name: rcoder
image: registry.yichamao.com/rcoder:latest
ports:
- containerPort: 8087
env:
# 启用 K8s 运行时
- name: CONTAINER_RUNTIME
value: "kubernetes"
# 可选:指定 namespace默认使用 default
- name: RCODER_K8S_NAMESPACE
value: "default"
```
### 3. 验证权限
```bash
# 进入 RCoder Pod
kubectl exec -it <rcoder-pod-name> -- sh
# 测试 K8s API 访问权限
# 方法1使用 kubectl需要安装
kubectl auth can-i create pods --as=system:serviceaccount:default:rcoder-pods-sa
# 方法2直接测试 API
curl -k https://kubernetes.default.svc/api/v1/namespaces/default/pods \
--header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
```
---
## 故障排查
### 问题 1: Permission Denied
```
Error: Container creation failed: Failed to create pod: Unauthorized
```
**解决**: 检查 ServiceAccount 是否正确绑定到 Role/ClusterRole
```bash
# 检查 ServiceAccount
kubectl get sa rcoder-pods-sa -o yaml
# 检查 RoleBinding subjects
kubectl get rolebinding <rolebinding-name> -o yaml
```
### 问题 2: Cannot create Pods in other namespaces
**原因**: 使用了 RoleBinding 而不是 ClusterRoleBinding
**解决**: 如果需要跨 namespace 操作 Pod使用 ClusterRoleBinding
### 问题 3: Token 文件不存在
```
Error: K8s client init failed: No such file or directory: /var/run/secrets/kubernetes.io/serviceaccount/token
```
**原因**: 代码不在 Pod 内运行,或未配置 ServiceAccount
**解决**:
1. 确保 RCoder 部署在 K8s 集群内
2. 确保 Deployment 配置了 `serviceAccountName`
3. 检查是否挂载了 ServiceAccount token
```bash
# 检查 Pod 是否挂载了 token
kubectl exec <pod-name> -- ls -la /var/run/secrets/kubernetes.io/serviceaccount/
```
---
## 生产环境建议
### 1. 使用专用 namespace
```bash
# 创建独立 namespace
kubectl create namespace rcoder
```
### 2. 限制 Image Pull Secret如果使用私有仓库
```yaml
imagePullSecrets:
- name: regcred
```
### 3. NetworkPolicy可选
限制 Pod 网络通信:
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rcoder-pods-networkpolicy
namespace: rcoder
spec:
podSelector:
matchLabels:
app: rcoder
policyTypes:
- Ingress
- Egress
```
### 4. Resource Limits
为 RCoder Pod 设置资源限制:
```yaml
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
```
---
## 代码集成
### 启动时权限检查(建议添加)
`KubernetesRuntime::new()` 中添加权限验证:
```rust
pub async fn new(config: DockerManagerConfig) -> ContainerRuntimeResult<Self> {
let kube_config = Config::infer()
.await
.map_err(|e| ...)?;
let client = Client::try_from(kube_config)
.map_err(|e| ...)?;
// 验证权限:尝试列出 pods
let pods: Api<Pod> = Api::namespaced(client.clone(), &namespace);
pods.list(&ListParams::default().limit(1)).await
.map_err(|e| ContainerRuntimeError::K8sError(
format!("Permission denied or API server unreachable: {}", e)
))?;
// ... 继续初始化
}
```
### 环境变量配置
| 环境变量 | 默认值 | 说明 |
|----------|--------|------|
| `CONTAINER_RUNTIME` | `docker` | 运行时类型docker/kubernetes/k8s |
| `RCODER_K8S_NAMESPACE` | `default` | Pod 创建的 namespace |
| `RCODER_K8S_SERVICE_ACCOUNT` | `rcoder-pods-sa` | 使用的 ServiceAccount |
---
## 完整示例部署
参见下一节 "Helm Chart 或 Kustomize 清单"
---
## 相关文档
- [K8s RBAC 官方文档](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
- [kube-rs 认证文档](https://kube.rs/client/auth/)
- [ServiceAccount 配置](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)