clusterctl  • One cli to rule them all

Deepak SharmaDeepak Sharma
6 min read

clusterctl is the defacto cli that Cluster API provides for managing and performing operations. clusterctl has a very nice user interface and experience built into it. The command line predates the Cluster API Operator which is a new Declarative way of running Cluster API stack.

Functions

clusterctl is like a Swiss army knife for Cluster API all operations from initializing the Cluster API stack to the ability to upgrade and customize existing Cluster API Providers. Generate cluster templates using variable substitutions. Manage life cycle events like cluster upgrade, and cert rotation and provide helper functions like extracting cluster kubeconfig and generating topology plan.

clusterctl has evolved to include plugins as well. Like Kubectl, one can write plugins to be used with clusterctl.

  • Initialize Cluster API stack

clusterctl init allows you to initialize Bootstrap and Management Cluster using factory defaults or you can use overrides and customize providers to their needs.

Please read the article below to understand the different components in the Cluster API stack

  • Render Templates

clusterctl generate allows users to generate clusters, providers or generic YAML from templates. clusterctl internally uses drone/envsubst to substitute variables in template files.

  • Helper functions

clusterctl get kubeconfig and clusterctl describe cluster are nice helper functions that allow users to get kubeconfig stored in a secret for a cluster to be directly printed to the terminal or saved to a file, and allow to have a friendly view of all cluster-related Custom Resources to be displayed in one place, respectively.

  • LifeCycle Management

clusterctl move, clusterctl upgrade and clusterctl delete allow users to move a running cluster from one management cluster to another management cluster, to upgrade providers versions, and to delete clusters respectively.

Installation

  • GitHub Release

Every GitHub contains a binaries for clusterctl for different architecture, please select one according to your needs.

  • Homebrew (linux+mac)

brew install clusterctl

Demo

Prerequisite

A Kubernetes cluster, we are using kind in this demo.

Run the command clusterctl init --infrastructure=docker I have used —v 10 to print a detailed information for you to go through what happens when you initiliaze a stack. You are not supposed to understand it all, but going through this will give you a good idea of operation clusterctl is doing.

clusterctl init --infrastructure=docker --v 10
No default config file available
Installing the clusterctl inventory CRD
Creating CustomResourceDefinition="providers.clusterctl.cluster.x-k8s.io"
Fetching providers
Potential override file searchFile="~/cluster-api/overrides/cluster-api/v1.9.3/core-components.yaml" provider="cluster-api" version="v1.9.3"
Fetching file="core-components.yaml" provider="cluster-api" type="CoreProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/bootstrap-kubeadm/v1.9.3/bootstrap-components.yaml" provider="bootstrap-kubeadm" version="v1.9.3"
Fetching file="bootstrap-components.yaml" provider="kubeadm" type="BootstrapProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/control-plane-kubeadm/v1.9.3/control-plane-components.yaml" provider="control-plane-kubeadm" version="v1.9.3"
Fetching file="control-plane-components.yaml" provider="kubeadm" type="ControlPlaneProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/infrastructure-docker/v1.9.3/infrastructure-components-development.yaml" provider="infrastructure-docker" version="v1.9.3"
Fetching file="infrastructure-components-development.yaml" provider="docker" type="InfrastructureProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/cluster-api/v1.9.3/metadata.yaml" provider="cluster-api" version="v1.9.3"
Fetching file="metadata.yaml" provider="cluster-api" type="CoreProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/bootstrap-kubeadm/v1.9.3/metadata.yaml" provider="bootstrap-kubeadm" version="v1.9.3"
Fetching file="metadata.yaml" provider="kubeadm" type="BootstrapProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/control-plane-kubeadm/v1.9.3/metadata.yaml" provider="control-plane-kubeadm" version="v1.9.3"
Fetching file="metadata.yaml" provider="kubeadm" type="ControlPlaneProvider" version="v1.9.3"
Potential override file searchFile="~/cluster-api/overrides/infrastructure-docker/v1.9.3/metadata.yaml" provider="infrastructure-docker" version="v1.9.3"
Fetching file="metadata.yaml" provider="docker" type="InfrastructureProvider" version="v1.9.3"
Creating Namespace="cert-manager-test"
Potential override file searchFile="~/cluster-api/overrides/cert-manager/v1.16.2/cert-manager.yaml" provider="cert-manager" version="v1.16.2"
Fetching file="cert-manager.yaml" provider="cert-manager" type="" version="v1.16.2"
Installing cert-manager version="v1.16.2"
Creating Namespace="cert-manager"
Creating CustomResourceDefinition="certificaterequests.cert-manager.io"
Creating CustomResourceDefinition="certificates.cert-manager.io"
Creating CustomResourceDefinition="challenges.acme.cert-manager.io"
Creating CustomResourceDefinition="clusterissuers.cert-manager.io"
Creating CustomResourceDefinition="issuers.cert-manager.io"
Creating CustomResourceDefinition="orders.acme.cert-manager.io"
Creating ServiceAccount="cert-manager-cainjector" Namespace="cert-manager"
Creating ServiceAccount="cert-manager" Namespace="cert-manager"
Creating ServiceAccount="cert-manager-webhook" Namespace="cert-manager"
Creating ClusterRole="cert-manager-cainjector"
Creating ClusterRole="cert-manager-controller-issuers"
Creating ClusterRole="cert-manager-controller-clusterissuers"
Creating ClusterRole="cert-manager-controller-certificates"
Creating ClusterRole="cert-manager-controller-orders"
Creating ClusterRole="cert-manager-controller-challenges"
Creating ClusterRole="cert-manager-controller-ingress-shim"
Creating ClusterRole="cert-manager-cluster-view"
Creating ClusterRole="cert-manager-view"
Creating ClusterRole="cert-manager-edit"
Creating ClusterRole="cert-manager-controller-approve:cert-manager-io"
Creating ClusterRole="cert-manager-controller-certificatesigningrequests"
Creating ClusterRole="cert-manager-webhook:subjectaccessreviews"
Creating ClusterRoleBinding="cert-manager-cainjector"
Creating ClusterRoleBinding="cert-manager-controller-issuers"
Creating ClusterRoleBinding="cert-manager-controller-clusterissuers"
Creating ClusterRoleBinding="cert-manager-controller-certificates"
Creating ClusterRoleBinding="cert-manager-controller-orders"
Creating ClusterRoleBinding="cert-manager-controller-challenges"
Creating ClusterRoleBinding="cert-manager-controller-ingress-shim"
Creating ClusterRoleBinding="cert-manager-controller-approve:cert-manager-io"
Creating ClusterRoleBinding="cert-manager-controller-certificatesigningrequests"
Creating ClusterRoleBinding="cert-manager-webhook:subjectaccessreviews"
Creating Role="cert-manager-cainjector:leaderelection" Namespace="kube-system"
Creating Role="cert-manager:leaderelection" Namespace="kube-system"
Creating Role="cert-manager-tokenrequest" Namespace="cert-manager"
Creating Role="cert-manager-webhook:dynamic-serving" Namespace="cert-manager"
Creating RoleBinding="cert-manager-cainjector:leaderelection" Namespace="kube-system"
Creating RoleBinding="cert-manager:leaderelection" Namespace="kube-system"
Creating RoleBinding="cert-manager-cert-manager-tokenrequest" Namespace="cert-manager"
Creating RoleBinding="cert-manager-webhook:dynamic-serving" Namespace="cert-manager"
Creating Service="cert-manager-cainjector" Namespace="cert-manager"
Creating Service="cert-manager" Namespace="cert-manager"
Creating Service="cert-manager-webhook" Namespace="cert-manager"
Creating Deployment="cert-manager-cainjector" Namespace="cert-manager"
Creating Deployment="cert-manager" Namespace="cert-manager"
Creating Deployment="cert-manager-webhook" Namespace="cert-manager"
Creating MutatingWebhookConfiguration="cert-manager-webhook"
Creating ValidatingWebhookConfiguration="cert-manager-webhook"
Waiting for cert-manager to be available...
Updating Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Issuer="test-selfsigned" Namespace="cert-manager-test"
Creating Certificate="selfsigned-cert" Namespace="cert-manager-test"
Deleting Namespace="cert-manager-test"
Deleting Issuer="test-selfsigned" Namespace="cert-manager-test"
Deleting Certificate="selfsigned-cert" Namespace="cert-manager-test"
Installing provider="cluster-api" version="v1.9.3" targetNamespace="capi-system"
Creating objects provider="cluster-api" version="v1.9.3" targetNamespace="capi-system"
Creating Namespace="capi-system"
Creating Issuer="capi-selfsigned-issuer" Namespace="capi-system"
Creating Certificate="capi-serving-cert" Namespace="capi-system"
Creating CustomResourceDefinition="clusterclasses.cluster.x-k8s.io"
Creating CustomResourceDefinition="clusterresourcesetbindings.addons.cluster.x-k8s.io"
Creating CustomResourceDefinition="clusterresourcesets.addons.cluster.x-k8s.io"
Creating CustomResourceDefinition="clusters.cluster.x-k8s.io"
Creating CustomResourceDefinition="extensionconfigs.runtime.cluster.x-k8s.io"
Creating CustomResourceDefinition="ipaddressclaims.ipam.cluster.x-k8s.io"
Creating CustomResourceDefinition="ipaddresses.ipam.cluster.x-k8s.io"
Creating CustomResourceDefinition="machinedeployments.cluster.x-k8s.io"
Creating CustomResourceDefinition="machinedrainrules.cluster.x-k8s.io"
Creating CustomResourceDefinition="machinehealthchecks.cluster.x-k8s.io"
Creating CustomResourceDefinition="machinepools.cluster.x-k8s.io"
Creating CustomResourceDefinition="machines.cluster.x-k8s.io"
Creating CustomResourceDefinition="machinesets.cluster.x-k8s.io"
Creating ServiceAccount="capi-manager" Namespace="capi-system"
Creating Role="capi-leader-election-role" Namespace="capi-system"
Creating ClusterRole="capi-aggregated-manager-role"
Creating ClusterRole="capi-manager-role"
Creating RoleBinding="capi-leader-election-rolebinding" Namespace="capi-system"
Creating ClusterRoleBinding="capi-manager-rolebinding"
Creating Service="capi-webhook-service" Namespace="capi-system"
Creating Deployment="capi-controller-manager" Namespace="capi-system"
Creating MutatingWebhookConfiguration="capi-mutating-webhook-configuration"
Creating ValidatingWebhookConfiguration="capi-validating-webhook-configuration"
Creating inventory entry provider="cluster-api" version="v1.9.3" targetNamespace="capi-system"
Installing provider="bootstrap-kubeadm" version="v1.9.3" targetNamespace="capi-kubeadm-bootstrap-system"
Creating objects provider="bootstrap-kubeadm" version="v1.9.3" targetNamespace="capi-kubeadm-bootstrap-system"
Creating Namespace="capi-kubeadm-bootstrap-system"
Creating Issuer="capi-kubeadm-bootstrap-selfsigned-issuer" Namespace="capi-kubeadm-bootstrap-system"
Creating Certificate="capi-kubeadm-bootstrap-serving-cert" Namespace="capi-kubeadm-bootstrap-system"
Creating CustomResourceDefinition="kubeadmconfigs.bootstrap.cluster.x-k8s.io"
Creating CustomResourceDefinition="kubeadmconfigtemplates.bootstrap.cluster.x-k8s.io"
Creating ServiceAccount="capi-kubeadm-bootstrap-manager" Namespace="capi-kubeadm-bootstrap-system"
Creating Role="capi-kubeadm-bootstrap-leader-election-role" Namespace="capi-kubeadm-bootstrap-system"
Creating ClusterRole="capi-kubeadm-bootstrap-manager-role"
Creating RoleBinding="capi-kubeadm-bootstrap-leader-election-rolebinding" Namespace="capi-kubeadm-bootstrap-system"
Creating ClusterRoleBinding="capi-kubeadm-bootstrap-manager-rolebinding"
Creating Service="capi-kubeadm-bootstrap-webhook-service" Namespace="capi-kubeadm-bootstrap-system"
Creating Deployment="capi-kubeadm-bootstrap-controller-manager" Namespace="capi-kubeadm-bootstrap-system"
Creating MutatingWebhookConfiguration="capi-kubeadm-bootstrap-mutating-webhook-configuration"
Creating ValidatingWebhookConfiguration="capi-kubeadm-bootstrap-validating-webhook-configuration"
Creating inventory entry provider="bootstrap-kubeadm" version="v1.9.3" targetNamespace="capi-kubeadm-bootstrap-system"
Installing provider="control-plane-kubeadm" version="v1.9.3" targetNamespace="capi-kubeadm-control-plane-system"
Creating objects provider="control-plane-kubeadm" version="v1.9.3" targetNamespace="capi-kubeadm-control-plane-system"
Creating Namespace="capi-kubeadm-control-plane-system"
Creating Issuer="capi-kubeadm-control-plane-selfsigned-issuer" Namespace="capi-kubeadm-control-plane-system"
Creating Certificate="capi-kubeadm-control-plane-serving-cert" Namespace="capi-kubeadm-control-plane-system"
Creating CustomResourceDefinition="kubeadmcontrolplanes.controlplane.cluster.x-k8s.io"
Creating CustomResourceDefinition="kubeadmcontrolplanetemplates.controlplane.cluster.x-k8s.io"
Creating ServiceAccount="capi-kubeadm-control-plane-manager" Namespace="capi-kubeadm-control-plane-system"
Creating Role="capi-kubeadm-control-plane-leader-election-role" Namespace="capi-kubeadm-control-plane-system"
Creating ClusterRole="capi-kubeadm-control-plane-aggregated-manager-role"
Creating ClusterRole="capi-kubeadm-control-plane-manager-role"
Creating RoleBinding="capi-kubeadm-control-plane-leader-election-rolebinding" Namespace="capi-kubeadm-control-plane-system"
Creating ClusterRoleBinding="capi-kubeadm-control-plane-manager-rolebinding"
Creating Service="capi-kubeadm-control-plane-webhook-service" Namespace="capi-kubeadm-control-plane-system"
Creating Deployment="capi-kubeadm-control-plane-controller-manager" Namespace="capi-kubeadm-control-plane-system"
Creating MutatingWebhookConfiguration="capi-kubeadm-control-plane-mutating-webhook-configuration"
Creating ValidatingWebhookConfiguration="capi-kubeadm-control-plane-validating-webhook-configuration"
Creating inventory entry provider="control-plane-kubeadm" version="v1.9.3" targetNamespace="capi-kubeadm-control-plane-system"
Installing provider="infrastructure-docker" version="v1.9.3" targetNamespace="capd-system"
Creating objects provider="infrastructure-docker" version="v1.9.3" targetNamespace="capd-system"
Creating Namespace="capd-system"
Creating Issuer="capd-selfsigned-issuer" Namespace="capd-system"
Creating Certificate="capd-serving-cert" Namespace="capd-system"
Creating CustomResourceDefinition="dockerclusters.infrastructure.cluster.x-k8s.io"
Creating CustomResourceDefinition="dockerclustertemplates.infrastructure.cluster.x-k8s.io"
Creating CustomResourceDefinition="dockermachinepools.infrastructure.cluster.x-k8s.io"
Creating CustomResourceDefinition="dockermachinepooltemplates.infrastructure.cluster.x-k8s.io"
Creating CustomResourceDefinition="dockermachines.infrastructure.cluster.x-k8s.io"
Creating CustomResourceDefinition="dockermachinetemplates.infrastructure.cluster.x-k8s.io"
Creating ServiceAccount="capd-manager" Namespace="capd-system"
Creating Role="capd-leader-election-role" Namespace="capd-system"
Creating ClusterRole="capd-manager-role"
Creating RoleBinding="capd-leader-election-rolebinding" Namespace="capd-system"
Creating ClusterRoleBinding="capd-manager-rolebinding"
Creating Service="capd-webhook-service" Namespace="capd-system"
Creating Deployment="capd-controller-manager" Namespace="capd-system"
Creating MutatingWebhookConfiguration="capd-mutating-webhook-configuration"
Creating ValidatingWebhookConfiguration="capd-validating-webhook-configuration"
Creating inventory entry provider="infrastructure-docker" version="v1.9.3" targetNamespace="capd-system"

Your management cluster has been initialized successfully!

You can now create your first workload cluster by running the following:

  clusterctl generate cluster [name] --kubernetes-version [version] | kubectl apply -f -

No default config file available

You should see Cluster API core, and Docker infrastructure provider running in the cluster.

kubectl get pods -A
NAMESPACE                           NAME                                                             READY   STATUS    RESTARTS   AGE
capd-system                         capd-controller-manager-7bdf7bbc68-4skfm                         1/1     Running   0          4m42s
capi-kubeadm-bootstrap-system       capi-kubeadm-bootstrap-controller-manager-5f4b58554-j2kts        1/1     Running   0          4m43s
capi-kubeadm-control-plane-system   capi-kubeadm-control-plane-controller-manager-5575d7b987-kr9ph   1/1     Running   0          4m42s
capi-system                         capi-controller-manager-569cd9b7cb-zwwx4                         1/1     Running   0          4m43s
cert-manager                        cert-manager-74b56b6655-4qbwb                                    1/1     Running   0          5m29s
cert-manager                        cert-manager-cainjector-55d94dc4cc-rvtfs                         1/1     Running   0          5m29s
cert-manager                        cert-manager-webhook-564f647c66-4hkn5                            1/1     Running   0          5m29s
kube-system                         coredns-7c65d6cfc9-789dp                                         1/1     Running   0          6m32s
kube-system                         coredns-7c65d6cfc9-rdhwg                                         1/1     Running   0          6m32s
kube-system                         etcd-kind-control-plane                                          1/1     Running   0          6m40s
kube-system                         kindnet-6brtp                                                    1/1     Running   0          6m32s
kube-system                         kube-apiserver-kind-control-plane                                1/1     Running   0          6m40s
kube-system                         kube-controller-manager-kind-control-plane                       1/1     Running   0          6m40s
kube-system                         kube-proxy-bsjw7                                                 1/1     Running   0          6m32s
kube-system                         kube-scheduler-kind-control-plane                                1/1     Running   0          6m40s
local-path-storage                  local-path-provisioner-57c5987fd4-nkl2j                          1/1     Running   0          6m32s

Now that we are able to create Cluster API stack using clusterctl or Cluster API Operator, we are in shape to get started creating a Workload Cluster, in the next section.

0
Subscribe to my newsletter

Read articles from Deepak Sharma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Deepak Sharma
Deepak Sharma

I have 10+ years of working experience working on Backend Systems, Blockchain & Kubernetes. Currently, I am working on my startup and starting my first Open Source गोपाल A DIY Kubernetes Cluster Management framework.