Agent Runtime 为 Agent 集群配置默认拒绝的 Agent 网络

为 Agent 配置默认拒绝的网络,仅允许访问指定模型和工具 API,减少误访问内部服务及数据外传的风险。本例创建一个 Cube Pod,只允许它向指定域名发送 /v1/ 下的 GET 请求,并验证其他方法和路径被拒绝。

相关产品
Agent Runtime 产品页,含版本规格、价格与购买入口。

一、功能说明

ZeroProxy 根据 Pod 标签选择访问策略,默认拒绝未授权的业务请求,集群 DNS 单独放行。应用沿用原地址,无需设置 HTTP_PROXY。

ZeroProxy 随集群默认安装。使用时,仍需配置命名空间标签和 Pod 注解;已有 Pod 需重建。

配置 作用
命名空间标签 zeroproxy.io/managed=true 对该命名空间启用准入管理,未声明注入的新 Pod 会被拒绝
Pod 注解 zeroproxy.io/inject: "true" 创建 Pod 时注入网络代理
Pod 标签与 ZeroProxyPolicy 选择该任务可以访问的目标和接口

默认拒绝主要约束 Agent 主动发起的业务访问,Cube 负责沙箱运行环境隔离,ZeroProxy 负责这篇的业务网络访问控制。

二、开始前准备

1. 已 创建 Agent 集群和节点池,Cube 节点就绪,使用 Linux amd64、Kubernetes 1.29 及以上,并启用原生 Sidecar。示例参考 Chart 0.4.7,其他版本需核对策略字段。

2. 确认 ZeroProxy Controller 和 Webhook 就绪;两个 Webhook 副本需要至少两个可调度节点。

3. 准备独立测试命名空间和可查看日志的 HTTP 服务,先确认服务能正常响应 GET /v1/ping。

4. 将示例域名 api.example.com、IPv4 地址 203.0.113.10/32 和端口替换为实际值。HTTP 测试不要携带敏感数据;HTTPS 配置见后文。

5. 通过 访问配置 连接目标集群。需要管理测试命名空间、策略和 Pod,以及查看日志、执行容器命令的权限。

由管理员检查 platformDenyCIDRs,确认已包含需要禁止访问的内部网段。

可以通过以下只读命令检查组件:

kubectl get crd zeroproxypolicies.zeroproxy.iokubectl get deployment -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,IMAGES:.spec.template.spec.containers[*].image'kubectl get runtimeclass cube

找到 ZeroProxy Controller 和 Webhook 的名称及命名空间,例如 kube-system。查不到时,检查集群连接和查询权限。

将查询到的名称填入下面的命令。如果两个组件不在同一命名空间,分别查询。

export ZEROPROXY_NAMESPACE='<实际命名空间>'export ZEROPROXY_CONTROLLER='<Controller Deployment 名称>'export ZEROPROXY_WEBHOOK='<Webhook Deployment 名称>'kubectl -n "$ZEROPROXY_NAMESPACE" get deployment "$ZEROPROXY_CONTROLLER" "$ZEROPROXY_WEBHOOK"

开始测试前记录组件的实际镜像与策略字段:

kubectl -n "$ZEROPROXY_NAMESPACE" get deployment "$ZEROPROXY_CONTROLLER" "$ZEROPROXY_WEBHOOK" -o jsonkubectl explain zeroproxypolicy.spec –api-version=zeroproxy.io/v1alpha1

核对 configTOML、network.allowTCP,以及后文使用的 network.infrastructureTCP、caSecretRef。字段有差异时按组件版本调整;Chart 与镜像版本号不可直接比较。

三、第一步:准备默认拒绝的命名空间

在目标集群控制台的 YAML 创建入口提交以下资源。控制台跳转至关联 TKE 集群时,先核对集群 ID。

apiVersion: v1kind: Namespacemetadata: name: agent-network-demo labels: zeroproxy.io/managed: "true"

先不创建访问策略,以验证默认拒绝。请使用新命名空间,避免影响现有业务:旧 Pod 不会自动注入代理,未声明注入的新 Pod 会被拒绝创建。

四、第二步:创建使用 Cube 和网络代理的 Pod

在控制台通过 YAML 创建以下 Pod。测试镜像需能从节点拉取;若使用私有镜像仓库,在该命名空间准备镜像拉取凭证并添加 imagePullSecrets。

apiVersion: v1kind: Podmetadata: name: agent-network-demo namespace: agent-network-demo labels: app: agent-network-demo tenant: demo annotations: zeroproxy.io/inject: "true"spec: runtimeClassName: cube automountServiceAccountToken: false dnsPolicy: ClusterFirst nodeSelector: kubernetes.io/arch: amd64 securityContext: runAsNonRoot: true runAsUser: 1000 containers: – name: app image: curlimages/curl:8.10.1 command: ["sh", "-c", "sleep 3600"] securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] resources: requests: cpu: 10m memory: 32Mi limits: cpu: 100m memory: 64Mi

接入自己的 Agent 时,替换镜像、命令和资源规格。使用 Deployment 时,标签和注解放在 spec.template.metadata,运行时与安全配置放在 spec.template.spec。

在 initContainers 中确认代理 zeroproxy-sidecar 的 restartPolicy 为 Always:

kubectl -n agent-network-demo get pod agent-network-demo -o yamlkubectl -n agent-network-demo exec agent-network-demo -c zeroproxy-sidecar — zeroproxy-sidecar status

确认代理 ready=true、error=null,且 desiredRevision 与 loadedRevision 一致。Pod 就绪不代表目标已放行。

先从业务容器访问已确认可用的测试目标:

kubectl -n agent-network-demo exec agent-network-demo -c app — \\ curl -i –connect-timeout 5 –max-time 10 http://api.example.com/v1/ping

预期请求被拒绝。保留响应、代理和目标日志,供放行后对比;连接失败本身不能证明策略生效。

五、第三步:只放行需要的接口

在控制台的自定义资源 YAML 创建入口提交以下 ZeroProxyPolicy,将域名和 IP 替换为准备好的实际值:

apiVersion: zeroproxy.io/v1alpha1kind: ZeroProxyPolicymetadata: name: allow-agent-tool namespace: agent-network-demospec: podSelector: matchLabels: app: agent-network-demo tenant: demo configTOML: | [[policies.sources]] source = "inline" default_decision = "deny" [[policies.sources.rules]] name = "allow-tool-read" priority = 100 decision = "allow" resources = [{ hosts = ["api.example.com"], ports = [80], path_prefix = "/v1/" }] methods = ["GET"] network: allowTCP: – cidr: 203.0.113.10/32 ports: [80]

allowTCP 放行目标 IP 和端口,configTOML 限定域名、GET 方法及 /v1/ 路径前缀,必须同时满足。

目标位于平台禁止的内部网段时,由管理员确认后,在 spec.network 下增加与 allowTCP 同级的 infrastructureTCP。只填写受信目标的单个 IPv4 地址和端口,不放行整个网段。

infrastructureTCP: – cidr: REPLACE_WITH_TRUSTED_SERVICE_IPV4/32 ports: [8080]

域名、方法和路径限制仍生效。普通公网目标无需此项。

域名对应多个 IPv4 地址时逐项配置,地址变化后更新 allowTCP;当前不会自动更新 IP 白名单。

策略与 Pod 放在同一命名空间,标签须全部匹配。每个 Pod 仅匹配一份策略;无匹配或匹配多份都会关闭业务出口。

六、访问集群内的 Service

访问集群内 Service 时,除 ZeroProxy 规则外,还要检查 NetworkPolicy。前者控制域名、方法和路径,后者控制 Pod 之间的连接,两者独立生效。

先检查两端策略、Service 后端和代理日志:

kubectl -n agent-network-demo get networkpolicykubectl -n '<目标服务命名空间>' get networkpolicykubectl -n '<目标服务命名空间>' get service '<Service 名称>' -o yamlkubectl -n '<目标服务命名空间>' get pods –show-labelskubectl -n '<目标服务命名空间>' get endpointslices \\ -l kubernetes.io/service-name='<Service 名称>' -o widekubectl -n agent-network-demo logs agent-network-demo -c zeroproxy-sidecar –tail=100

以下示例访问 agent-tools 中标签为 app: tool-api、监听 TCP 8080 的后端。请按实际服务替换命名空间、标签和端口,并核对 Service 选择器及 ZeroProxy 的目标配置。

客户端受出站隔离时,添加以下授权:

apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-agent-tool-egress namespace: agent-network-demospec: podSelector: matchLabels: app: agent-network-demo tenant: demo policyTypes: [Egress] egress: – to: – namespaceSelector: matchLabels: kubernetes.io/metadata.name: agent-tools podSelector: matchLabels: app: tool-api ports: – protocol: TCP port: 8080

两个选择器须放在同一项中,限定目标命名空间及 Pod 标签。后端重建后,只要标签和端口不变,无需修改规则。

添加 Egress 策略会隔离选中 Pod 的出站流量。保留业务所需授权,尤其是 DNS;ZeroProxy 的 DNS 放行不能替代 NetworkPolicy 授权。

下面的 DNS 规则适用于 kube-system 中标签为 k8s-app: kube-dns 的 CoreDNS。先用 kubectl -n kube-system get pods -l k8s-app=kube-dns –show-labels 确认。使用 NodeLocal DNS 或其他部署方式时,由管理员按实际流量路径配置。

apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-agent-dns namespace: agent-network-demospec: podSelector: matchLabels: app: agent-network-demo tenant: demo policyTypes: [Egress] egress: – to: – namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: – protocol: UDP port: 53 – protocol: TCP port: 53

如果服务端也受入站隔离,在 agent-tools 命名空间添加对应的入站规则:

apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-agent-tool-ingress namespace: agent-toolsspec: podSelector: matchLabels: app: tool-api policyTypes: [Ingress] ingress: – from: – namespaceSelector: matchLabels: kubernetes.io/metadata.name: agent-network-demo podSelector: matchLabels: app: agent-network-demo tenant: demo ports: – protocol: TCP port: 8080

服务端没有入站隔离时,无需添加此规则,以免影响其他调用方。NetworkPolicy 的允许规则会叠加,不会撤销已有权限或覆盖其他平台安全策略;由管理员确认后提交。更多说明见 Kubernetes NetworkPolicy。

配置完成后,按第四步验证允许、拒绝和撤销后的请求。连接失败时,按文末“常见问题”排查。

七、第四步:验证允许和拒绝都生效

策略保存后,等待代理加载对应版本:

kubectl -n agent-network-demo get pod agent-network-demo \\ -o jsonpath='{.metadata.annotations.zeroproxy\\.io/desired-revision}{"\\n"}'kubectl -n agent-network-demo exec agent-network-demo -c zeroproxy-sidecar — zeroproxy-sidecar status

等待 loadedRevision 与 Pod 注解版本一致,且 ready=true、error=null,再发起请求。

# 允许:指定域名、GET 方法和 /v1/ 路径kubectl -n agent-network-demo exec agent-network-demo -c app — \\ curl -i –connect-timeout 5 –max-time 10 http://api.example.com/v1/ping# 拒绝:方法不匹配kubectl -n agent-network-demo exec agent-network-demo -c app — \\ curl -i –connect-timeout 5 –max-time 10 -X POST http://api.example.com/v1/ping# 拒绝:路径不匹配kubectl -n agent-network-demo exec agent-network-demo -c app — \\ curl -i –connect-timeout 5 –max-time 10 http://api.example.com/admin/

检查项 预期结果 核对方式
放行前访问测试目标 被拒绝 代理处于默认拒绝状态,目标服务未收到请求
放行后 GET /v1/ping 收到目标应用的正常响应 核对状态码、响应内容和服务端访问日志
POST /v1/ping 代理返回 HTTP 403 目标服务未收到该请求
GET /admin/ 代理返回 HTTP 403 目标服务未收到该请求

检查 HTTP 状态码,不能只看 curl 退出码。超时、DNS 错误或 502 按文末方法排查;403 需结合代理拒绝原因及目标日志确认。

八、接入真实 Agent

·模型、知识库等 HTTPS 服务:仅把端口改为 443 不够。代理检查加密请求时需要管理员配置签发证书使用的 CA,并在策略中设置 caSecretRef。业务容器需要信任代理 CA;不得使用 –insecure 绕过验证。证书固定或独立 truststore 的客户端需单独适配。

·模型接口使用 POST:按真实接口配置方法和路径,例如模型服务所需的 POST 路径;不要直接照搬本例的只读 GET 策略。请求体条件不在当前支持范围内。

·多租户任务:不同租户使用独立命名空间及相应的 Kubernetes 权限。标签用于选择策略,不能代替租户权限隔离。策略、标签绑定和业务凭证由管理员管理。

·已有 Agent:修改工作负载模板后滚动重建,逐个确认代理已注入并加载策略。仅修改命名空间标签不会接管已有 Pod。

HTTPS 接入时,由管理员在业务命名空间创建含 ca.pem、ca-key.pem 的专用 Secret,并将其名称填入策略的 spec.caSecretRef;请求规则和 allowTCP 都需包含 443 端口。组件将公共 CA 放到业务容器的 /etc/zeroproxy-trust/ca.pem,并注入 SSL_CERT_FILE、REQUESTS_CA_BUNDLE、NODE_EXTRA_CA_CERTS。CA 私钥仅供代理使用,业务容器不得挂载该 Secret。使用 curl 验证时添加 –cacert /etc/zeroproxy-trust/ca.pem,并重复允许与拒绝两类请求检查。

九、一次实测结果

使用 ZeroProxy 0.4.10、Cube 客户端和独立 HTTP Service 验证,服务监听 TCP 8080。

配置或操作 实测结果
未配置代理允许规则 GET 返回 403,代理记录默认拒绝
代理允许,但服务端入站未授权 GET 返回 502
补齐后端连接和 DNS 授权 GET /v1/ping 返回 200,POST 和 /admin/ 返回 403
后端 Pod 重建、IP 改变 保留标签和端口,未修改规则,GET 仍返回 200
撤销代理允许规则 GET 恢复为 403

每次变更均确认代理加载版本一致后再发起请求。漏配 DNS 时,代理记录过上游域名解析失败;客户端的 curl –resolve 不能代替代理的 DNS 授权。

本次验证覆盖 HTTP 与标签选择器,未覆盖 HTTPS、其他网络插件和所有 DNS 部署。测试资源已清理,原有集群策略保留。

赞 (0)
上一篇 4天前
下一篇 4天前