7.7 KiB
7.7 KiB
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)
# 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。
# 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 方案)
# 应用 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:
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. 验证权限
# 进入 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
# 检查 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
解决:
- 确保 RCoder 部署在 K8s 集群内
- 确保 Deployment 配置了
serviceAccountName - 检查是否挂载了 ServiceAccount token
# 检查 Pod 是否挂载了 token
kubectl exec <pod-name> -- ls -la /var/run/secrets/kubernetes.io/serviceaccount/
生产环境建议
1. 使用专用 namespace
# 创建独立 namespace
kubectl create namespace rcoder
2. 限制 Image Pull Secret(如果使用私有仓库)
imagePullSecrets:
- name: regcred
3. NetworkPolicy(可选)
限制 Pod 网络通信:
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 设置资源限制:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
代码集成
启动时权限检查(建议添加)
在 KubernetesRuntime::new() 中添加权限验证:
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 清单"