Relay pods for external TCP targets #12

Open
opened 2026-08-31 12:42:38 +00:00 by aav · 0 comments
Owner

Problem

Some backends live outside the cluster but inside its VNet - e.g. the Azure Flexible Server netzlive-1p-netzlive-1.postgres.database.azure.com (no public access, private DNS in the cluster VNet). silta can only target svc/ and pod/, so these are unreachable: port-forward needs a pod that listens, and none does. Today people bounce through an ephemeral socat pod (the n-script's remote-postgres), which leaks the pod on any exit that is not a clean return or SIGINT.

Feature

A third target type that names the external endpoint directly:

{ namespace = "netzlive", target = "tcp/netzlive-stage1p-netzlive-1.postgres.database.azure.com:5432", local = 25433 }

On the first connection to such a forward, silta ensures a relay pod exists in the namespace and then forwards to it like a pod/ target. The relay is an alpine/socat listener that connects to the external host:port.

Lifecycle

  • Lazy: create on first connection, not at silta run startup. Unused forwards cost nothing.
  • Adopt: if a Ready pod with the expected name already exists, use it. Restarts and parallel silta instances share it.
  • Orphan control: set activeDeadlineSeconds (a few hours) on the pod. The cluster retires stale relays on its own; silta recreates on next use. Deleting on shutdown is a courtesy, not the safety mechanism. This closes the leak the n-script has.
  • Recreate on demand when the deadline killed a relay mid-session; cost is one reconnect.

Naming

<prefix>-<user>-<hash>
  • prefix defaults to "silta"; a per-forward pod_name option overrides only the prefix.
  • user is the sanitized OS username (not git config). Per-user relays: nobody's deadline kills anybody else's session, and attribution is visible in the plain pod list.
  • hash is a short hash of host:port, the collision guard and the adoption key.
  • Whole name must satisfy RFC 1123 (lowercase, dashes, 63 chars max): sanitize and truncate, keep the hash.

Example: silta-aav-3f9c2e, or pg-netzlive-aav-3f9c2e with pod_name = "pg-netzlive".

Labels on the pod: silta/target=host:port for listing and sweeping.

Notes

  • Needs RBAC to create pods in the target namespace.
  • describe should surface relay status (exists / Ready / absent) as hints.
  • The image reference should be overridable so clusters with registry policies can point at their mirror (e.g. netzebwnetzlive.azurecr.io/dockerhub/alpine/socat).
## Problem Some backends live outside the cluster but inside its VNet - e.g. the Azure Flexible Server netzlive-<env>1p-netzlive-1.postgres.database.azure.com (no public access, private DNS in the cluster VNet). silta can only target svc/ and pod/, so these are unreachable: port-forward needs a pod that listens, and none does. Today people bounce through an ephemeral socat pod (the n-script's remote-postgres), which leaks the pod on any exit that is not a clean return or SIGINT. ## Feature A third target type that names the external endpoint directly: { namespace = "netzlive", target = "tcp/netzlive-stage1p-netzlive-1.postgres.database.azure.com:5432", local = 25433 } On the first connection to such a forward, silta ensures a relay pod exists in the namespace and then forwards to it like a pod/ target. The relay is an alpine/socat listener that connects to the external host:port. ## Lifecycle - Lazy: create on first connection, not at silta run startup. Unused forwards cost nothing. - Adopt: if a Ready pod with the expected name already exists, use it. Restarts and parallel silta instances share it. - Orphan control: set activeDeadlineSeconds (a few hours) on the pod. The cluster retires stale relays on its own; silta recreates on next use. Deleting on shutdown is a courtesy, not the safety mechanism. This closes the leak the n-script has. - Recreate on demand when the deadline killed a relay mid-session; cost is one reconnect. ## Naming <prefix>-<user>-<hash> - prefix defaults to "silta"; a per-forward pod_name option overrides only the prefix. - user is the sanitized OS username (not git config). Per-user relays: nobody's deadline kills anybody else's session, and attribution is visible in the plain pod list. - hash is a short hash of host:port, the collision guard and the adoption key. - Whole name must satisfy RFC 1123 (lowercase, dashes, 63 chars max): sanitize and truncate, keep the hash. Example: silta-aav-3f9c2e, or pg-netzlive-aav-3f9c2e with pod_name = "pg-netzlive". Labels on the pod: silta/target=<host:port> for listing and sweeping. ## Notes - Needs RBAC to create pods in the target namespace. - describe should surface relay status (exists / Ready / absent) as hints. - The image reference should be overridable so clusters with registry policies can point at their mirror (e.g. netzebwnetzlive.azurecr.io/dockerhub/alpine/socat).
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
carvers/silta#12
No description provided.