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.
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.