Add Documentation for Tailscale Ingress (HTTP/HTTPS Service Exposure)
Summary
The current Tailscale integration documentation (docs/tailscale-integration.md) covers LoadBalancer services but doesn't document using the Tailscale IngressClass for exposing HTTP/HTTPS services.
Problem
Users may try to expose web applications (like Grafana, Metabase, etc.) via Tailscale using LoadBalancer services, which doesn't work properly for HTTP/HTTPS traffic. This results in connection refused errors.
What Works (Documented)
- ✅ LoadBalancer services for raw TCP (Kubernetes API, PostgreSQL)
- ✅ VIP route advertisement
- ✅ Magic DNS for
.ts.net hostnames
What's Missing (Undocumented)
- ❌ Using Tailscale Ingress for HTTP/HTTPS services
- ❌ Difference between LoadBalancer vs Ingress approaches
- ❌ When to use which method
Proposed Solution
Add a new section to docs/tailscale-integration.md explaining Tailscale Ingress usage.
Suggested Content
When to Use LoadBalancer vs Ingress
LoadBalancer Services - For raw TCP services:
- Databases (PostgreSQL, MySQL, Redis)
- SSH services
- Kubernetes API
- Any service that doesn't use HTTP protocol
Ingress Resources - For HTTP/HTTPS services:
- Web applications (Grafana, Metabase, etc.)
- REST APIs
- Web dashboards
- Any HTTP-based service
Example: Exposing a Web Application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-tailscale
namespace: monitoring
annotations:
tailscale.com/tailnet-fqdn: grafana.tail6fbc5.ts.net
tailscale.com/tags: tag:k8s-foundry,tag:production
spec:
ingressClassName: tailscale # Use Tailscale ingress controller
defaultBackend:
service:
name: grafana
port:
number: 3000
tls:
- hosts:
- grafana
Result: Accessible at https://grafana-1.tail6fbc5.ts.net (TLS auto-provisioned)
How It Works
- Tailscale operator creates a dedicated proxy pod for the Ingress
- The proxy handles HTTP/HTTPS routing and TLS termination
- Traffic flows:
Browser → Tailscale → Ingress Proxy → Service → Pod
- The operator automatically assigns a
.tail6fbc5.ts.net hostname
LoadBalancer Example (for comparison)
For TCP services like PostgreSQL:
apiVersion: v1
kind: Service
metadata:
name: postgres-tailscale
annotations:
tailscale.com/expose: "true"
tailscale.com/hostname: postgres
tailscale.com/tags: tag:k8s-foundry,tag:production
spec:
type: LoadBalancer
loadBalancerClass: tailscale
selector:
app: postgresql
ports:
- port: 5432
targetPort: 5432
Result: Accessible at postgres.tail6fbc5.ts.net:5432
Real-World Example
This issue was discovered when trying to expose Metabase (web analytics tool):
- Initial attempt: LoadBalancer service → Connection refused
- Solution: Tailscale Ingress → Works perfectly
The Ingress approach properly handles HTTP routing and TLS, while LoadBalancer is meant for raw TCP forwarding.
Suggested Documentation Location
Add a new section after "What Gets Deployed" (around line 205):
## Exposing Services via Tailscale
### HTTP/HTTPS Services (Web Apps)
Use Kubernetes Ingress resources with `ingressClassName: tailscale`:
[Include Ingress example from above]
### TCP Services (Databases, APIs)
Use LoadBalancer services with `loadBalancerClass: tailscale`:
[Include LoadBalancer example from above]
Additional Resources
Benefits
- Prevents users from wasting time debugging LoadBalancer services for HTTP apps
- Shows the correct pattern for each use case
- Helps users understand when Foundry's Tailscale integration ends and manual Kubernetes configuration begins
- Provides copy-paste examples for common scenarios
Labels: documentation, tailscale, enhancement
Priority: Medium - Affects user experience but workaround exists
Add Documentation for Tailscale Ingress (HTTP/HTTPS Service Exposure)
Summary
The current Tailscale integration documentation (
docs/tailscale-integration.md) covers LoadBalancer services but doesn't document using the Tailscale IngressClass for exposing HTTP/HTTPS services.Problem
Users may try to expose web applications (like Grafana, Metabase, etc.) via Tailscale using LoadBalancer services, which doesn't work properly for HTTP/HTTPS traffic. This results in connection refused errors.
What Works (Documented)
.ts.nethostnamesWhat's Missing (Undocumented)
Proposed Solution
Add a new section to
docs/tailscale-integration.mdexplaining Tailscale Ingress usage.Suggested Content
When to Use LoadBalancer vs Ingress
LoadBalancer Services - For raw TCP services:
Ingress Resources - For HTTP/HTTPS services:
Example: Exposing a Web Application
Result: Accessible at
https://grafana-1.tail6fbc5.ts.net(TLS auto-provisioned)How It Works
Browser → Tailscale → Ingress Proxy → Service → Pod.tail6fbc5.ts.nethostnameLoadBalancer Example (for comparison)
For TCP services like PostgreSQL:
Result: Accessible at
postgres.tail6fbc5.ts.net:5432Real-World Example
This issue was discovered when trying to expose Metabase (web analytics tool):
The Ingress approach properly handles HTTP routing and TLS, while LoadBalancer is meant for raw TCP forwarding.
Suggested Documentation Location
Add a new section after "What Gets Deployed" (around line 205):
Additional Resources
Benefits
Labels:
documentation,tailscale,enhancementPriority: Medium - Affects user experience but workaround exists