Networking & Monitoring¶
Services¶
Routable components expose a Kubernetes Service. The service spec supports type, port, nodePort, labels, and annotations:
spec:
webServer:
service:
type: LoadBalancer
port: 443
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
The operator does not expose Kubernetes Service.spec.loadBalancerIP because that field is deprecated. Prefer controller-specific annotations when your provider documents them.
Gateway API (Recommended)¶
Requires Gateway API CRDs installed on the cluster. Gateway API is not included in Kubernetes and must be installed separately. If the CRDs are absent, the operator logs a message and skips HTTPRoute management.
spec:
networking:
gateway:
gatewayRef:
name: my-gateway
namespace: gateway-system
hostnames:
- superset.example.com
The operator creates an HTTPRoute with path-based routing:
| Priority | Path | Target | Condition |
|---|---|---|---|
| 1 (most specific) | /ws |
websocket-server Service | websocketServer enabled |
| 2 | /mcp |
mcp-server Service | mcpServer enabled |
| 3 | /flower |
celery-flower Service | celeryFlower enabled and published (see the Flower note below) |
| 4 (catch-all) | / |
web-server Service | webServer enabled |
More specific paths are listed first to ensure correct routing priority. Paths are configurable via service.gatewayPath on each component spec.
For example, to serve Celery Flower under /monitoring:
Celery Flower ships unauthenticated
The operator's default Flower command carries no authentication, and the Flower dashboard discloses task names, arguments, and results metadata — for Superset that includes other users' async SQL Lab statements and alert/report payloads. To avoid exposing it unauthenticated on the end-user hostname, Flower is not published on the Ingress/Gateway surface in Production unless you explicitly set celeryFlower.service.gatewayPath. In Development and Staging it is published by default for convenience. Setting gatewayPath is your assertion that authentication sits in front of Flower — for example inject Flower's FLOWER_BASIC_AUTH environment variable from a Kubernetes Secret via celeryFlower.podTemplate.container.env (valueFrom.secretKeyRef), or enforce authentication at the ingress-controller layer for the Flower path.
Ingress (Legacy)¶
Gateway API and Ingress are mutually exclusive — set one or the other, not both.
Ingress uses the same per-component path routing as Gateway API: a host with no explicit paths is expanded by the operator into one rule per present component (/ → web server, plus /mcp and /ws for the components that are enabled, and /flower when Flower is published — see the Flower note above), reusing each component's service.gatewayPath. Requests are forwarded as-is (no path rewrite), so each component owns its subpath the same way it does under Gateway API (e.g. Flower via its --url_prefix).
spec:
networking:
ingress:
className: nginx
host: superset.example.com # no explicit paths -> all components routed by path
A host with explicit paths is treated as a user-controlled override and those paths route to the web server only — use this when you want full control of the path rules for a host:
spec:
networking:
ingress:
className: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
hosts:
- host: superset.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: superset-tls
hosts:
- superset.example.com
Use className for controllers that support spec.ingressClassName. For legacy controllers, put kubernetes.io/ingress.class under annotations instead:
spec:
networking:
ingress:
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/target-type: ip
hosts:
- host: superset.example.com
paths:
- path: /
pathType: Prefix
Graceful CRD Handling¶
If Gateway API CRDs are not present, the controller skips HTTPRoute watch registration and catches meta.IsNoMatchError at reconciliation time. The operator runs with reduced functionality rather than failing.
Superset Instance Metrics¶
Requires prometheus-operator CRDs. The operator gracefully skips if they are not installed.
The controller creates a Prometheus ServiceMonitor targeting the web-server component using unstructured objects (because the ServiceMonitor CRD is external: monitoring.coreos.com/v1). Default scrape interval is 30s (configurable). Targets pods with app.kubernetes.io/component: web-server.
Operator Metrics¶
The operator itself exposes controller-runtime default metrics — reconcile counts and durations, work-queue depth, leader election state. These are served over HTTPS on port 8443, guarded by Kubernetes bearer-token authentication and authorization. No custom lifecycle metrics are emitted today; condition and event streams cover the per-instance lifecycle state.
RBAC. Any scraper (typically Prometheus) needs the metrics-reader ClusterRole bound to its own ServiceAccount. Both install paths ship this role; bind it to your Prometheus ServiceAccount, for example:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-superset-operator-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: superset-operator-metrics-reader # Kustomize. For Helm, check the installed role name.
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
TLS by default. The operator generates a self-signed certificate at startup, so scrapers connect over HTTPS with insecureSkipVerify: true. This is the default in both the Kustomize ServiceMonitor (config/prometheus/monitor.yaml) and the Helm chart. It's fine for a trusted cluster but not for zero-trust environments. Authentication and authorization are always enforced via bearer tokens (TokenReview/SubjectAccessReview) regardless of TLS setup — see Design Decisions in the security reference for the trust-model context.
Enable via Helm¶
The chart ships a ServiceMonitor template, off by default. The minimal opt-in looks like:
metrics:
enabled: true
serviceMonitor:
enabled: true
interval: 30s
labels:
release: prometheus # selector your Prometheus picks up
That keeps the default self-signed + insecureSkipVerify: true behavior.
For real TLS via cert-manager, provision a metrics-server-cert Secret (typically via a cert-manager.io/v1 Certificate keyed to a self-signed Issuer) and point the chart at it:
metrics:
enabled: true
certSecretName: metrics-server-cert # mounts Secret into manager pod
serviceMonitor:
enabled: true
labels:
release: prometheus
tlsConfig: # free-form ServiceMonitor tlsConfig
insecureSkipVerify: false
serverName: <release>-superset-operator-metrics.<namespace>.svc
ca:
secret:
name: metrics-server-cert
key: ca.crt
The operator authenticates scrapers via bearer token (TokenReview), not mTLS, so ca + serverName are sufficient for the scraper to verify the server. Add cert/keySecret only if you've separately configured the metrics server to require client certs.
Setting metrics.certSecretName mounts the Secret into the manager pod and adds --metrics-cert-path args so the metrics server presents that certificate. The full set of knobs is documented in charts/superset-operator/values.yaml.
The chart does not ship the cert-manager Certificate or Issuer resources themselves; you create them (for example via cert-manager.io/v1 manifests alongside your values). See the Kustomize section below for a working example of those manifests.
Enable via Kustomize¶
Uncomment - ../prometheus in config/default/kustomization.yaml and re-apply. This adds the shipped ServiceMonitor in config/prometheus/monitor.yaml, which scrapes the operator's self-signed metrics endpoint with insecureSkipVerify: true.
For a cert-manager-managed certificate (real TLS, no insecureSkipVerify), install cert-manager on the cluster, then uncomment three more sections in config/default/kustomization.yaml:
[CERTMANAGER]— pulls inconfig/certmanager(aselfsigned-issuerIssuer plus ametrics-certsCertificate that issues themetrics-server-certSecret).[METRICS-WITH-CERTS]— mounts that Secret into the manager pod and adds the--metrics-cert-pathargs.[PROMETHEUS-WITH-CERTS]— areplacementsblock that substitutes the real Service name and namespace into the Certificate's dnsNames and the ServiceMonitor'stlsConfig.serverName.
Also uncomment the patch reference in config/prometheus/kustomization.yaml so the ServiceMonitor picks up the real-TLS tlsConfig from monitor_tls_patch.yaml.
Network Policies¶
Creates per-component NetworkPolicies that:
- Allow ingress from other pods of the same Superset instance on any port (matched by
app.kubernetes.io/name: superset+superset.apache.org/parentlabels — multiple Superset instances in the same namespace are isolated from each other). The same-instance rule is intentionally port-unrestricted so internal traffic between components (sidecar metrics scraping, the websocket server fanning out to web pods, etc.) is not silently blocked. - Allow ingress on the service port from any source for externally-facing components (web server, websocket server, MCP server, and Celery Flower once it is published — see the Flower note above) — this is necessary because ingress controllers and load balancers typically reside outside the namespace and cannot be matched with a pod selector.
- Allow all egress (for database/cache access)
- Support custom
extraIngressandextraEgressrules
Per-component rules:
| Component | Ingress from same-instance Superset pods | Ingress from external | Egress |
|---|---|---|---|
| WebServer | any port | port 8088 | all |
| CeleryWorker | any port | — | all |
| CeleryBeat | any port | — | all |
| CeleryFlower | any port | port 5555 (only when published; see the Flower note above) | all |
| WebsocketServer | any port | port 8080 | all |
| McpServer | any port | port 8088 | all |
If you need to restrict external ingress to specific sources, disable the built-in network policy and create your own NetworkPolicy resources with the desired from selectors.
The built-in policy is ingress segmentation only — egress is intentionally unrestricted so workloads can reach the metastore database, Valkey, SMTP servers, and other user-configured dependencies. For the rationale and hardening path, see Design Decisions in the security reference.