Running Glowpod
Day-two notes for an in-cluster install: what Glowpod stores, what it logs, how to watch it, and what to check when something is off.
Security model in short
- Everyone acts as themselves. Each Kubernetes call carries the signed-in
person's token, or impersonates them. Glowpod's service account may only
impersonateusers and groups (and has no rights at all with tokens only, or SSO withpassToken). - Nothing shared between people. Glowpod keeps no cluster data across requests that another person could be served; watches and lists run per person.
- Buttons follow RBAC, checked with
SelfSubjectAccessReview; a 403 is still handled if rights change mid-session. - Secret values stay hidden until someone clicks Reveal and is allowed to read that Secret. Helm release values are never shown.
- Browser side: session cookie
HttpOnly,Secure,SameSite=Strict; a CSRF token on every change; a strict Content-Security-Policy with a fresh nonce per page; HSTS on HTTPS; only thepublicURLhost is answered (other hosts get421 Misdirected Request). - Container: distroless, non-root (65532), read-only root filesystem, no
capabilities,
RuntimeDefaultseccomp. It passes the restricted Pod Security Standard.
What Glowpod stores
Nothing on disk. Sessions (and, for token sign-in, the token) live in memory and are gone when the pod restarts. There's nothing to back up.
Because sessions are in memory:
- Keep one replica. Glowpod is light: one pod serves many people.
- A restart or upgrade signs everyone out; they sign in again.
- If you must run more replicas, set
allowManyReplicas: trueand turn on sticky sessions (cookie affinity) at the ingress. A session then only works on the pod that created it.
Sessions end after session.ttl (12 h) or session.idle (2 h without use),
and on sign-out.
Logs
Use logs.format: json (the chart default) for log collectors. Every line has
time, level and msg. People are recorded by user at sign-in and by
identity (a stable hash, never the token) after that, so you can join the
two.
msg |
Level | Fields | When |
|---|---|---|---|
starting glowpod |
info | version, mode |
Start |
glowpod is serving |
info | addr, public_url |
Ready |
signed in |
info | method, user, identity, ip |
A sign-in |
signed out |
info | identity |
A sign-out |
changed resource |
info | action, identity, group, resource, namespace, name |
Apply, scale, restart, delete |
changed node |
info | action, identity, name |
Cordon, uncordon, drain |
opened a shell |
info | identity, namespace, pod, container |
Exec terminal |
token sign-in failed, LDAP sign-in failed, SSO … |
warn | err |
See Sign-in and access |
cluster request failed |
warn | code, err |
The API server returned an unexpected error |
Glowpod never logs tokens, passwords, kubeconfigs, Secret values or the content of a change. For a full record of what changed, use the Kubernetes audit log: because Glowpod impersonates or passes tokens, it shows the real person, with Glowpod's service account as the impersonator.
ip is the client's address when trustedProxies lists your ingress
controller; otherwise it's the proxy's.
Health and monitoring
GET /healthzanswers200whenever the process is up; the chart uses it for readiness and liveness probes. It skips the host check, so probes work withoutpublicURL.helm test glowpod -n glowpodchecks the Service end to end.- Watch the pod's restarts and memory. Memory grows with the number of signed-in people and open live views; the chart's 256Mi limit covers a few dozen people on a mid-size cluster. Raise it for more.
Network
Glowpod needs to reach:
- the Kubernetes API server (in-cluster,
kubernetes.default.svc); - your SSO issuer, from the pod (discovery, keys, token exchange);
- your LDAP server;
- Prometheus, if you use the network gauge.
If you restrict egress with NetworkPolicy, allow these. networkPolicy.enabled
in the chart restricts ingress to Glowpod only.
Live updates, logs and the terminal use WebSockets on the same host. Your
ingress must pass Upgrade requests and allow long idle connections (an hour
or more).
Upgrades
helm upgrade glowpod deploy/helm/glowpod -n glowpod -f glowpod-values.yaml --set image.tag=<new>
Read the release notes for changed values; the values schema rejects ones
that no longer exist. Pin image.digest for reproducible deploys.
Troubleshooting
The pod won't start. Check kubectl -n glowpod logs deploy/glowpod.
Configuration errors are one plain line, for example:
-public-url is http://; serve Glowpod over HTTPS, or pass -insecure-cookies for a testSSO needs -public-url and -oidc-client-idLDAP needs -ldap-user-base
"Unknown host" (421). The browser's host doesn't match publicURL.
Fix publicURL, or open Glowpod at that address.
Sign-in works but the page bounces back to sign-in. The browser isn't
sending the cookie: Glowpod is served over plain HTTP. Use HTTPS (or
localhost for a port-forward).
Signed in, but lists are empty or say you aren't allowed. That's the
person's RBAC. Check with
kubectl auth can-i --list -n <ns> --as=<user> --as-group=<group>; see
Sign-in and access.
SSO/LDAP users get errors on everything (impersonate forbidden). The
impersonation ClusterRole is missing: keep rbac.create: true, or create
<release>-impersonator yourself.
Live views stop updating after a minute. The ingress closes idle WebSockets; raise its read/send timeouts.
CPU and memory gauges say "Install metrics-server". Install
metrics-server. The
network gauge appears only when Prometheus is found or prometheusURL is set.