Kubernetes, without the exposed ingress

The OpenVLAN operator joins your clusters to the tailnet — pods, services, and operators reachable privately from anywhere.

Annotate a service, and it exists — privately

No load balancer provisioning, no certificate ceremony, no ingress controller tuning. The operator watches for the annotation and publishes the service straight onto the tailnet, where it gets a MagicDNS name and identity-based access control.

  • ✓Zero public exposure unless you explicitly opt in
  • ✓Works alongside your existing CNI — no rip-and-replace
  • ✓Namespaces isolated by ACL, not by network topology
kubectl — expose a service
api-gatewayprod · ClusterIP:443ON MESH
orders-svcprod · ClusterIP:8080ON MESH
grafanaops · ClusterIP:3000ON MESH
pg-adminstaging · ClusterIP:5432NOT EXPOSED

Every pod carries an identity

Workloads authenticate with short-lived credentials issued at deploy time. When a pod is evicted or a node is reclaimed, its access evaporates with it — nothing long-lived to scrape from a config map and reuse elsewhere.

workload identities
ci-runnerephemeral · expires 1htag:ciSCOPED
payments-apiprod · rotatingtag:prodSCOPED
old-sidecarremoved last week—EXPIRED

What the operator does

⚙️

Cluster ingress

Expose cluster services to the tailnet with a simple annotation — no public load balancer, no cert drama.

🔗

Cluster egress

Let pods reach databases and internal APIs through subnet routes, with source identity intact.

📡

Multi-cluster

Dev, staging, and prod clusters on one mesh — namespaces stay isolated by ACL, not by network.

🧩

Service-to-service

Pods in different clusters call each other by name over encrypted paths; no cross-cluster peering required.

🧠

Operator API

Services and pods become first-class tailnet citizens via CRDs, managed like everything else in your cluster.

🔐

Short-lived auth

Ephemeral clusters authenticate with expiring auth keys; nothing long-lived to leak.

🛡️

SSH to nodes

Debug node-level issues with OpenVLAN SSH — no bastion pod, full session audit.

🚫

Zero ingress

The API server itself can drop its public endpoint and live entirely on the mesh.

🧪

Private dev clusters

Developers hit their namespace's services from laptops; nothing about the cluster is public.

🔁

GitOps runners

CI applies manifests to clusters over the mesh; cloud keys stay out of the runner.

🏛️

Legacy bridge

Cluster workloads reach the on-prem Oracle DB through the office subnet router.

📜

Helm-native

Install, upgrade, and configure with the tooling your team already reviews in PRs.

Install

# Helm install, then annotate a service
$ helm install openvlan-operator openvlan/operator
 
apiVersion: v1
kind: Service
metadata:
  name: api-gateway
  annotations:
    openvlan.com/expose: "true"
 
# now reachable at api-gateway.prod.tailnet.com — privately

Kubernetes FAQs

Does the operator replace my CNI?
No — it runs alongside whatever CNI you use today. Pod-to-pod traffic inside the cluster keeps flowing as-is; the operator handles traffic entering or leaving the tailnet.
Is there a performance overhead?
The data plane is AmneziaWG at kernel speed. Typical service-to-service paths add under 1 ms versus plain overlay networking, and throughput stays at line rate for normal service traffic.
How does RBAC interact with ACLs?
They compose: your cluster RBAC governs who can deploy and annotate, while tailnet ACLs govern what each workload can reach at runtime. Security teams typically own the ACL file; platform teams own the Helm values.
Can we keep the API server private?
Yes — a popular endgame. Move the API server endpoint onto the mesh, and kubectl just works for authorized devices while the public endpoint gets deleted along with its allowlist.
What about Windows node pools?
Supported — the operator handles Linux and Windows nodes in the same cluster, so mixed pools stay on one mesh with one policy file.

Clusters on the mesh in minutes

Helm chart, one annotation, done.