Documentation / Kubernetes Integration

Kubernetes Integration

Automatically expose Kubernetes services to the internet with a simple annotation

Overview

The stunl Kubernetes Controller watches for Services with the stunl.com/expose annotation and automatically creates tunnel sidecars to expose them to the internet.

How It Works

1. Annotate Service
stunl.com/expose: "true"
2. Controller Creates Tunnel
Deployment: stunl-myapp
3. Service Exposed
https://myapp.stunl.io

Benefits

  • No LoadBalancer or Ingress required
  • Works in any cluster (local, cloud, air-gapped)
  • Automatic TLS certificates
  • GitOps compatible (annotation-based)

Installation

1

Create namespace and RBAC

$ kubectl create namespace stunl-system
$ kubectl apply -f https://stunl.com/k8s/rbac.yaml
2

Create API key secret

$ kubectl create secret generic stunl-api-key \
    --namespace stunl-system \
    --from-literal=api-key=st_live_your_key_here
3

Deploy the controller

$ kubectl apply -f https://stunl.com/k8s/controller.yaml

# Verify controller is running
$ kubectl get pods -n stunl-system
NAME                               READY   STATUS    RESTARTS   AGE
stunl-controller-7d8f9b6c4-x2k9p   1/1     Running   0          30s

Usage

Add the stunl.com/expose: "true" annotation to any Service to expose it.

service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-web-app
  annotations:
    stunl.com/expose: "true"
    stunl.com/subdomain: "myapp"          # Optional: custom subdomain
    stunl.com/protocol: "http"            # Optional: http (default), tcp, udp
spec:
  selector:
    app: my-web-app
  ports:
    - port: 80
      targetPort: 8080
Apply and check
$ kubectl apply -f service.yaml

# The controller automatically adds the tunnel URL annotation
$ kubectl get svc my-web-app -o jsonpath='{.metadata.annotations.stunl\.com/url}'
https://myapp.stunl.io

Annotations Reference

Annotation Description Default
stunl.com/expose Enable tunnel for this Service "false"
stunl.com/subdomain Custom subdomain {name}-{namespace}
stunl.com/protocol Protocol: http, tcp, udp "http"
stunl.com/domain Pro domain (e.g., localshare.io) stunl.io
stunl.com/use-root Use root domain (no subdomain) "false"

Output Annotation

The controller automatically adds stunl.com/url to the Service with the public tunnel URL once the tunnel is established.

Examples

HTTP Service (Web App)

apiVersion: v1
kind: Service
metadata:
  name: frontend
  annotations:
    stunl.com/expose: "true"
    stunl.com/subdomain: "demo"
spec:
  ports:
    - port: 80
# Result: https://demo.stunl.io

TCP Service (Database)

apiVersion: v1
kind: Service
metadata:
  name: postgres
  annotations:
    stunl.com/expose: "true"
    stunl.com/protocol: "tcp"
    stunl.com/subdomain: "mydb"
spec:
  ports:
    - port: 5432
# Result: mydb.stunl.io:15432

Pro Domain

apiVersion: v1
kind: Service
metadata:
  name: api
  annotations:
    stunl.com/expose: "true"
    stunl.com/domain: "localshare.io"
    stunl.com/subdomain: "api"
spec:
  ports:
    - port: 8080
# Result: https://api.localshare.io

Controller Configuration

The controller can be configured via command-line arguments in the deployment:

Flag Description Default
--tunnel-server stunl server address portal.stunl.com
--client-image Tunnel client container image stunl/client:latest
--metrics-bind-address Metrics endpoint address :8080
--health-probe-bind-address Health check endpoint :8081
--leader-elect Enable leader election for HA true

Security Considerations

RBAC Permissions

The controller requires minimal RBAC: watch/list Services, create/update/delete Deployments in watched namespaces, and record Events.

API Key Secret

Store your API key in a Kubernetes Secret. The controller automatically mounts it to tunnel client pods.

Network Policies

The controller deployment includes NetworkPolicy to restrict egress to only the stunl server.

Pod Security

Controller runs as non-root with read-only root filesystem and all capabilities dropped.

Troubleshooting

Tunnel not created

Check controller logs:

kubectl logs -n stunl-system deployment/stunl-controller

Tunnel pod crashing

Check the tunnel deployment logs:

kubectl logs deployment/stunl-{service-name} -n {namespace}

Check events

The controller records validation failures as Events:

kubectl get events --field-selector reason=ValidationFailed

Next Steps