TLS and Ingress
flex.plane runs on Kubernetes and exposes its services through standard Kubernetes ingress. You need an ingress controller and TLS certificates to serve the portal and API securely.
Choose an ingress controller
flex.plane works with any Kubernetes ingress controller. The most common choices:
| Controller | Notes |
|---|---|
| NGINX Ingress | The most widely used. Well-tested with flex.plane. Recommended for most deployments. |
| Traefik | Popular in k3s environments. Works well with minimal configuration. |
| HAProxy Ingress | Good for high-throughput deployments. |
Install your chosen controller following its documentation. For example, with NGINX:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
-n ingress-nginx --create-namespace
The flextenant chart references the ingress class name in its values:
orchestrator:
ingress:
enabled: true
className: "nginx"
portal:
ingress:
enabled: true
className: "nginx"
Configure cert-manager
cert-manager automates TLS certificate provisioning and renewal. It integrates with Let's Encrypt and other ACME providers.
Install cert-manager:
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
-n cert-manager --create-namespace \
--set crds.enabled=true
Create a ClusterIssuer for Let's Encrypt:
# cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- http01:
ingress:
class: nginx
kubectl apply -f cluster-issuer.yaml
Then reference the issuer in your flex.plane ingress annotations:
orchestrator:
ingress:
enabled: true
tlsEnabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt"
portal:
ingress:
enabled: true
tlsEnabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt"
cert-manager will automatically request certificates and renew them before expiry.
https://acme-staging-v02.api.letsencrypt.org/directory) for testing to avoid hitting rate limits.Set up DNS
You need DNS records pointing to your ingress controller's external IP or load balancer. The typical setup uses a single domain with path-based routing:
| DNS Record | Target | Purpose |
|---|---|---|
flexplane.example.com | Ingress controller IP | Portal, API, playground |
auth.example.com | Zitadel ingress IP | OIDC authentication |
If your Zitadel and flex.plane share the same ingress controller, you can use the same IP for both records.
For Kubernetes clusters running on bare metal or on-premises, you may need to configure a LoadBalancer service type with MetalLB or similar, or use NodePort with an external reverse proxy.
WebSocket support
The orchestrator's terminal proxy (port 7777) uses WebSocket connections for VM console access. Make sure your ingress controller is configured to support WebSocket upgrades. For NGINX Ingress, this typically works out of the box. If you use a CDN or external load balancer in front of your ingress, verify that it passes WebSocket connections through.