Skip to content

Commit 50ee250

Browse files
committed
Update README to clarify STATIC_BACKENDS format and enhance Kubernetes service discovery section
1 parent 0f6de58 commit 50ee250

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

README.md

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ go build -o xdatabase-proxy cmd/proxy/main.go
9090
| Variable | Description | Required | Default | Example Value | When to Use |
9191
| ---------------- | -------------------------------------------------------------------------------------- | -------- | ------------ | --------------------------------------- | ----------- |
9292
| DISCOVERY_MODE | Discovery strategy: `kubernetes` or `static` | No | kubernetes | static | Auto-set to `static` if `STATIC_BACKENDS` is provided |
93-
| STATIC_BACKENDS | Static backend configuration (JSON array) | Conditional | - | [{"name":"db1","host":"10.0.1.5","port":5432}] | **Required** when not using Kubernetes discovery |
93+
| STATIC_BACKENDS | Static backend mapping (`deployment_id[.pool]=host:port` comma-separated) | Conditional | - | db1=10.0.1.5:5432,db1.pool=10.0.1.5:6432 | **Required** when not using Kubernetes discovery |
9494
| KUBECONFIG | Path to kubeconfig file | Conditional | ~/.kube/config | /path/to/config | **Required** when `DISCOVERY_MODE=kubernetes` AND running outside cluster (VM/Container) |
9595
| KUBE_CONTEXT | Kubernetes context name | No | - | production-cluster | Use for multi-cluster setups with kubeconfig |
9696

@@ -104,11 +104,16 @@ go build -o xdatabase-proxy cmd/proxy/main.go
104104
**Configuration Rules:**
105105
-**In Kubernetes Pod**: `DISCOVERY_MODE=kubernetes` (default, uses in-cluster config)
106106
-**VM/Container → Remote K8s**: `DISCOVERY_MODE=kubernetes` + `KUBECONFIG=/path/to/config`
107-
-**Static Backends**: `STATIC_BACKENDS='[...]'` (auto-sets `DISCOVERY_MODE=static`)
107+
-**Static Backends**: `STATIC_BACKENDS='db1=host:5432,db1.pool=host:6432'` (auto-sets `DISCOVERY_MODE=static`)
108108
- ⚠️ **Cannot mix**: Cannot use both `STATIC_BACKENDS` and `DISCOVERY_MODE=kubernetes` at same time
109109
- ⚠️ **KUBECONFIG required**: If `DISCOVERY_MODE=kubernetes` + not in cluster → must provide `KUBECONFIG`
110110
- ⚠️ **NAMESPACE required**: If `DISCOVERY_MODE=kubernetes` → must provide `NAMESPACE`
111111

112+
**Static Backends Format:**
113+
- `deployment_id=host:port` → direct connections
114+
- `deployment_id.pool=host:port` → pooled connections (optional)
115+
- Multiple entries comma-separated, e.g. `db1=10.0.1.5:5432,db1.pool=10.0.1.5:6432`
116+
112117
#### TLS/SSL Configuration
113118

114119
| Variable | Description | Required | Default | Example Value | When to Use |
@@ -162,17 +167,42 @@ go build -o xdatabase-proxy cmd/proxy/main.go
162167
| TLS_ENABLE_SELF_SIGNED | TLS_AUTO_GENERATE |
163168
| POD_NAMESPACE | NAMESPACE |
164169

165-
### Kubernetes Labels
170+
### Kubernetes Service Discovery
171+
172+
Labels act as a **composite index** for service discovery. Proxy uses `(xdatabase-proxy-deployment-id, xdatabase-proxy-database-type, xdatabase-proxy-pooled)` as the lookup key.
173+
174+
**Label Matching Strategy:**
175+
- Proxy searches for services matching the composite index
176+
- If multiple services match the same criteria, **the first one is used** (like `findFirst()` in databases)
177+
- Extra labels are ignored (safe to add additional labels)
178+
- Missing optional labels are handled gracefully
166179

167-
The following labels are required for services in Kubernetes discovery mode:
180+
| Label | Type | Description | Example Value | Index |
181+
| --------------------------------- | ------- | -------------------------------------------------- | --------------- | ----- |
182+
| **xdatabase-proxy-deployment-id** | String | Database deployment ID (routing key) | db-deployment-1 | ✅ YES |
183+
| **xdatabase-proxy-database-type** | String | Database type (filter) | postgresql | ✅ YES |
184+
| **xdatabase-proxy-pooled** | Boolean | Pooled connections (true/false) | true | ✅ YES |
185+
| xdatabase-proxy-destination-port | Integer | Target port for the database connection | 5432 ||
186+
| xdatabase-proxy-enabled | Boolean | (Deprecated) Whether service is managed by proxy | true ||
168187

169-
| Label | Description | Example Value |
170-
| -------------------------------- | -------------------------------------------------- | --------------- |
171-
| xdatabase-proxy-enabled | Whether the service should be managed by the proxy | true |
172-
| xdatabase-proxy-deployment-id | Database deployment ID | db-deployment-1 |
173-
| xdatabase-proxy-database-type | Database type | postgresql |
174-
| xdatabase-proxy-pooled | Whether this is a connection pooling service | true/false |
175-
| xdatabase-proxy-destination-port | Target port for the database connection | 5432 |
188+
**Label Indexing Example:**
189+
190+
When proxy receives connection: `postgres://user.db-prod.pool@proxy:5432/db`
191+
- Extracts: `deployment_id=db-prod`, `pooled=true`
192+
- Searches: services with `deployment_id=db-prod` AND `pooled=true`
193+
- Returns: **first matching service** (even if multiple exist)
194+
195+
```
196+
Cluster Services:
197+
1. Service: db-prod-1 (deployment_id=db-prod, pooled=true) → ✅ MATCHED & USED
198+
2. Service: db-prod-2 (deployment_id=db-prod, pooled=true) → ⏭️ SKIPPED (duplicate)
199+
3. Service: db-prod-pool (deployment_id=db-prod, pooled=false) → ⏭️ SKIPPED (diff pooled)
200+
4. Service: db-staging (deployment_id=db-staging, pooled=true)→ ⏭️ SKIPPED (diff id)
201+
```
202+
203+
**Connection String Routing:**
204+
- `postgres://user.db-prod@proxy:5432/db` → uses `deployment_id=db-prod, pooled=false`
205+
- `postgres://user.db-prod.pool@proxy:5432/db` → uses `deployment_id=db-prod, pooled=true`
176206

177207
## Usage Examples
178208

@@ -206,7 +236,7 @@ docker run -d \
206236
export DATABASE_TYPE=postgresql
207237
export RUNTIME=vm
208238
export DISCOVERY_MODE=static
209-
export STATIC_BACKENDS='[{"name":"db1","host":"10.0.1.5","port":5432},{"name":"db2","host":"10.0.1.6","port":5432}]'
239+
export STATIC_BACKENDS='db1=10.0.1.5:5432,db1.pool=10.0.1.5:6432,db2=10.0.1.6:5432'
210240
export TLS_AUTO_GENERATE=true
211241
export TLS_AUTO_RENEW=true
212242

@@ -262,21 +292,45 @@ postgresql://myuser.db-deployment-1.pool@localhost:5432/mydb
262292
## Architecture
263293

264294
```
265-
┌─────────────────────────────────────────────────────────────┐
266-
│ XDatabase Proxy │
267-
│ │
268-
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
269-
│ │ Config │ │ Factory │ │ Orchestrator │ │
270-
│ │ Management │→ │ Pattern │→ │ (main.go) │ │
271-
│ └──────────────┘ └──────────────┘ └──────────────┘ │
272-
│ │
273-
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
274-
│ │ Discovery │ │ TLS │ │ Proxy │ │
275-
│ │ (K8s/Static)│ │ Provider │ │ Handler │ │
276-
│ └──────────────┘ └──────────────┘ └──────────────┘ │
277-
└─────────────────────────────────────────────────────────────┘
295+
┌───────────────────────────────────────────────────────────────┐
296+
│ xdatabase-proxy │
297+
│ │
298+
│ ┌──────────────────┐ ┌──────────────────────┐ │
299+
│ │ Config & Runtime │ │ Orchestrator (app.go)│ │
300+
│ │ env -> types │ → │ wires factories │ │
301+
│ └──────────────────┘ └──────────────────────┘ │
302+
│ | | │
303+
│ v v │
304+
│ ┌──────────────────┐ ┌──────────────────────┐ │
305+
│ │ ResolverFactory │ │ TLSFactory │ │
306+
│ │ (k8s | static) │ │ (k8s | file | memory) │ │
307+
│ └──────────────────┘ └──────────────────────┘ │
308+
│ \ / │
309+
│ v v │
310+
│ ┌────────────────────────────────┐ │
311+
│ │ ProxyFactory (PostgreSQL) │ │
312+
│ │ builds ConnectionHandler │ │
313+
│ └────────────────────────────────┘ │
314+
│ | │
315+
│ ┌────────────────────────┐ │
316+
│ │ Core Server │ │
317+
│ │ (TCP accept loop) │ │
318+
│ └────────────────────────┘ │
319+
│ | │
320+
│ ┌────────────────────────┐ │
321+
│ │ Health Server │ │
322+
│ │ /health, /ready │ │
323+
│ └────────────────────────┘ │
324+
└───────────────────────────────────────────────────────────────┘
278325
```
279326

327+
**Flow**
328+
- Env → `config`: validates runtime, discovery, TLS, ports.
329+
- `app.Application`: initializes logger, resolver, TLS provider (optional), proxy handler, listener.
330+
- Factories: runtime-aware resolver (k8s/static), pluggable TLS (k8s/file/memory), protocol proxy.
331+
- `core.Server`: TCP accept loop, delegates to connection handler.
332+
- `api.HealthServer`: `/health` liveness, `/ready` readiness.
333+
280334
## Health Check Endpoints
281335

282336
- `GET /health` - Basic health check

0 commit comments

Comments
 (0)