Skip to main content

Define Preflight Checks for KOTS

This topic provides a basic understanding and some key considerations about preflight checks for Replicated KOTS installations that use standard Kubernetes manifests or Kubernetes Operators to help guide you in defining them for your application.

For information about defining preflight checks for Helm charts, see Define Preflight Checks for Helm Charts.

About KOTS Preflight Checks

You define preflight checks based on your application needs. Replicated recommends that you use preflight checks to help ensure that your customers' environments support your application before installing the application.

Preflights checks for KOTS and kURL run automatically before the application is installed.

Preflight checks are not included by default, so you must enable them. For KOTS entitlements, you add a Preflight custom resource to your release to define preflight checks for standard Kubernetes manifests and Kubernetes Operators.

note

Introduced in KOTS v1.101.0

If you have already created a KOTS release using Helm charts and want to add support for Helm installations, Replicated recommends defining preflight checks directly in the Helm charts. This lets you maintain one set of preflight specifications for all installation types.

Preflights specified in the Helm chart override the Preflight custom resource used by KOTS. During installation, if KOTS cannot find preflights specified in the Helm chart archive, then KOTS searches for kind: Preflight in the root of the release. See Define Preflight Checks for Helm Charts.

Create a Preflight Custom Resource

To define preflight checks for KOTS installations, you add the Preflight custom resource (kind: Preflight) to your release.

The following example shows a basic Preflight custom resource in your release.

For more information about the Preflight custom resource, see Preflight and Support Bundle.

apiVersion: troubleshoot.sh/v1beta2
kind: Preflight
metadata:
name: preflights
spec:
collectors: []
analyzers: []

Next, define the preflight checks specification by adding collectors and analyzers. Optionally, you can add to the default redactors. For more information, see Define the Preflight Checks Specification.

Define the Preflight Checks Specification

Any preflight checks you run are dependent on your application needs. This section gives some guidance about how to think about using collectors and analyzers to design preflight checks.

For more information about defining collectors and analyzers, see Collecting Data and Analyzing Data in the Troubleshoot documentation.

Collectors

Add collectors to define information to be collected for analysis during the analyze phase. For example, you can collect information about the MySQL version that is running in a cluster:

apiVersion: troubleshoot.sh/v1beta2
kind: Preflight
metadata:
name: supported-mysql-version
spec:
collectors:
- mysql:
collectorName: mysql
uri: 'repl{{ ConfigOption "db_user" }}:repl{{ConfigOption "db_password" }}@tcp(repl{{ ConfigOption "db_host" }}:repl{{ConfigOption "db_port" }})/repl{{ ConfigOption "db_name" }}'

Replicated recommends using a template function for the URI, as shown above, to avoid exposing sensitive information. For more information about template functions, see About Template Functions.

For more information about defining collectors and analyzers, see Collecting Data and Analyzing Data in the Troubleshoot documentation.

Analyzers

You must add analyzers to analyze the data from the collectors that you specified. Define the criteria for the pass, fail, and warn outcomes, and specify custom messages for each.

For example, you can set a fail outcome if the MySQL version is less than the minimum required. Then, specify a message to display that informs your customer of the reasons for the failure and steps they can take to fix the issue.

spec:
collectors:
- mysql:
collectorName: mysql
uri: 'repl{{ ConfigOption "db_user" }}:repl{{ConfigOption "db_password" }}@tcp(repl{{ ConfigOption "db_host" }}:repl{{ConfigOption "db_port" }})/repl{{ ConfigOption "db_name" }}'
analyzers:
- mysql:
checkName: Must be MySQL 8.x or later
collectorName: mysql
outcomes:
- fail:
when: connected == false
message: Cannot connect to MySQL server
- fail:
when: version < 8.x
message: The MySQL server must be at least version 8
- pass:
message: The MySQL server is ready

For more information about defining collectors and analyzers, see Collecting Data and Analyzing Data in the Troubleshoot documentation.

For basic examples of checking CPU, memory, and disk capacity, see Node Resources Analyzer in the Troubleshoot documentation.

strict Analyzers

You can set any preflight analyzers to strict: true if you want to enforce requirements for the chosen analyzers. For more information about strict preflight checks, see strict in the Troubleshoot documentation.

Note the following considerations:

  • Any fail outcomes for that analyzer block the deployment of the release until your specified requirement is met.
  • If a strict collector requires cluster scope and minimal RBAC mode is set, then the collector is skipped during the preflight check.
  • Strict preflight analyzers are ignored if the exclude flag is also used.

For more information about cluster privileges, see requireMinimalRBACPrivileges for name-scoped access in Configuring Role-Based Access.

The following example shows the strict field set to true for MySQL versions:

spec:
collectors:
- mysql:
collectorName: mysql
uri: 'repl{{ ConfigOption "db_user" }}:repl{{ConfigOption "db_password" }}@tcp(repl{{ ConfigOption "db_host" }}:repl{{ConfigOption "db_port" }})/repl{{ ConfigOption "db_name" }}'
analyzers:
- mysql:
strict: true
checkName: Must be MySQL 8.x or later
collectorName: mysql
outcomes:
- fail:
when: connected == false
message: Cannot connect to MySQL server
- fail:
when: version < 8.x
message: The MySQL server must be at least version 8
- pass:
message: The MySQL server is ready

For more information about defining collectors and analyzers, see Collecting Data and Analyzing Data in the Troubleshoot documentation.

Example

The following example shows a preflight support bundle specification for a KOTS installation. For more examples, see the Troubleshoot example repository in GitHub.

For more information about defining collectors and analyzers, see Collecting Data and Analyzing Data in the Troubleshoot documentation.

apiVersion: troubleshoot.sh/v1beta2
kind: Preflight
metadata:
name: supported-mysql-version
spec:
collectors:
- mysql:
collectorName: mysql
uri: 'repl{{ ConfigOption "db_user" }}:repl{{ConfigOption "db_password" }}@tcp(repl{{ ConfigOption "db_host" }}:repl{{ConfigOption "db_port" }})/repl{{ ConfigOption "db_name" }}'
analyzers:
- mysql:
strict: true
checkName: Must be MySQL 8.x or later
collectorName: mysql
outcomes:
- fail:
when: connected == false
message: Cannot connect to MySQL server
- fail:
when: version < 8.x
message: The MySQL server must be at least version 8
- pass:
message: The MySQL server is ready
- clusterVersion:
outcomes:
- fail:
when: "< 1.20.0"
message: This application requires at least Kubernetes 1.20.0, and recommends 1.22.0.
uri: https://www.kubernetes.io
- warn:
when: "< 1.22.0"
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.22.0 or later.
uri: https://kubernetes.io
- pass:
when: ">= 1.22.0"
message: Your cluster meets the recommended and required versions of Kubernetes.
- containerRuntime:
outcomes:
- pass:
when: "== containerd"
message: containerd container runtime was found.
- fail:
message: Did not find containerd container runtime.
- storageClass:
checkName: Required storage classes
storageClassName: "default"
outcomes:
- fail:
message: Could not find a storage class called default.
- pass:
message: All good on storage classes
- nodeResources:
checkName: Must have at least 3 nodes in the cluster, with 5 recommended
outcomes:
- fail:
when: "count() < 3"
message: This application requires at least 3 nodes.
uri: https://kurl.sh/docs/install-with-kurl/adding-nodes
- warn:
when: "count() < 5"
message: This application recommends at last 5 nodes.
uri: https://kurl.sh/docs/install-with-kurl/adding-nodes
- pass:
message: This cluster has enough nodes.
- nodeResources:
checkName: Every node in the cluster must have at least 8 GB of memory, with 32 GB recommended
outcomes:
- fail:
when: "min(memoryCapacity) < 8Gi"
message: All nodes must have at least 8 GB of memory.
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
- warn:
when: "min(memoryCapacity) < 32Gi"
message: All nodes are recommended to have at least 32 GB of memory.
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
- pass:
message: All nodes have at least 32 GB of memory.
- nodeResources:
checkName: Total CPU Cores in the cluster is 4 or greater
outcomes:
- fail:
when: "sum(cpuCapacity) < 4"
message: The cluster must contain at least 4 cores
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
- pass:
message: There are at least 4 cores in the cluster
- nodeResources:
checkName: Every node in the cluster must have at least 40 GB of ephemeral storage, with 100 GB recommended
outcomes:
- fail:
when: "min(ephemeralStorageCapacity) < 40Gi"
message: All nodes must have at least 40 GB of ephemeral storage.
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
- warn:
when: "min(ephemeralStorageCapacity) < 100Gi"
message: All nodes are recommended to have at least 100 GB of ephemeral storage.
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
- pass:
message: All nodes have at least 100 GB of ephemeral storage.

Next Step

Save and promote the release to a development environment to test your changes. For more information about installing with KOTS, see About Installing an Application.