Using Kustomize with Workload Cluster Manifests
Although the clusterctl generate cluster
command exposes a number of different configuration values
for customizing workload cluster YAML manifests, some users may need additional flexibility above
and beyond what clusterctl generate cluster
or the example “flavor” templates that some CAPI providers
supply (as an example, see these flavor templates
for the Cluster API Provider for Azure). In the future, a templating solution
may be integrated into clusterctl
to help address this need, but in the meantime users can use
kustomize
as a solution to this need.
This document provides a few examples of using kustomize
with Cluster API. All of these examples
assume that you are using a directory structure that looks something like this:
.
├── base
│ ├── base.yaml
│ └── kustomization.yaml
└── overlays
├── custom-ami
│ ├── custom-ami.json
│ └── kustomization.yaml
└── mhc
├── kustomization.yaml
└── workload-mhc.yaml
In the overlay directories, the “base” (unmodified) Cluster API configuration (perhaps generated using
clusterctl generate cluster
) would be referenced as a resource in kustomization.yaml
using ../../base
.
Example: Using Kustomize to Specify Custom Images
Users can use kustomize
to specify custom OS images for Cluster API nodes. Using the Cluster API
Provider for AWS (CAPA) as an example, the following kustomization.yaml
would leverage a JSON 6902 patch
to modify the AMI for nodes in a workload cluster:
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patchesJson6902:
- path: custom-ami.json
target:
group: infrastructure.cluster.x-k8s.io
kind: AWSMachineTemplate
name: ".*"
version: v1alpha3
The referenced JSON 6902 patch in custom-ami.json
would look something like this:
[
{ "op": "add", "path": "/spec/template/spec/ami", "value": "ami-042db61632f72f145"}
]
This configuration assumes that the workload cluster only uses MachineDeployments. Since
MachineDeployments and the KubeadmControlPlane both leverage AWSMachineTemplates, this kustomize
configuration would catch all nodes in the workload cluster.
Example: Adding a MachineHealthCheck for a Workload Cluster
Users could also use kustomize
to combine additional resources, like a MachineHealthCheck (MHC), with the
base Cluster API manifest. In an overlay directory, specify the following in kustomization.yaml
:
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- workload-mhc.yaml
The content of the workload-mhc.yaml
file would be the definition of a standard MHC:
apiVersion: cluster.x-k8s.io/v1alpha3
kind: MachineHealthCheck
metadata:
name: md-0-mhc
spec:
clusterName: test
# maxUnhealthy: 40%
nodeStartupTimeout: 10m
selector:
matchLabels:
cluster.x-k8s.io/deployment-name: md-0
unhealthyConditions:
- type: Ready
status: Unknown
timeout: 300s
- type: Ready
status: "False"
timeout: 300s
You would want to ensure the clusterName
field in the MachineHealthCheck manifest appropriately
matches the name of the workload cluster, taking into account any transformations you may have specified
in kustomization.yaml
(like the use of “namePrefix” or “nameSuffix”).
Running kustomize build .
with this configuration would append the MHC to the base
Cluster API manifest, thus creating the MHC at the same time as the workload cluster.
Modifying Names
The kustomize
“namePrefix” and “nameSuffix” transformers are not currently “Cluster API aware.”
Although it is possible to use these transformers with Cluster API manifests, doing so requires separate
patches for Clusters versus infrastructure-specific equivalents (like an AzureCluster or a vSphereCluster).
This can significantly increase the complexity of using kustomize
for this use case.
Modifying the transformer configurations for kustomize
can make it more effective with Cluster API.
For example, changes to the nameReference
transformer in kustomize
will enable kustomize
to know
about the references between Cluster API objects in a manifest. See
here for more
information on transformer configurations.
Add the following content to the namereference.yaml
transformer configuration:
- kind: Cluster
group: cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/clusterName
kind: MachineDeployment
- path: spec/template/spec/clusterName
kind: MachineDeployment
- kind: AWSCluster
group: infrastructure.cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/infrastructureRef/name
kind: Cluster
- kind: KubeadmControlPlane
group: controlplane.cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/controlPlaneRef/name
kind: Cluster
- kind: AWSMachine
group: infrastructure.cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/infrastructureRef/name
kind: Machine
- kind: KubeadmConfig
group: bootstrap.cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/bootstrap/configRef/name
kind: Machine
- kind: AWSMachineTemplate
group: infrastructure.cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/template/spec/infrastructureRef/name
kind: MachineDeployment
- path: spec/infrastructureTemplate/name
kind: KubeadmControlPlane
- kind: KubeadmConfigTemplate
group: bootstrap.cluster.x-k8s.io
version: v1alpha3
fieldSpecs:
- path: spec/template/spec/bootstrap/configRef/name
kind: MachineDeployment
Including this custom configuration in a kustomization.yaml
would then enable the use of simple
“namePrefix” and/or “nameSuffix” directives, like this:
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
configurations:
- namereference.yaml
namePrefix: "blue-"
nameSuffix: "-dev"
Running kustomize build.
with this configuration would modify the name of all the Cluster API
objects and the associated referenced objects, adding “blue-” at the beginning and appending “-dev”
at the end.