Managing Kubernetes Operators
Operator Quick Reference
| Operator |
Primary CRDs |
Typical Namespace |
Project |
| Strimzi |
Kafka, KafkaTopic, KafkaUser, KafkaConnect, KafkaMirrorMaker2 |
strimzi-system |
strimzi.io |
| Keycloak |
Keycloak, KeycloakRealmImport |
keycloak-system |
keycloak.org |
| kube-prometheus-stack |
Prometheus, Alertmanager, ServiceMonitor, PodMonitor, PrometheusRule |
monitoring |
prometheus-operator |
| cert-manager |
Issuer, ClusterIssuer, Certificate, CertificateRequest |
cert-manager |
cert-manager.io |
| external-dns |
(no CRDs — annotation-driven) |
external-dns |
kubernetes-sigs |
Decision Matrix
Read the pattern file(s) matching the user's intent. Load only what's needed.
| User Intent |
Load |
| Install / compare installation methods |
installation-methods.md |
| Deploy Kafka cluster |
patterns/strimzi/cluster-setup.md |
| Configure Kafka listeners or storage |
patterns/strimzi/listeners-and-storage.md |
| Create Kafka topics or users |
patterns/strimzi/topics-and-users.md |
| Set up Kafka Connect / connectors |
patterns/strimzi/kafka-connect.md |
| Replicate Kafka across clusters |
patterns/strimzi/mirror-maker.md |
| Configure Keycloak realm |
patterns/keycloak/realm-configuration.md |
| Set up SSO / identity providers |
patterns/keycloak/identity-providers.md |
| Create Keycloak clients |
patterns/keycloak/client-setup.md |
| Customize Keycloak themes or SPIs |
patterns/keycloak/customization.md |
| Add Prometheus scraping for a service |
patterns/kube-prometheus-stack/service-monitors.md |
| Create alerting rules |
patterns/kube-prometheus-stack/alerting-rules.md |
| Provision Grafana dashboards |
patterns/kube-prometheus-stack/grafana-dashboards.md |
| Set up Thanos for long-term metrics |
patterns/kube-prometheus-stack/thanos-integration.md |
| Set up TLS certificates |
patterns/cert-manager/issuers.md + patterns/cert-manager/certificates.md |
| Configure ACME / challenge solvers |
patterns/cert-manager/issuers.md + patterns/cert-manager/webhook-solvers.md |
| Troubleshoot certificate renewal |
patterns/cert-manager/certificates.md |
| Auto-manage DNS records |
patterns/external-dns/provider-setup.md + patterns/external-dns/source-configuration.md |
| Configure DNS record ownership |
patterns/external-dns/ownership-and-policy.md |
| Upgrade any operator |
installation-methods.md + cross-cutting section below |
| Monitor operator health |
Cross-cutting section below (no extra file) |
Installation
Three methods exist: OLM, Helm, and raw manifests. See installation-methods.md for full comparison.
| Operator |
Recommended Method |
Notes |
| Strimzi |
Helm or OLM |
strimzi/strimzi-kafka-operator chart |
| Keycloak |
Helm or manifests |
keycloak/keycloak-operator chart |
| kube-prometheus-stack |
Helm only |
Complex subchart dependencies |
| cert-manager |
Helm |
cert-manager/cert-manager chart |
| external-dns |
Helm |
kubernetes-sigs/external-dns chart |
Cross-Cutting Concerns
CRD Versioning
CRD API versions progress: v1alpha1 → v1beta1 → v1. Before upgrading:
# check stored versions
kubectl get crd kafkas.kafka.strimzi.io -o jsonpath='{.status.storedVersions}'
# list all CRDs for an operator
kubectl get crd | grep strimzi.io
- Back up CRDs before upgrades:
kubectl get crd <name> -o yaml > backup.yaml
- Check operator release notes for deprecated API versions
- Conversion webhooks handle version translation — verify they're running after upgrade
Upgrade Strategies
General operator upgrade checklist:
- Read release notes and breaking changes
- Back up CRDs and CRs:
kubectl get <crd> -A -o yaml > backup.yaml
- Check CRD version compatibility between old and new operator
- Upgrade operator (Helm:
helm upgrade --atomic --wait, OLM: update subscription channel)
- Verify operator pod is healthy:
kubectl get pods -n <operator-ns>
- Verify managed resources reconciled: check CR
.status.conditions
- Run smoke tests against managed workloads
Rolling vs recreate:
- Most operators tolerate rolling updates (leader election handles handoff)
- Recreate if operator doesn't support leader election or runs as singleton
Canary upgrades:
- Run old + new operator in different namespaces with
WATCH_NAMESPACE scoping
- Validate new operator on non-production namespace before cluster-wide rollout
Deploy the Strimzi Drain Cleaner for graceful pod eviction during node maintenance — it ensures brokers are rolled safely when nodes are drained.
Monitoring Operator Health
All controller-runtime operators expose standard metrics:
# key metrics to watch
controller_runtime_reconcile_total{result="error"} # reconciliation failures
controller_runtime_reconcile_time_seconds # reconciliation latency
workqueue_depth # pending reconciliations
workqueue_longest_running_processor_seconds # stuck reconciliations
ServiceMonitor for operator pods:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: strimzi-operator
namespace: monitoring
spec:
namespaceSelector:
matchNames: [strimzi-system]
selector:
matchLabels:
app: strimzi-cluster-operator
endpoints:
- port: http
path: /metrics
interval: 30s
Alert on reconciliation failures:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: operator-health
namespace: monitoring
spec:
groups:
- name: operator-health
rules:
- alert: OperatorReconcileErrors
expr: rate(controller_runtime_reconcile_total{result="error"}[5m]) > 0
for: 10m
labels:
severity: warning
annotations:
summary: "Operator {{ $labels.controller }} has reconciliation errors"
Resource Sizing
Use Guaranteed QoS (requests == limits for CPU and memory) for all operator-managed workloads in production. Burstable pods under node pressure get OOM-killed first, triggering cascading failures.
RBAC Patterns
- Operators need cluster-wide RBAC for CRDs by default
- Namespace-scoped operators: set
WATCH_NAMESPACE env var to restrict scope
- Audit operator ClusterRole after install — remove unused rules for least-privilege
- Multi-tenant: one operator per namespace vs cluster-wide with namespace filtering
# audit what an operator service account can do
kubectl auth can-i --list --as=system:serviceaccount:strimzi-system:strimzi-cluster-operator
Namespace Strategy
- Dedicated namespace per operator:
strimzi-system, cert-manager, monitoring, external-dns
- Workload CRs (Kafka, Certificate, ServiceMonitor) live in application namespaces
- Operators watch across namespaces unless restricted via
WATCH_NAMESPACE
- Label namespaces for selective operator targeting where supported
Troubleshooting Workflow
Generic operator troubleshooting checklist:
- Operator pod healthy?
kubectl get pods -n <operator-ns> — check Ready, restarts
- Operator logs?
kubectl logs -n <operator-ns> deploy/<operator-name> --tail=100
- CR status conditions?
kubectl get <cr> <name> -o yaml — check .status.conditions for errors
- Events?
kubectl get events -n <ns> --sort-by='.lastTimestamp' --field-selector=reason!=Pulled
- RBAC?
kubectl auth can-i --as=system:serviceaccount:<ns>:<sa> <verb> <resource>
- CRDs installed?
kubectl get crd | grep <operator-domain>
- Webhooks?
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
Validation Loop
- Apply CR → check operator logs → check CR
.status → fix → repeat
- For upgrades: pre-upgrade checks → upgrade → post-upgrade verification → rollback if needed
- For new operator installs: install operator → verify CRDs exist → apply test CR → verify reconciliation
Deep-dive References
Strimzi (Kafka)
patterns/strimzi/cluster-setup.md — KRaft cluster provisioning, node pools
patterns/strimzi/listeners-and-storage.md — Listener types, authentication, JBOD, volume expansion
patterns/strimzi/topics-and-users.md — KafkaTopic, KafkaUser, ACLs
patterns/strimzi/kafka-connect.md — Connectors, plugin builds, Connect ACLs
patterns/strimzi/mirror-maker.md — MirrorMaker2, cross-cluster replication
Keycloak
patterns/keycloak/realm-configuration.md — Realm CRs, export/import, settings
patterns/keycloak/identity-providers.md — OIDC, SAML, social providers
patterns/keycloak/client-setup.md — Clients, scopes, service accounts
patterns/keycloak/customization.md — Themes, SPIs, custom providers
kube-prometheus-stack
patterns/kube-prometheus-stack/service-monitors.md — ServiceMonitor, PodMonitor
patterns/kube-prometheus-stack/alerting-rules.md — PrometheusRule, routing
patterns/kube-prometheus-stack/grafana-dashboards.md — Dashboard provisioning
patterns/kube-prometheus-stack/thanos-integration.md — Long-term storage
cert-manager
patterns/cert-manager/issuers.md — Issuer, ClusterIssuer, ACME, CA, Vault
patterns/cert-manager/certificates.md — Certificate lifecycle, renewal
patterns/cert-manager/webhook-solvers.md — HTTP01, DNS01 solvers
external-dns
patterns/external-dns/provider-setup.md — DNS provider configuration
patterns/external-dns/source-configuration.md — Ingress/Service/Gateway sources
patterns/external-dns/ownership-and-policy.md — TXT records, policy modes
Official References
1---2name: managing-k8s-operators3description: Kubernetes operator management best practices. Use when deploying, configuring, upgrading, or troubleshooting Kubernetes operators including Strimzi (Kafka), Keycloak, kube-prometheus-stack (Prometheus, Grafana, Alertmanager), cert-manager, or external-dns.4---56# Managing Kubernetes Operators78## Operator Quick Reference910| Operator | Primary CRDs | Typical Namespace | Project |11|----------|-------------|-------------------|---------|12| Strimzi | Kafka, KafkaTopic, KafkaUser, KafkaConnect, KafkaMirrorMaker2 | strimzi-system | strimzi.io |13| Keycloak | Keycloak, KeycloakRealmImport | keycloak-system | keycloak.org |14| kube-prometheus-stack | Prometheus, Alertmanager, ServiceMonitor, PodMonitor, PrometheusRule | monitoring | prometheus-operator |15| cert-manager | Issuer, ClusterIssuer, Certificate, CertificateRequest | cert-manager | cert-manager.io |16| external-dns | (no CRDs — annotation-driven) | external-dns | kubernetes-sigs |1718## Decision Matrix1920Read the pattern file(s) matching the user's intent. Load only what's needed.2122| User Intent | Load |23|---|---|24| Install / compare installation methods | `installation-methods.md` |25| Deploy Kafka cluster | `patterns/strimzi/cluster-setup.md` |26| Configure Kafka listeners or storage | `patterns/strimzi/listeners-and-storage.md` |27| Create Kafka topics or users | `patterns/strimzi/topics-and-users.md` |28| Set up Kafka Connect / connectors | `patterns/strimzi/kafka-connect.md` |29| Replicate Kafka across clusters | `patterns/strimzi/mirror-maker.md` |30| Configure Keycloak realm | `patterns/keycloak/realm-configuration.md` |31| Set up SSO / identity providers | `patterns/keycloak/identity-providers.md` |32| Create Keycloak clients | `patterns/keycloak/client-setup.md` |33| Customize Keycloak themes or SPIs | `patterns/keycloak/customization.md` |34| Add Prometheus scraping for a service | `patterns/kube-prometheus-stack/service-monitors.md` |35| Create alerting rules | `patterns/kube-prometheus-stack/alerting-rules.md` |36| Provision Grafana dashboards | `patterns/kube-prometheus-stack/grafana-dashboards.md` |37| Set up Thanos for long-term metrics | `patterns/kube-prometheus-stack/thanos-integration.md` |38| Set up TLS certificates | `patterns/cert-manager/issuers.md` + `patterns/cert-manager/certificates.md` |39| Configure ACME / challenge solvers | `patterns/cert-manager/issuers.md` + `patterns/cert-manager/webhook-solvers.md` |40| Troubleshoot certificate renewal | `patterns/cert-manager/certificates.md` |41| Auto-manage DNS records | `patterns/external-dns/provider-setup.md` + `patterns/external-dns/source-configuration.md` |42| Configure DNS record ownership | `patterns/external-dns/ownership-and-policy.md` |43| Upgrade any operator | `installation-methods.md` + cross-cutting section below |44| Monitor operator health | Cross-cutting section below (no extra file) |4546## Installation4748Three methods exist: OLM, Helm, and raw manifests. See `installation-methods.md` for full comparison.4950| Operator | Recommended Method | Notes |51|----------|-------------------|-------|52| Strimzi | Helm or OLM | `strimzi/strimzi-kafka-operator` chart |53| Keycloak | Helm or manifests | `keycloak/keycloak-operator` chart |54| kube-prometheus-stack | Helm only | Complex subchart dependencies |55| cert-manager | Helm | `cert-manager/cert-manager` chart |56| external-dns | Helm | `kubernetes-sigs/external-dns` chart |5758## Cross-Cutting Concerns5960### CRD Versioning6162CRD API versions progress: `v1alpha1` → `v1beta1` → `v1`. Before upgrading:6364```bash65# check stored versions66kubectl get crd kafkas.kafka.strimzi.io -o jsonpath='{.status.storedVersions}'6768# list all CRDs for an operator69kubectl get crd | grep strimzi.io70```7172- Back up CRDs before upgrades: `kubectl get crd <name> -o yaml > backup.yaml`73- Check operator release notes for deprecated API versions74- Conversion webhooks handle version translation — verify they're running after upgrade7576### Upgrade Strategies7778General operator upgrade checklist:79801. Read release notes and breaking changes812. Back up CRDs and CRs: `kubectl get <crd> -A -o yaml > backup.yaml`823. Check CRD version compatibility between old and new operator834. Upgrade operator (Helm: `helm upgrade --atomic --wait`, OLM: update subscription channel)845. Verify operator pod is healthy: `kubectl get pods -n <operator-ns>`856. Verify managed resources reconciled: check CR `.status.conditions`867. Run smoke tests against managed workloads8788Rolling vs recreate:89- Most operators tolerate rolling updates (leader election handles handoff)90- Recreate if operator doesn't support leader election or runs as singleton9192Canary upgrades:93- Run old + new operator in different namespaces with `WATCH_NAMESPACE` scoping94- Validate new operator on non-production namespace before cluster-wide rollout9596Deploy the [Strimzi Drain Cleaner](https://github.com/strimzi/drain-cleaner) for graceful pod eviction during node maintenance — it ensures brokers are rolled safely when nodes are drained.9798### Monitoring Operator Health99100All controller-runtime operators expose standard metrics:101102```yaml103# key metrics to watch104controller_runtime_reconcile_total{result="error"} # reconciliation failures105controller_runtime_reconcile_time_seconds # reconciliation latency106workqueue_depth # pending reconciliations107workqueue_longest_running_processor_seconds # stuck reconciliations108```109110ServiceMonitor for operator pods:111112```yaml113apiVersion: monitoring.coreos.com/v1114kind: ServiceMonitor115metadata:116 name: strimzi-operator117 namespace: monitoring118spec:119 namespaceSelector:120 matchNames: [strimzi-system]121 selector:122 matchLabels:123 app: strimzi-cluster-operator124 endpoints:125 - port: http126 path: /metrics127 interval: 30s128```129130Alert on reconciliation failures:131132```yaml133apiVersion: monitoring.coreos.com/v1134kind: PrometheusRule135metadata:136 name: operator-health137 namespace: monitoring138spec:139 groups:140 - name: operator-health141 rules:142 - alert: OperatorReconcileErrors143 expr: rate(controller_runtime_reconcile_total{result="error"}[5m]) > 0144 for: 10m145 labels:146 severity: warning147 annotations:148 summary: "Operator {{ $labels.controller }} has reconciliation errors"149```150151### Resource Sizing152153Use Guaranteed QoS (requests == limits for CPU and memory) for all operator-managed workloads in production. Burstable pods under node pressure get OOM-killed first, triggering cascading failures.154155### RBAC Patterns156157- Operators need cluster-wide RBAC for CRDs by default158- Namespace-scoped operators: set `WATCH_NAMESPACE` env var to restrict scope159- Audit operator ClusterRole after install — remove unused rules for least-privilege160- Multi-tenant: one operator per namespace vs cluster-wide with namespace filtering161162```bash163# audit what an operator service account can do164kubectl auth can-i --list --as=system:serviceaccount:strimzi-system:strimzi-cluster-operator165```166167### Namespace Strategy168169- Dedicated namespace per operator: `strimzi-system`, `cert-manager`, `monitoring`, `external-dns`170- Workload CRs (Kafka, Certificate, ServiceMonitor) live in application namespaces171- Operators watch across namespaces unless restricted via `WATCH_NAMESPACE`172- Label namespaces for selective operator targeting where supported173174## Troubleshooting Workflow175176Generic operator troubleshooting checklist:1771781. **Operator pod healthy?**179 `kubectl get pods -n <operator-ns>` — check Ready, restarts1802. **Operator logs?**181 `kubectl logs -n <operator-ns> deploy/<operator-name> --tail=100`1823. **CR status conditions?**183 `kubectl get <cr> <name> -o yaml` — check `.status.conditions` for errors1844. **Events?**185 `kubectl get events -n <ns> --sort-by='.lastTimestamp' --field-selector=reason!=Pulled`1865. **RBAC?**187 `kubectl auth can-i --as=system:serviceaccount:<ns>:<sa> <verb> <resource>`1886. **CRDs installed?**189 `kubectl get crd | grep <operator-domain>`1907. **Webhooks?**191 `kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations`192193## Validation Loop1941951. Apply CR → check operator logs → check CR `.status` → fix → repeat1962. For upgrades: pre-upgrade checks → upgrade → post-upgrade verification → rollback if needed1973. For new operator installs: install operator → verify CRDs exist → apply test CR → verify reconciliation198199## Deep-dive References200201### Strimzi (Kafka)202- `patterns/strimzi/cluster-setup.md` — KRaft cluster provisioning, node pools203- `patterns/strimzi/listeners-and-storage.md` — Listener types, authentication, JBOD, volume expansion204- `patterns/strimzi/topics-and-users.md` — KafkaTopic, KafkaUser, ACLs205- `patterns/strimzi/kafka-connect.md` — Connectors, plugin builds, Connect ACLs206- `patterns/strimzi/mirror-maker.md` — MirrorMaker2, cross-cluster replication207208### Keycloak209- `patterns/keycloak/realm-configuration.md` — Realm CRs, export/import, settings210- `patterns/keycloak/identity-providers.md` — OIDC, SAML, social providers211- `patterns/keycloak/client-setup.md` — Clients, scopes, service accounts212- `patterns/keycloak/customization.md` — Themes, SPIs, custom providers213214### kube-prometheus-stack215- `patterns/kube-prometheus-stack/service-monitors.md` — ServiceMonitor, PodMonitor216- `patterns/kube-prometheus-stack/alerting-rules.md` — PrometheusRule, routing217- `patterns/kube-prometheus-stack/grafana-dashboards.md` — Dashboard provisioning218- `patterns/kube-prometheus-stack/thanos-integration.md` — Long-term storage219220### cert-manager221- `patterns/cert-manager/issuers.md` — Issuer, ClusterIssuer, ACME, CA, Vault222- `patterns/cert-manager/certificates.md` — Certificate lifecycle, renewal223- `patterns/cert-manager/webhook-solvers.md` — HTTP01, DNS01 solvers224225### external-dns226- `patterns/external-dns/provider-setup.md` — DNS provider configuration227- `patterns/external-dns/source-configuration.md` — Ingress/Service/Gateway sources228- `patterns/external-dns/ownership-and-policy.md` — TXT records, policy modes229230## Official References231232- [Strimzi Documentation](https://strimzi.io/documentation/)233- [Keycloak Operator Guide](https://www.keycloak.org/operator/installation)234- [kube-prometheus-stack Chart](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack)235- [cert-manager Documentation](https://cert-manager.io/docs/)236- [external-dns Documentation](https://kubernetes-sigs.github.io/external-dns/)