跳到主要内容
版本:0.3.0-dev0

网络拓扑

本文档描述 TFRS Operator 管理的网络架构,包括流量入口、路由机制、mTLS 和租户隔离。

流量入口链路

外部请求经过以下链路到达后端服务:

客户端


Cloud LB (CLB / NodePort) ← TFRCluster.spec.clusterType 决定


Istio Ingress Gateway (Port 80) ← istio-ingress namespace


Gateway CR (default-gateway) ← 集群统一网关


VirtualService (cluster-routes) ← 统一路由入口


EnvoyFilter (Cookie/QP → Header) ← 提取租户标识


EnvoyFilter (Lua Dynamic Routing) ← 动态路由到目标服务


Backend Service ← 租户命名空间内的服务

Gateway 架构

TFRCluster 创建一个共享的 Istio Gateway,所有租户流量通过此网关进入集群。

配置项默认值说明
Gateway 名称default-gateway可通过 spec.ingress.gatewayRef 覆盖
Gateway 命名空间istio-ingressIstio Ingress Gateway 所在命名空间
监听端口80 (HTTP)TLS 由上游 CLB 终结
Hosts["*"]可通过 spec.ingress.hosts 限制

集群类型适配

集群类型入口方式特殊配置
tkeCLB (LoadBalancer)通过 tkeClusterConfig.clbId 绑定腾讯云 CLB
kindNodePort使用 nodePortConfig 指定 HTTP/HTTPS 端口映射
docker-desktopNodePort同 Kind,适配 Docker Desktop 网络

TFRCluster 部署两个 EnvoyFilter 实现基于 Cookie 和 QueryParam 的动态路由。

从请求 Cookie 或 URL QueryParam 中提取租户标识,转换为 HTTP Header:

Cookie 来源:

Cookie 名称映射 Header默认 Cookie Key说明
tfNamespaceX-TF-Namespace可通过 spec.routing.cookieNames 配置目标租户命名空间
tfRobotIdX-TF-RobotId可通过 spec.routing.cookieNames 配置目标机器人实例 ID

QueryParam 来源:

QueryParam映射 Header说明
namespaceX-TF-Namespace目标租户命名空间
ridX-TF-RobotId目标机器人实例 ID

优先级: 当 Cookie 和 QueryParam 同时存在时,QueryParam 优先。例如 /v1/login?namespace=tenant-a&rid=robot-1 会覆盖 Cookie 中的对应值。

第二步:Lua 动态路由(EnvoyFilter lua-dynamic-routing

根据请求路径和 Header 动态选择后端服务:

请求路径所需 Header路由目标
/v1/loginX-TF-Namespacetfrobot-http.{namespace}:80(无论是否有 rid)
/socket.io/X-TF-Namespace + X-TF-RobotIdtf-robot-{robotId}.{namespace}:8080
/socket.io/(缺少 rid)X-TF-Namespace返回 400 JSON 错误响应
其他路径X-TF-Namespacetfrobot-http.{namespace}:80
缺少路由信息返回 401 JSON 错误响应

VirtualService 请求头处理

集群级 VirtualService cluster-routes 还执行以下操作:

  • X-Real-IP 注入:将客户端真实 IP 写入 X-Real-IP Header
  • X-Forwarded-Host 注入:保留原始请求 Host
  • Underscore Header 支持:通过 Istio mesh config 允许包含下划线的 Header 名称

租户网络隔离

每个 TFRTenant 命名空间通过以下 Istio 策略实现网络隔离:

PeerAuthentication(mTLS)

apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: {tenant-namespace}
spec:
mtls:
mode: STRICT

所有命名空间内的服务通信强制使用 mTLS,防止未加密流量。

AuthorizationPolicy

限制仅允许以下来源的流量进入租户命名空间:

来源说明
istio-ingressIngress Gateway 转发的外部流量
本命名空间命名空间内服务间通信
spec.extraAllowedNamespaces额外允许的命名空间(如 Prometheus 所在命名空间)

DestinationRule

配置客户端 mTLS 模式,确保命名空间内所有服务间通信加密:

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: default
namespace: {tenant-namespace}
spec:
host: "*.{tenant-namespace}.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL

服务 DNS 模式

租户命名空间内的关键服务遵循以下 DNS 命名模式:

服务DNS 模式端口说明
TFRobot APItfrobot-http.{ns}.svc.cluster.local80API 服务统一入口
TFRobot 实例tf-robot-{robotId}.{ns}.svc.cluster.local8080单个机器人实例(Socket.IO)
PostgreSQL{ns}-pg-rw.{ns}.svc.cluster.local5432CNPG 读写端点
Redisredis.{ns}.svc.cluster.local6379Redis 缓存
MinIOminio.{ns}.svc.cluster.local9000对象存储 API
RabbitMQrabbitmq.{ns}.svc.cluster.local5672AMQP 消息队列
Jaegerjaeger-collector.{ns}.svc.cluster.local4317OTLP gRPC 端点
Grafanagrafana.{ns}.svc.cluster.local3000监控仪表盘

网络拓扑总览

graph TB
subgraph External
Client[客户端]
CLB[Cloud LB]
end

subgraph istio-ingress
IGW[Istio Ingress Gateway]
GW[Gateway CR]
VS[VirtualService]
EFC[EnvoyFilter Cookie]
EFL[EnvoyFilter Lua]
end

subgraph tenant-ns-1[租户命名空间 A]
PA1[PeerAuthentication STRICT]
AP1[AuthorizationPolicy]
API1[TFRobot API :80]
BOT1[tf-robot-1 :8080]
PG1[PostgreSQL :5432]
RD1[Redis :6379]
MN1[MinIO :9000]
RQ1[RabbitMQ :5672]
end

subgraph tenant-ns-2[租户命名空间 B]
PA2[PeerAuthentication STRICT]
AP2[AuthorizationPolicy]
API2[TFRobot API :80]
BOT2[tf-robot-2 :8080]
PG2[PostgreSQL :5432]
end

Client --> CLB --> IGW
IGW --> GW --> VS
VS --> EFC --> EFL
EFL -->|X-TF-Namespace=A| API1
EFL -->|X-TF-Namespace=A, X-TF-RobotId=1| BOT1
EFL -->|X-TF-Namespace=B| API2

API1 -.->|mTLS| PG1
API1 -.->|mTLS| RD1
API1 -.->|mTLS| MN1
API1 -.->|mTLS| RQ1