Network Topology
This document describes the network architecture managed by TFRS Operator, including traffic ingress, routing mechanisms, mTLS, and tenant isolation.
Traffic Ingress Chainâ
External requests traverse the following chain to reach backend services:
Client
â
âŧ
Cloud LB (CLB / NodePort) â Determined by TFRCluster.spec.clusterType
â
âŧ
Istio Ingress Gateway (Port 80) â istio-ingress namespace
â
âŧ
Gateway CR (default-gateway) â Cluster-wide shared gateway
â
âŧ
VirtualService (cluster-routes) â Unified routing entry point
â
âŧ
EnvoyFilter (Cookie/QP â Header) â Extract tenant identifiers
â
âŧ
EnvoyFilter (Lua Dynamic Routing) â Dynamic routing to target service
â
âŧ
Backend Service â Service in tenant namespace
Gateway Architectureâ
TFRCluster creates a shared Istio Gateway through which all tenant traffic enters the cluster.
| Configuration | Default Value | Description |
|---|---|---|
| Gateway Name | default-gateway | Overridable via spec.ingress.gatewayRef |
| Gateway Namespace | istio-ingress | Istio Ingress Gateway namespace |
| Listen Port | 80 (HTTP) | TLS terminated by upstream CLB |
| Hosts | ["*"] | Restrictable via spec.ingress.hosts |
Cluster Type Adaptationâ
| Cluster Type | Ingress Method | Special Configuration |
|---|---|---|
tke | CLB (LoadBalancer) | Binds Tencent Cloud CLB via tkeClusterConfig.clbId |
kind | NodePort | Uses nodePortConfig for HTTP/HTTPS port mappings |
docker-desktop | NodePort | Same as Kind, adapted for Docker Desktop networking |
Cookie / QueryParam Routingâ
TFRCluster deploys two EnvoyFilters to implement dynamic routing based on cookies and query parameters.
Step 1: Tenant Identifier Extraction (EnvoyFilter envoy-filter-cookie)â
Extracts tenant identifiers from request cookies or URL query parameters and converts them to HTTP headers:
Cookie Source:
| Cookie Name | Mapped Header | Default Cookie Key | Description |
|---|---|---|---|
tfNamespace | X-TF-Namespace | Configurable via spec.routing.cookieNames | Target tenant namespace |
tfRobotId | X-TF-RobotId | Configurable via spec.routing.cookieNames | Target robot instance ID |
QueryParam Source:
| QueryParam | Mapped Header | Description |
|---|---|---|
namespace | X-TF-Namespace | Target tenant namespace |
rid | X-TF-RobotId | Target robot instance ID |
Priority: When both cookie and query parameter are present, the query parameter takes precedence. For example,
/v1/login?namespace=tenant-a&rid=robot-1overrides the corresponding cookie values.
Step 2: Lua Dynamic Routing (EnvoyFilter lua-dynamic-routing)â
Dynamically selects backend services based on request path and headers:
| Request Path | Required Headers | Routing Target |
|---|---|---|
/v1/login | X-TF-Namespace | tfrobot-http.{namespace}:80 (regardless of rid) |
/socket.io/ | X-TF-Namespace + X-TF-RobotId | tf-robot-{robotId}.{namespace}:8080 |
/socket.io/ (missing rid) | X-TF-Namespace | Returns 400 JSON error response |
| Other paths | X-TF-Namespace | tfrobot-http.{namespace}:80 |
| Missing routing info | â | Returns 401 JSON error response |
VirtualService Header Processingâ
The cluster-level VirtualService cluster-routes also performs the following:
- X-Real-IP injection: Writes the client's real IP into the
X-Real-IPheader - X-Forwarded-Host injection: Preserves the original request Host
- Underscore header support: Allows header names containing underscores via Istio mesh config
Tenant Network Isolationâ
Each TFRTenant namespace achieves network isolation through the following Istio policies:
PeerAuthentication (mTLS)â
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: {tenant-namespace}
spec:
mtls:
mode: STRICT
All service communication within the namespace is forced to use mTLS, preventing unencrypted traffic.
AuthorizationPolicyâ
Restricts traffic to the tenant namespace to only the following sources:
| Source | Description |
|---|---|
istio-ingress | External traffic forwarded by the Ingress Gateway |
| Same namespace | Intra-namespace service communication |
spec.extraAllowedNamespaces | Additional allowed namespaces (e.g., Prometheus namespace) |
DestinationRuleâ
Configures client-side mTLS mode to ensure all inter-service communication within the namespace is encrypted:
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
Service DNS Patternsâ
Key services within tenant namespaces follow these DNS naming patterns:
| Service | DNS Pattern | Port | Description |
|---|---|---|---|
| TFRobot API | tfrobot-http.{ns}.svc.cluster.local | 80 | Unified API service entry |
| TFRobot Instance | tf-robot-{robotId}.{ns}.svc.cluster.local | 8080 | Individual robot instance (Socket.IO) |
| PostgreSQL | {ns}-pg-rw.{ns}.svc.cluster.local | 5432 | CNPG read-write endpoint |
| Redis | redis.{ns}.svc.cluster.local | 6379 | Redis cache |
| MinIO | minio.{ns}.svc.cluster.local | 9000 | Object storage API |
| RabbitMQ | rabbitmq.{ns}.svc.cluster.local | 5672 | AMQP message queue |
| Jaeger | jaeger-collector.{ns}.svc.cluster.local | 4317 | OTLP gRPC endpoint |
| Grafana | grafana.{ns}.svc.cluster.local | 3000 | Monitoring dashboard |
Network Topology Overviewâ
graph TB
subgraph External
Client[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[Tenant Namespace 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[Tenant Namespace 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