feat(ingress): single-host Guacamole via guacamole-namespace IngressRoute
Cluster Traefik disallows cross-namespace service refs from
IngressRoutes, so the PathPrefix(/guacamole) rule I added to
fc-desktop IngressRoute in 292528e failed with:
"service guacamole/guacamole not in the parent resource namespace
fc-desktop"
Move the /guacamole path match into the guacamole namespace where
the Service actually lives:
- apps/guacamole/guacamole.yaml adds a new `guacamole-desktop-path`
IngressRoute matching `Host(desktop.iamworkin.lan) &&
PathPrefix(/guacamole)` → guacamole:8080 (no add-prefix middleware;
the browser already sends the /guacamole/* path that Guacamole's
servlet serves at).
- New Certificate `desktop-guacamole-path-tls` for desktop.iamworkin.lan
in the guacamole namespace, issued by step-ca-acme. Separate cert
from fc-desktop's remotedesktop-web-tls because Secret refs are
also scoped per-namespace; duplicating the cert is cheaper than
enabling cross-namespace secret refs cluster-wide.
- Revert the cross-namespace attempt in apps/fc-desktop/fc-desktop.yaml
back to a Host-only route. Traefik's router matching precedence
(longer/more-specific rule wins) handles the /guacamole vs
catch-all priority without explicit priority: fields.
Closes the single-host Guacamole URL regression Codex's branch
introduced — GuacamolePublicUrl=https://desktop.iamworkin.lan/guacamole
now resolves to the Guacamole webapp end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,23 +23,16 @@ spec:
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- websecure
|
- websecure
|
||||||
routes:
|
routes:
|
||||||
# Single-host Guacamole routing: Traefik forwards the /guacamole
|
# Host-level catch-all for desktop.iamworkin.lan. The /guacamole
|
||||||
# path-prefix directly to the guacamole Service in the guacamole
|
# path-prefix match lives in apps/guacamole/guacamole.yaml as a
|
||||||
# namespace. Must precede the catch-all Host() rule so priority
|
# separate IngressRoute in the guacamole namespace — the cluster
|
||||||
# resolves the more-specific match first. RemoteDesktop.Web then
|
# Traefik disallows cross-namespace service refs, so the PathPrefix
|
||||||
# emits launch URLs with host=desktop.iamworkin.lan + /guacamole
|
# rule can't sit here. Traefik's router matching precedence gives
|
||||||
# prefix, keeping Guacamole reachable through the same public
|
# longer/more-specific rules priority automatically, so as long as
|
||||||
# surface (GuacamolePublicUrl=https://desktop.iamworkin.lan/guacamole).
|
# the guacamole IngressRoute exists it takes /guacamole traffic
|
||||||
- match: Host(`desktop.iamworkin.lan`) && PathPrefix(`/guacamole`)
|
# before this catch-all sees it.
|
||||||
kind: Rule
|
|
||||||
priority: 20
|
|
||||||
services:
|
|
||||||
- name: guacamole
|
|
||||||
namespace: guacamole
|
|
||||||
port: 8080
|
|
||||||
- match: Host(`desktop.iamworkin.lan`)
|
- match: Host(`desktop.iamworkin.lan`)
|
||||||
kind: Rule
|
kind: Rule
|
||||||
priority: 10
|
|
||||||
services:
|
services:
|
||||||
- name: remotedesktop-web
|
- name: remotedesktop-web
|
||||||
port: 8080
|
port: 8080
|
||||||
|
|||||||
@@ -444,6 +444,46 @@ spec:
|
|||||||
tls:
|
tls:
|
||||||
secretName: guacamole-tls
|
secretName: guacamole-tls
|
||||||
---
|
---
|
||||||
|
# Single-host Guacamole routing — matches RemoteDesktop.Web launch URLs
|
||||||
|
# that embed Guacamole as a path-prefixed iframe on the primary desktop
|
||||||
|
# host (https://desktop.iamworkin.lan/guacamole/#/client/...). The
|
||||||
|
# Traefik IngressRoute lives in the guacamole namespace because the
|
||||||
|
# cluster disallows cross-namespace service refs from IngressRoutes.
|
||||||
|
# No add-prefix middleware: the browser already sends /guacamole/*
|
||||||
|
# which is the servlet path Guacamole's webapp serves at.
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: desktop-guacamole-path-tls
|
||||||
|
namespace: guacamole
|
||||||
|
spec:
|
||||||
|
secretName: desktop-guacamole-path-tls
|
||||||
|
issuerRef:
|
||||||
|
name: step-ca-acme
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- desktop.iamworkin.lan
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: guacamole-desktop-path
|
||||||
|
namespace: guacamole
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/part-of: flowercore
|
||||||
|
app.kubernetes.io/component: guacamole-ingress
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`desktop.iamworkin.lan`) && PathPrefix(`/guacamole`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: guacamole
|
||||||
|
port: 8080
|
||||||
|
tls:
|
||||||
|
secretName: desktop-guacamole-path-tls
|
||||||
|
---
|
||||||
# 1Password secret sync — creates guacamole-credentials K8s Secret
|
# 1Password secret sync — creates guacamole-credentials K8s Secret
|
||||||
# Fields: username, password, DB-User, DB-Password, DB-Root-Password, DB-Name, URL
|
# Fields: username, password, DB-User, DB-Password, DB-Root-Password, DB-Name, URL
|
||||||
apiVersion: onepassword.com/v1
|
apiVersion: onepassword.com/v1
|
||||||
|
|||||||
Reference in New Issue
Block a user