WazuhCluster reference¶
apiVersion: wazuh.bnerd.com/v1alpha1, kind: WazuhCluster (namespaced).
Spec¶
| Field | Type | Default | Description |
|---|---|---|---|
version |
string | 4.14.5 |
Wazuh release for all component images. |
deploymentMode |
enum | ha |
ha or single-node. |
imageRegistry |
string | wazuh |
Registry/namespace prefix for images. |
indexer.replicas |
int | 3 (ha) / 1 (single) | Indexer nodes. |
indexer.image |
string | derived | Override indexer image. |
indexer.heapSize |
string | derived | OpenSearch JVM heap (-Xms/-Xmx). If unset, derived from indexer.resources.limits.memory (~50%, clamped to [256m, 31g]); falls back to 1g when no memory limit is set. |
indexer.storage.size |
string | 50Gi |
Indexer PVC size. |
indexer.storage.storageClassName |
string | cluster default | Indexer storage class. |
indexer.resources |
ResourceRequirements | 500m / 2Gi |
Indexer container resources (default applied when unset). |
indexer.extraConfig |
string | – | Appended to opensearch.yml. |
indexer.podDisruptionBudget.enabled |
bool | true (≥2 replicas) |
Create a PodDisruptionBudget (maxUnavailable: 1) protecting indexer quorum on node drains. Never created below 2 replicas. |
indexer.tuneMaxMapCount |
bool | true |
Run a privileged init container to set vm.max_map_count=262144. Set false on PSA-restricted clusters that pre-tune the sysctl at the node pool. |
indexer.retention.enabled |
bool | false |
Apply an OpenSearch ISM policy that deletes old wazuh-alerts-*/wazuh-archives-* indices. Opt-in (deletes security data). |
indexer.retention.days |
int | 90 |
Index age after which indices are deleted when retention is enabled. |
manager.image |
string | derived | Override manager image (master + workers). |
manager.config.fileIntegrityMonitoring.enabled |
bool | true |
FIM (syscheck) on/off. |
manager.config.fileIntegrityMonitoring.directories |
[]string | baseline set | FIM monitored paths. |
manager.config.vulnerabilityDetection.enabled |
bool | true |
Vulnerability detection on/off. |
manager.config.securityConfigurationAssessment.enabled |
bool | true |
SCA on/off. |
manager.config.extraConfig |
string | – | Raw XML appended inside <ossec_config>. |
manager.config.customRules |
map[string]string | – | Custom rule files (name→XML) placed in etc/rules (synced to workers). |
manager.config.customDecoders |
map[string]string | – | Custom decoder files (name→XML) placed in etc/decoders. |
manager.config.cdbLists |
map[string]string | – | CDB lists (name→content) placed in etc/lists. |
manager.alerts.logLevel |
int | 3 |
Minimum alert severity (1-16). |
manager.alerts.email.enabled |
bool | false |
Enable SMTP email alerts. |
manager.alerts.email.smtpServer / .from / .to[] |
string(s) | – | SMTP settings. |
manager.master.storage |
StorageSpec | 50Gi |
Master PVC. |
manager.master.resources |
ResourceRequirements | 250m / 1536Mi |
Master resources (default when unset). |
manager.workers.replicas |
int | 2 (ha) / 0 (single) | Worker nodes. |
manager.workers.storage |
StorageSpec | 50Gi |
Worker PVC. |
manager.workers.resources |
ResourceRequirements | 250m / 1536Mi |
Worker resources (default when unset). |
manager.workers.podDisruptionBudget.enabled |
bool | true (≥2 replicas) |
Create a PodDisruptionBudget (maxUnavailable: 1) for the workers. Never created below 2 replicas (so off in single-node). |
dashboard.replicas |
int | 1 | Dashboard pods. |
dashboard.image |
string | derived | Override dashboard image. |
dashboard.resources |
ResourceRequirements | 100m / 1536Mi |
Dashboard resources (default when unset). |
dashboard.service.type |
enum | ClusterIP |
ClusterIP/NodePort/LoadBalancer. |
dashboard.ingress.enabled |
bool | false |
Create an Ingress for the dashboard. |
dashboard.ingress.host |
string | – | Ingress host. |
dashboard.ingress.className |
string | – | ingressClassName. |
dashboard.ingress.tls.enabled |
bool | false |
Enable Ingress TLS. |
dashboard.ingress.tls.secretName |
string | dashboard cert | TLS secret. |
agentService.type |
enum | ClusterIP |
Exposure for enrollment (1515), events (1514), API (55000). |
tls.caSecretRef |
string | – | Existing CA secret (tls.crt/tls.key); self-signed if empty. |
credentials.credentialsSecret |
string | <name>-credentials |
Secret holding credentials; set automatically after scrubbing inline values. |
credentials.adminPassword |
string | generated | Indexer admin password (inline; scrubbed into the Secret). |
credentials.kibanaserverPassword |
string | generated | Dashboard→indexer password (inline; scrubbed). |
credentials.apiPassword |
string | generated | Wazuh API password (inline; scrubbed). |
credentials.registrationPassword |
string | generated | Agent enrollment password / authd.pass (inline; scrubbed). |
credentials.clusterKey |
string | generated | Manager cluster key (inline; scrubbed). |
backup.enabled |
bool | false |
Register a snapshot repository and run scheduled snapshots. |
backup.type |
enum | filesystem |
filesystem (shared volume) or s3 (repository-s3 plugin). |
backup.schedule |
string | 0 1 * * * |
Cron schedule for snapshots. |
backup.storage.size / .storageClassName |
string | 50Gi |
Shared snapshot volume (filesystem backend; RWX for HA). |
backup.s3.bucket / .endpoint / .region / .pathPrefix |
string | – | S3 repository settings (s3 backend). |
backup.s3.credentialsSecret |
string | – | Secret with access_key/secret_key for the bucket. |
backup.s3.pluginImage |
string | opensearchproject/opensearch:2.19.5 |
Version-matched image used to install repository-s3 (needs network). |
networkPolicy.enabled |
bool | false |
Create per-component ingress NetworkPolicies (needs a CNI that enforces them). |
Inline credentials.* plaintext is written into the Secret and then removed from the CR,
which is rewritten to reference credentialsSecret. See
TLS & Credentials.
Status¶
| Field | Description |
|---|---|
phase |
Pending / Provisioning / Ready / Degraded / Failed. |
observedVersion |
Version actually running (advances only when fully rolled out). |
appliedSecurityRevision |
Credential revision currently applied to the indexer; drives rotation re-keying. |
appliedRestore |
Snapshot name last restored (via the wazuh.bnerd.com/restore-snapshot annotation). |
appliedCertRotation |
Value of the wazuh.bnerd.com/rotate-certificates annotation last acted on; change the annotation to re-issue leaf certs. |
endpoints.dashboard / .agentEnrollment / .indexer |
Reachable endpoints. |
indexer / managerMaster / managerWorkers / dashboard |
readyReplicas / desiredReplicas. |
conditions[] |
CertificatesReady, IndexerReady, ManagerReady, DashboardReady, Ready. |
Example (HA)¶
apiVersion: wazuh.bnerd.com/v1alpha1
kind: WazuhCluster
metadata:
name: acme
namespace: wazuh-acme
spec:
deploymentMode: ha
indexer:
replicas: 3
storage:
size: 100Gi
storageClassName: fast-ssd
manager:
workers:
replicas: 2
dashboard:
ingress:
enabled: true
host: wazuh.acme.example.com
className: nginx
tls:
enabled: true
agentService:
type: LoadBalancer
Full examples live in the repository under
examples/.
Validation¶
The CRD rejects invalid manifests at kubectl apply time using CEL
(x-kubernetes-validations), which requires Kubernetes ≥ 1.25 (CEL validation
is GA in 1.29; on older API servers these rules are silently skipped). The enforced
cross-field invariants are:
deploymentMode: harequiresindexer.replicas ≥ 3(OpenSearch master quorum).deploymentMode: single-noderequiresindexer.replicas == 1and no manager workers.backup.type: s3requiresbackup.s3.bucketto be set.
A few rules cannot be expressed in CEL (they need quantity math or old-vs-new
comparison) and are enforced by the optional validating admission webhook
(webhook.enabled in the chart, off by default):
indexer.heapSizemust not exceedindexer.resources.limits.memory(else the JVM OOMs).- The indexer may not be scaled below its 3-node quorum on an
hacluster.
See the Security Hardening guide for how to enable the webhook.