Skip to main content
Version: 0.4.0-beta

Cluster Wizard Deployment

This guide covers the installation of Cluster Wizard.
Cluster Wizard is deployed as a Kubernetes workload, so you must have a functional Kubernetes cluster to host its services. Once Cluster Wizard is installed, you can interact with it using either the Wizard Client or the Wizard Client Web UI.

Prerequisites​

Before you start, ensure the following are available:

  • A valid Cluster Wizard license file is required. You will create a Kubernetes secret from this file during installation.
  • A running Kubernetes cluster. Cluster Admin privileges are recommended, though a namespace admin role may be sufficient.
    • Please see quick-start for a K3s or docker Compose deployment.
  • A default storage class with a working provisioner.
    • If a default storage class is not available, you must be able to manually create and bind PersistentVolumeClaims (PVCs).
    • Verify Kubernetes storage class is present
    kubectl get storageclasses.storage.k8s.io
  • A Kubernetes-compatible load balancer (e.g., MetalLB or LoxiLB) if you plan to expose Cluster Wizard using the LoadBalancer service type.
  • An ingress controller (e.g., NGINX or HAProxy) must be installed if you plan to expose Cluster Wizard using Kubernetes Ingress.
  • Optional: Cert Manager for automatic certificate management to simplify handling mTLS certificates Cert Manager
  • A node to manage with Node Wizard installed.

Requirements​

In addition to the above prerequisites, ensure the following for installation:

  • Access to Cluster Wizard Helm charts. The cluster must have outbound network access to: https://charts.cluster-wizard.com/
  • Prepared Kubernetes secrets. This guide will walk you through generating and creating these secrets:
    • Cluster Wizard client CA certificate
    • Cluster Wizard server certificate

Cluster Wizard Deployment Video​


Getting Started - Installing Cluster Wizard​

Installation Preparation​

Adding Helm Repository​

Cluster Wizard's helm charts are available at https://charts.cluster-wizard.com. A matching helm chart version for Cluster Wizard 0.4.x versions is 0.1.0. Cluster Wizard's chart can be obtained with the following steps:

helm repo add cluster-wizard https://charts.cluster-wizard.com/  
helm repo update cluster-wizard
helm search repo cluster-wizard --versions
helm fetch cluster-wizard/cluster-wizard --version 0.1.0 --untar

Required Helm values​

Below is a minimal set of helm values needed to deploy Cluster Wizard.

  • licenseSecretName: name of the license secret
  • clusterWizardCert.clientCASecretName: name of the client CA cert secret
  • clusterWizardCert.serverSecretName: name of the server cert secret
  • admin user information
    • adminUser
    • adminEmail
  • configuration needed for Postgres
    • postgres.install.install
    • postgres.password
    • postgres.cwPassword
    • postgres.host

Here we utilize a loadBalancer set by expose.type to assign an IP to our service. It is possible to change the expose setup to other methods.

Example cluster-wizard-values-override.yaml:

licenseSecretName: "cw-license"

clusterWizardCert:
clientCASecretName: "client-ca"
serverSecretName: "cluster-wizard-cert"

adminUser: "cluster-wizard-admin"
adminEmail: "cluster-wizard-admin@corespeq.com"

postgres:
install:
install: true
password: "supersecret"
cwPassword: "supersecretToo"

expose:
type: loadBalancer
loadBalancer:
IP: "192.168.100.100"
important

The names of your secrets (cw-license, client-ca, cluster-wizard-cert) must exactly match what you define in cluster-wizard-values-override.yaml. Otherwise, installation will fail with ContainerCreating errors.

Preparing Secrets for License and Certificates​

Cluster Wizard requires a license, a client CA certificate, and a server certificate. Set the license secret with:

kubectl create namespace cluster-wizard

kubectl create secret generic cw-license -n cluster-wizard \
--from-file=license=cluster-wizard-040.lic
Self Managed Certificates​

If the CA cert and server cert files are already present, deploy the secrets using the following commands:

kubectl create secret tls cluster-wizard-cert -n cluster-wizard \
--cert=server/server_cert.pem \
--key=server/server_key.pem

kubectl create secret tls client-ca -n cluster-wizard \
--cert=CA/client_ca_cert.pem \
--key=CA/client_ca_key.pem

Alternatively, you may use Cert Manager for automatic certificate management.

Cert Manager Managed Certificates​
  1. Create a Cert Manager Issuer, cluster-wizard-issuer.yaml:
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: cluster-wizard-issuer
namespace: cluster-wizard
spec:
selfSigned: {}
kubectl apply -f cluster-wizard-issuer.yaml
  1. Create Client CA, client-ca.yaml:
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: client-ca
namespace: cluster-wizard
spec:
isCA: true
commonName: CORESPEQ INC
secretName: client-ca
privateKey:
algorithm: RSA
encoding: PKCS8
size: 2048
duration: 87600h
issuerRef:
name: cluster-wizard-issuer
kind: Issuer
kubectl apply -f client-ca.yaml
  1. Create Server CA, server-ca.yaml:
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: server-ca
namespace: cluster-wizard
spec:
isCA: true
commonName: CORESPEQ INC
secretName: server-ca
privateKey:
algorithm: ECDSA
size: 521
duration: 87600h
issuerRef:
name: cluster-wizard-issuer
kind: Issuer
kubectl apply -f server-ca.yaml
  1. Create a Cert Manager Issuer that uses the Server CA, issuer-with-server-ca.yaml:
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: issuer-with-server-ca
namespace: cluster-wizard
spec:
ca:
secretName: server-ca
kubectl apply -f issuer-with-server-ca.yaml
  1. Create Certificate used by Cluster Wizard, cluster-wizard-cert.yaml:
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cluster-wizard-cert
namespace: cluster-wizard
spec:
dnsNames:
- cluster-wizard
secretName: cluster-wizard-cert
issuerRef:
name: issuer-with-server-ca
kind: Issuer
subject:
organizations:
- CORESPEQ INC
organizationalUnits:
- Cluster Wizard Team
note

The dnsNames specified in cluster-wizard-cert.yaml will need to be available via a DNS service to the Wizard Client. If DNS is not an option consider using ipAddresses instead of dnsNames.

...
spec:
ipAddresses:
- 192.168.100.100
...
kubectl apply -f cluster-wizard-cert.yaml

Install Cluster Wizard​

helm install cluster-wizard ./cluster-wizard \
--version 0.1.0 \
--namespace cluster-wizard \
-f cluster-wizard-values-override.yaml

Verifying Installation​

  • Check pod status for running state:
kubectl get pods -n cluster-wizard
NAME READY STATUS RESTARTS AGE
cluster-wizard-7f567f57f5-7f5tl 1/1 Running 0 5m05s
cluster-wizard-postgres-7b8f7b885-7b8xl 1/1 Running 0 5m05s
  • Check service exposure:
kubectl get svc -n cluster-wizard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-wizard-svc ClusterIP 10.233.52.203 192.168.100.100 50001/TCP 5m05s
postgres-service ClusterIP 10.233.13.17 <none> 5432/TCP 5m05s
  • Check logs:
kubectl logs deployment/cluster-wizard -n cluster-wizard
2025/05/05 05:05:05 START of check license
2025/05/05 05:05:05 get current time from time server
2025/05/05 05:05:05 Starting cluster-wizard ... : 0.4.0
2025/05/05 05:05:05 CEPH_USER: CEPH_POOL: CEPH_ENABLE:false host:postgres-service
2025/05/05 05:05:05 START of check ceph status
2025/05/05 05:05:05 CEPH disabled
2025/05/05 05:05:05 Creating ServerKeyPair:
2025/05/05 05:05:05 loading: /cluster_wizard/server_cert.pem
2025/05/05 05:05:05 loading: /cluster_wizard/server_key.pem
2025/05/05 05:05:05 Creating Client Cert Pool
2025/05/05 05:05:05 loading: /cluster_wizard/client_ca_cert.pem

Next Steps​

Before using any clients, the admin credentials need to be obtained from the Kubernetes secret admin-cred created by the Cluster Wizard. Use the following commands to get the admin certificate and key.

kubectl get secret admin-cred -n cluster-wizard -o jsonpath='{.data.cert}' | base64 -d > admin-cert.crt

kubectl get secret admin-cred -n cluster-wizard -o jsonpath='{.data.private_key}' | base64 -d > admin-private.key

Install and configure Wizard Client or Wizard Client Web UI to access Cluster Wizard.

Once Wizard Client is installed the admin certificate and key can be used to access Cluster Wizard. If the above basic cluster-wizard-values-override.yaml was applied, Cluster Wizard is exposed via loadBalancer.

Obtain the service IP with the following command:

kubectl get svc cluster-wizard-svc -n cluster-wizard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-wizard-svc ClusterIP 10.233.52.128 192.168.100.100 50001:31450/TCP 05d

A DNS entry matching the Cluster Wizard certificate needs to be set up. For now, add an entry to the /etc/hosts that matches "cluster-wizard" from the dnsNames entry in cluster-wizard-cert to access Cluster Wizard:

sudo vi /etc/hosts
...
192.168.100.100 cluster-wizard
...

Alternatively, if ipAddresses was used in the server certificate append -s 192.168.100.100 to the wizard-client command.

If Cert Manager was used to setup the server CA, get the certificate with

kubectl get secret cluster-wizard-cert -n cluster-wizard -o jsonpath='{.data.ca\.crt}' | base64 -d > ca_cert.pem

Now Wizard Client can be used to add nodes that have Node Wizard installed.

wizard-client -c hosts -cert admin-cert.crt -ca ./ca_cert.pem  -pkey admin-private.key

Cluster Wizard Helm Values​

Admin User​

The admin account for Cluster Wizard defined by adminUser and adminEmail. These are required values with no defaults.

Example cluster-wizard-values-override.yaml snippet showing Admin User values:

adminUser: "cluster-wizard-admin"
adminEmail: "cluster-wizard-admin@corespeq.com"

Ceph​

Configures Cluster Wizard's Ceph integration, allowing for RBD-backed images for VMs, snapshots, and migration between hosts.

  • ceph.enabled: enables Ceph integration. Default is false
  • ceph.secretName: name of secret containing ceph.conf and ceph keyring
    • conf is the required key for ceph.conf file
    • keyring is the required key for the ceph keyring
  • ceph.pool: ceph pool name used by libvirt
  • ceph.user: ceph user used by libvirt pool

See Ceph Basics for Cluster Wizard for more information about ceph.conf and ceph keyrings.

warning

ceph.conf must contain "keyring = /cluster_wizard/libvirt.keyring"

ceph.conf:

# minimal ceph.conf for 8108d676-8848-11aa-8e88-35b7aac3aa46
[global]
fsid = 8108d676-8848-11aa-8e88-35b7aac3aa46
mon_host = [v2:172.17.3.1:3300/0,v1:172.17.3.1:6789/0] [v2:172.17.3.2:3300/0,v1:172.17.3.2:6789/0] [v2:172.17.3.3:3300/0,v1:172.17.3.3:6789/0]
keyring = /cluster_wizard/libvirt.keyring

libvirt.keyring:

[client.libvirt]
key = CQC+j3xl/bcROhCCBd0aGSfiTIie9gRJEewYRw==

Example secret creation:

kubectl create secret generic cluster-wizard-ceph -n cluster-wizard \
--from-file=conf=ceph.conf \
--from-file=keyring=libvirt.keyring

Example cluster-wizard-values-override.yaml snippet showing ceph values:

ceph:
enabled: true
secretName: "cluster-wizard-ceph"
pool: "libvirt-pool"
user: "libvirt"

values.yaml snippet showing ceph values:

ceph:
enabled: false
secretName: ""
pool: ""
user: ""

Certificates​

Cluster Wizard requires two TLS certificate secrets. A Client CA certificate secret used for signing client certificates and Server certificate secret used for mTLS communication with Wizard Client. These are required values with no defaults.

  • clusterWizardCert.clientCASecretName: name of secret containing client CA certificate in Kubernetes TLS format. Required secret keys:
    • tls.crt: key for the client CA certificate
    • tls.key: key for the private key
  • clusterWizardCert.serverSecretName: name of secret containing server certificate in Kubernetes TLS format. Required secret keys:
    • tls.crt: key for the public certificate
    • tls.key: key for server private key

Example secret creation using already existing certificates:

kubectl create secret tls cluster-wizard-cert -n cluster-wizard \
--cert=server/server_cert.pem \
--key=server/server_key.pem

kubectl create secret tls client-ca -n cluster-wizard \
--cert=CA/client_ca_cert.pem \
--key=CA/client_ca_key.pem

Alternatively, it is possible to use Cert Manager to manage certificates.

Example cluster-wizard-values-override.yaml snippet showing clusterWizardCert:

clusterWizardCert:
clientCASecretName: "client-ca"
serverSecretName: "cluster-wizard-cert"

Expose​

Configures how Cluster Wizard service is exposed:

  • expose.type - controls how cluster wizard service is exposed. Set the service type as "clusterIP", "ingress", "loadBalancer", "nodePort" or "". Default is clusterIP.
    • clusterIP: Used when expose.type is "clusterIP"
      • expose.clusterIP.staticClusterIP - sets the ip address of the ClusterIP service, leave empty for acquiring dynamic ip. Default is ""
      • expose.clusterIP.ports.externalPort - port the cluster-wizard service listens on. Default is "50001"
    • ingress: Used when expose.type is "ingress"
      • expose.ingress.host: URL used for access
      • expose.ingress.controller: set to the type of ingress controller if it has specific requirements. default works for most ingress controllers. Possible values "default", "gce", "ncp", "alb", or "f5-bigip". Default is default.
      • expose.ingress.kubeVersionOverride: Allow .Capabilities.KubeVersion.Version to be overridden while creating ingress
      • expose.ingress.className: Sets the ingress class name, eg "haproxy"
      • expose.ingress.annotations: Optional annotations needed by different ingress providers.
    • loadBalancer: Used when expose.type is "loadBalancer"
      • expose.loadBalancer.IP - specifies the IP address assigned by the loadBalancer. Default is "" for automatic assignment.
      • expose.loadBalancer.ports.externalPort - port the cluster-wizard service listens on. Default is "50001"
      • expose.loadBalancer.sourceRanges - specifies which CIDR IP ranges are allowed to access the LoadBalancer’s external IP. eg: "192.168.100.0/24"
    • nodePort: Used when expose.type is "nodePort"
      • expose.nodePort.ports.externalPort.port - port the cluster-wizard service listens on. Default is "50001"
      • expose.nodePort.ports.externalPort.nodePort - sets the node port the service listens on. Default value is 30002

Example cluster-wizard-values-override.yaml snippet showing expose values with loadBalancer configuration with automatic IP assignment:

expose:
type: loadBalancer

Example cluster-wizard-values-override.yaml snippet showing expose values for nodeport:

expose:
type: nodePort
nodePort:
ports:
externalPort:
port: 50001
nodePort: 30002

Example cluster-wizard-values-override.yaml snippet for ingress using haproxy:

expose:
type: ingress
ingress:
host: cluster-wizard
className: "haproxy"
annotations:
haproxy.org/ssl-passthrough: "true"

values.yaml snippet showing all expose values:

expose:
type: clusterIP
ingress:
host: cluster-wizard
controller: default
kubeVersionOverride: ""
className: ""
annotations:
haproxy.org/ssl-passthrough: "true"
clusterIP:
staticClusterIP: ""
ports:
externalPort: 50001
nodePort:
ports:
externalPort:
port: 50001
nodePort: 30002
loadBalancer:
IP: ""
ports:
externalPort: 50001
sourceRanges: []

Image​

Configures the image repository, tag and pull policy for the cluster-wizard deployment.

  • image.repository: sets the repository used for pulling the image. Default is "clusterwizard/cluster-wizard"
  • image.pullPolicy: controls how the container image is pulled from the repository when starting a pod. Possible values: Always, IfNotPresent, Never. Default is IfNotPresent.
  • image.tag: container tag used when cluster-wizard is installed. Default is "" and will pull Cluster Wizard Version 0.4.0.

values.yaml snippet show image values:

image:
repository: clusterwizard/cluster-wizard
pullPolicy: IfNotPresent
tag: ""

License​

Cluster Wizard requires a valid license to operate. This is a required value with no default.

  • licenseSecretName: name of secret containing the cluster-wizard license. Required secret key:
    • license key containing valid license

Example secret creation:

kubectl create secret generic cw-license -n cluster-wizard \
--from-file=license=cluster-wizard-040.lic

Example cluster-wizard-values-override.yaml snippet showing licenseSecretName:

licenseSecretName: "cw-license" 

Name Overrides​

Configures cluster-wizard's installation names

  • nameOverride:
  • fullnameOverride:

values.yaml snippet showing name overrides:

nameOverride: ""
fullnameOverride: ""

OPA​

Configures cluster-wizard's authorization rules

  • opa.policy: rego policy file to override default authorization rules
  • opa.roles : json file to override default roles

values.yaml snippet show OPA values:

opa:
policy: ""
role: ""

Postgres​

Cluster Wizard requires access to a postgres database. If an external postgres database is not available, Cluster Wizard helm charts can deploy one.

Required values for postgres:

  • postgres.password: password of postgres user
  • postgres.cwPassword: password for the postgres.cwUser database account to be created.
  • postgres.host: where postgres can be accessed.

Example cluster-wizard-values-override.yaml snippet showing postgres values for an existing postgres database:

postgres:
password: "securePostgresPassword"
cwPassword: "secureWizardClientPassword"
cwUser: "cw-admin"
host: "postgres-service"

Example cluster-wizard-values-override.yaml snippet showing postgres values for creating a new postgres database:

postgres:
install:
install: true
password: "supersecret"
cwPassword: "supersecretToo"
cwUser: "cw-admin"
host: "postgres-service"

Optional values for postgres:

SSL:

  • postgres.ssl - sets whether or not the postgres server requires ssl for client connections

Installation:

  • postgres.install.install - controls whether or not postgres is installed by the helm chart. Default is false.

    Image Pull Policy:

    • postgres.install.pullPolicy - controls how the container image is pulled from the repository when starting a pod. Possible values: Always, IfNotPresent, Never. Default is IfNotPresent.

    PVC:

    • postgres.install.pvc.accessMode - sets the accessMode value on the PVC created for postgres. Possible values: ReadWriteOnce, ReadOnlyMany, ReadWriteMany. Provisioner dependent. Default is ReadWriteOnce.
    • postgres.install.pvc.size - sets the size of the PVC created for postgres. Default is 5Gi.
    • postgres.install.pvc.storageClass - set the storage class used for the pvc. Provisioner dependent. Default is "".

    Expose Options:

    • postgres.install.expose.type - controls how cluster wizard postgres service is exposed. Set the service type as "clusterIP", "loadBalancer", "nodePort" or "". Default is clusterIP.
      • clusterIP: used when postgres.install.expose.type is "clusterIP"
        • postgres.install.expose.clusterIP.staticClusterIP - sets the ip address of the ClusterIP service, leave empty for acquiring dynamic ip. Default is ""
      • loadBalancer: used when postgres.install.expose.type is "loadBalancer"
        • postgres.install.expose.loadBalancer.IP - specifies the IP address assigned by the loadBalancer. Default is "" for automatic assignment.
        • postgres.install.expose.loadBalancer.sourceRanges - specifies which CIDR IP ranges are allowed to access the LoadBalancer’s external IP. eg: "192.168.100.0/24"
      • nodePort: used when postgres.install.expose.type is "nodePort"
        • postgres.install.expose.nodePort.ports.externalPort.nodePort - sets the node port the service listens on. Default value is 30002 Postgres Version
  • postgres.tag - container tag used to define which version of postgres is installed. Default is 17.5

Database Populate:

  • postgres.populateDB - controls if cluster wizard populate database with initial values. Default is true

Database User Account

  • postgres.cwUser - Name of the database account used by client. Default is wizard_clients
  • postgres.cwDBName - Name of database. Default is cluster_management

values.yaml snippet showing all postgres values:

postgres:
install:
install: false
pullPolicy: "IfNotPresent"
pvc:
accessMode: "ReadWriteOnce"
size: "5Gi"
storageClass: ""
expose:
type: clusterIP
clusterIP:
staticClusterIP: ""
nodePort:
ports:
externalPort:
nodePort: 30002
loadBalancer:
IP: ""
sourceRanges: [ ]
tag: "17.5"
populateDB: true
password: ""
cwPassword: ""
cwUser: ""
host: "postgres-service"

Troubleshooting​

Quick Diagnostic Commands​

Run these first to quickly assess the situation:

# Check if pods are running
kubectl get pods -n cluster-wizard

# Check for event logs (e.g., FailedMount, CrashLoopBackOff)
kubectl describe pod <pod-name> -n cluster-wizard

# Check Cluster Wizard logs
kubectl logs deployment/cluster-wizard -n cluster-wizard

Common Problems​

The cluster-wizard helm repo is not available​

  • Helm Output:
    • helm search repo cluster-wizard --versions
      No results found
    • helm fetch cluster-wizard/cluster-wizard --version 0.1.0 --untar
      Error: repo cluster-wizard not found
  • Cause: The cluster-wizard helm repo is not available.
  • Solution: Add the cluster-wizard repo. helm repo add cluster-wizard https://charts.cluster-wizard.com/. See Adding Helm Repository for detailed steps.

Missing "cluster-wizard" Kubernetes namespace​

  • Helm Output:
    Error: INSTALLATION FAILED: create: failed to create: namespaces "cluster-wizard" not found
  • Cause: The Kubernetes namespace cluster-wizard has not been created.
  • Solution: Create Kubernetes namespace cluster-wizard. See Preparing Secrets for License and Certificates for instructions on creating the namespace.

Helm release already installed in namespace​

  • Helm Output:

    Error: INSTALLATION FAILED: cannot re-use a name that is still in use
  • Cause: Helm sees a release named cluster-wizard already installed in namespace cluster-wizard. Helm release names must be unique per namespace.

  • Solution:

    1. Check if cluster-wizard is already deployed
    helm list -n cluster-wizard
    1. If you want to update the existing deployment, use:
    helm upgrade --install cluster-wizard ./cluster-wizard \
    --version 0.1.0 \
    --namespace cluster-wizard \
    -f cluster-wizard-values-override.yaml

    This applies your changes to the current release without uninstalling it.

    1. If you want a clean install of the Cluster Wizard deployment:

      a. Delete existing release:

      helm uninstall cluster-wizard -n cluster-wizard

      b. Reinstall Cluster Wizard, see Install Cluster Wizard:

      helm install cluster-wizard ./cluster-wizard  \
      --version 0.1.0 \
      --namespace cluster-wizard \
      -f cluster-wizard-values-override.yaml

Missing Kubernetes secrets required by Cluster Wizard.​

  • Helm Output:
Error: INSTALLATION FAILED: failed post-install: 1 error occurred:
* timed out waiting for the condition
  • Cluster Wizard Pod Status stuck in ContainerCreating

kubectl get pods -n cluster-wizard shows Status: ContainerCreating

kubectl get pods -n cluster-wizard
NAME READY STATUS RESTARTS AGE
cluster-wizard-7f5676d657-9cbvp 0/1 ContainerCreating 0 5m05s
cluster-wizard-postgres-7b8f44985-xncpx 1/1 Running 0 5m05s
create-secret-job-4v4tz 0/1 ContainerCreating 0 5m05s
  • Pod details show MountVolume.SetUp failed

kubectl describe pod cluster-wizard-7f5676d657-9cbvp shows secret "client-ca" not found, secret "cluster-wizard-cert" not found, or secret "cw-license" not found

kubectl describe pod cluster-wizard-7f5676d657-9cbvp -n cluster-wizard
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m05s default-scheduler Successfully assigned cluster-wizard/cluster-wizard-7f5676d657-9cbvp to worker01
Warning FailedMount 5s (x11 over 5m5s) kubelet MountVolume.SetUp failed for volume "secret-volume" : [secret "client-ca" not found, secret "cluster-wizard-cert" not found, secret "cw-license" not found]

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m05s default-scheduler Successfully assigned cluster-wizard/cluster-wizard-7f5676d657-9cbvp to worker01
Warning FailedMount 5s (x11 over 5m5s) kubelet MountVolume.SetUp failed for volume "secret-volume" : secret "cw-license" not found
  • Cause: The secrets referenced by clusterWizardCert.clientCASecretName, clusterWizardCert.serverSecretName or licenseSecretName were not created.
  • Solution: Create required secrets. See installation-preparation.

Invalid Cluster Wizard License​

  • Helm Output:
Error: INSTALLATION FAILED: failed post-install: 1 error occurred:
* job create-secret-job failed: BackoffLimitExceeded
  • Cluster Wizard Pod Status: Error

kubectl get pods -n cluster-wizard shows STATUS: Error

kubectl get pods -n cluster-wizard
NAME READY STATUS RESTARTS AGE
cluster-wizard-7f5676d657-9cbvp 0/1 Error 6 (5m05s ago) 5m05s
cluster-wizard-postgres-7b8f44985-xncpx 1/1 Running 0 5m05s
create-secret-job-gm466 0/1 Error 0 5m05s
create-secret-job-hfrtl 0/1 Error 0 5m05s
create-secret-job-qpmps 0/1 Error 0 5m05s
create-secret-job-wzf5l 0/1 Error 0 5m05s
  • Cluster Wizard Logs

kubectl logs deployment/cluster-wizard -n cluster-wizard shows "[ERROR] : Failed to check license"

kubectl logs deployment/cluster-wizard -n cluster-wizard
2025/05/05 05:05:05 START of check license
2025/05/05 05:05:05 main.go:273: [ERROR] : Failed to check license - invalid character 'i' looking for beginning of value

or

2025/05/05 05:05:05 START of check license
2025/05/05 05:05:05 license.go:63: [ERROR] : unexpected end of JSON input
2025/05/05 05:05:05 main.go:262: [ERROR] : Failed to check license - unexpected end of JSON input
  • Cause: The secret pointed to by licenseSecretName contains an invalid license.
  • Solution: Create a secret containing a Valid Cluster Wizard license file referenced by licenseSecretName. See preparing-secrets-for-license-and-certificates.

Cluster Wizard Postgres pod stuck in pending​

  • Helm Output:
Error: INSTALLATION FAILED: failed post-install: 1 error occurred:
* timed out waiting for the condition
  • cluster-wizard-postgres-* pod status stuck in Pending

kubectl get pods -n cluster-wizard shows Status: Pending for cluster-wizard-postgres-* and Error for postgres-populator-*

kubectl get pods -n cluster-wizard
NAME READY STATUS RESTARTS AGE
cluster-wizard-df35757b8-d9trm 1/1 Running 0 5m05s
cluster-wizard-postgres-7b8f33985-p4qsj 0/1 Pending 0 5m05s
create-secret-job-nrfkv 0/1 Completed 0 5m05s
postgres-populator-m3zg8 0/1 Error 0 5m05s
  • Pod details shows FailedScheduling

kubectl describe pod cluster-wizard-postgres-7b8f44985-p4qsj -n cluster-wizard shows FailedScheduling

  kubectl describe pod cluster-wizard-postgres-7b8f44985-p4qsj -n cluster-wizard
Name: cluster-wizard-postgres-7b8f44985-p4qsj
Namespace: cluster-wizard
...
Status: Pending
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 16m default-scheduler 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
Warning FailedScheduling 6m6s (x2 over 11m) default-scheduler 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
  • Cause: The PersistentVolume needed by the cluster-wizard-postgres container is not available.
  • Solution: Ensure your Kubernetes clusters has a default storage class, with a provisioner or manually create a backing PV for the PVC returned by kubectl get pvc -n cluster-wizard See prerequisites.