diff --git a/k8s_manager.py b/k8s_manager.py index 092c9f1..d9560e6 100644 --- a/k8s_manager.py +++ b/k8s_manager.py @@ -390,27 +390,9 @@ IP.1 = 127.0.0.1 ) ingress_rules.append(ingress_rule_with_host) - # 同时添加不带 host 的规则(允许通过 IP 直接访问) - # 注意:使用 agent_name 作为路径前缀,避免与其他 Ingress 冲突 - # 这对于 openclaw 很重要,因为 DNS 可能还未配置 - if host and service_name: - # 从 service_name 提取 agent_name(格式:{agent_name}-service) - agent_name_from_service = service_name.replace("-service", "") - no_host_path = client.V1HTTPIngressPath( - path=f"/{agent_name_from_service}", - path_type="Prefix", - backend=client.V1IngressBackend( - service=client.V1IngressServiceBackend( - name=service_name, - port=client.V1ServiceBackendPort(number=service_port) - ) - ) - ) - # 不带 host 的规则:同时支持根路径和带 agent 名称的路径 - ingress_rule_no_host = client.V1IngressRule( - http=client.V1HTTPIngressRuleValue(paths=[http_ingress_path, no_host_path]) - ) - ingress_rules.append(ingress_rule_no_host) + # 注意:不再添加不带 host 的规则,避免多个 Ingress 之间的路径冲突 + # 每个 agent 应该通过自己的域名访问,而不是通过 IP + 路径 + # 如果需要通过 IP 访问,应该使用不同的路径前缀,但这会导致 nginx ingress 验证失败 # 构建 Ingress 注解 annotations = { @@ -1648,6 +1630,9 @@ IP.1 = 127.0.0.1 "mode": "token", "token": "${GATEWAY_AUTH_TOKEN}" }, + "controlUi": { + "dangerouslyDisableDeviceAuth": True # 禁用设备认证,避免 "pairing required" 错误 + }, "http": { "endpoints": { "chatCompletions": {"enabled": True} @@ -1970,6 +1955,34 @@ echo "Config initialized successfully" ) init_containers.append(config_init_container) + # Init Container 2: 初始化 identity volume 权限 + # 由于 gateway 容器需要创建 identity 目录,使用 emptyDir volume 避免权限问题 + # 在 initContainer 中预先创建并设置正确的权限 + permission_fix_container = client.V1Container( + name="permission-fix", + image="busybox:1.36", + command=["sh", "-c", """ +echo "=== Initializing identity volume permissions ===" +# 创建 identity 目录并设置正确的权限(emptyDir volume) +mkdir -p /identity +chown -R 1000:1000 /identity +chmod -R 755 /identity +ls -la /identity/ 2>/dev/null || echo "Directory check completed" +echo "Identity volume initialized successfully" +"""], + security_context=client.V1SecurityContext( + run_as_user=0, # 以 root 运行 + run_as_group=0 + ), + volume_mounts=[ + client.V1VolumeMount( + name="identity", + mount_path="/identity" + ), + ] + ) + init_containers.append(permission_fix_container) + # Gateway Container gateway_container = client.V1Container( name="gateway", @@ -2029,6 +2042,11 @@ echo "Config initialized successfully" mount_path="/home/node/.openclaw/devices", sub_path="devices" ), + # 添加 identity volume 挂载,用于存储设备身份信息 + client.V1VolumeMount( + name="identity", + mount_path="/home/node/.openclaw/identity" + ), ], command=["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789"], resources=gateway_resources, @@ -2105,6 +2123,8 @@ echo "Config initialized successfully" persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(claim_name=pvc_name) ), client.V1Volume(name="docker-storage", empty_dir=client.V1EmptyDirVolumeSource()), + # Identity volume: 用于存储设备身份信息,使用 emptyDir 避免权限问题 + client.V1Volume(name="identity", empty_dir=client.V1EmptyDirVolumeSource()), # Docker config 从 secret 挂载,用于 DinD ACR 认证 client.V1Volume( name="docker-config",