Cluster API bootstrap provider kubeadm
What is the Cluster API bootstrap provider kubeadm?
Cluster API bootstrap provider Kubeadm (CABPK) is a component responsible for generating a cloud-init script to turn a Machine into a Kubernetes Node. This implementation uses kubeadm for Kubernetes bootstrap.
Resources
How does CABPK work?
Assuming you have deployed the CAPI and CAPD controllers, create a Cluster object and its corresponding DockerCluster
infrastructure object.
kind: DockerCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
metadata:
name: my-cluster-docker
---
kind: Cluster
apiVersion: cluster.x-k8s.io/v1beta2
metadata:
name: my-cluster
spec:
infrastructureRef:
kind: DockerCluster
apiGroup: infrastructure.cluster.x-k8s.io
name: my-cluster-docker
Now you can start creating machines by defining a Machine, its corresponding DockerMachine object, and
the KubeadmConfig bootstrap object.
kind: KubeadmConfig
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
metadata:
name: my-control-plane1-config
---
kind: DockerMachine
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
metadata:
name: my-control-plane1-docker
---
kind: Machine
apiVersion: cluster.x-k8s.io/v1beta2
metadata:
name: my-control-plane1
labels:
cluster.x-k8s.io/cluster-name: my-cluster
cluster.x-k8s.io/control-plane: "true"
set: controlplane
spec:
bootstrap:
configRef:
apiGroup: bootstrap.cluster.x-k8s.io
kind: KubeadmConfig
name: my-control-plane1-config
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: DockerMachine
name: my-control-plane1-docker
version: "v1.19.1"
CABPK’s main responsibility is to convert a KubeadmConfig bootstrap object into a cloud-init script that is
going to turn a Machine into a Kubernetes Node using kubeadm.
The cloud-init script will be saved into a secret KubeadmConfig.Status.DataSecretName and then the infrastructure provider
(CAPD in this example) will pick up this value and proceed with the machine creation and the actual bootstrap.
KubeadmConfig objects
The KubeadmConfig object allows full control of Kubeadm init/join operations by exposing raw InitConfiguration,
ClusterConfiguration and JoinConfiguration objects.
InitConfiguration and JoinConfiguration exposes Patches field which can be used to specify the patches from a directory,
this support is available from K8s 1.22 version onwards.
CABPK will fill in some values if they are left empty with sensible defaults:
KubeadmConfig field | Default |
|---|---|
clusterConfiguration.KubernetesVersion | Machine.Spec.Version[1] |
clusterConfiguration.clusterName | Cluster.metadata.name |
clusterConfiguration.controlPlaneEndpoint | Cluster.status.apiEndpoints[0] |
clusterConfiguration.networking.dnsDomain | Cluster.spec.clusterNetwork.serviceDomain |
clusterConfiguration.networking.serviceSubnet | Cluster.spec.clusterNetwork.service.cidrBlocks[0] |
clusterConfiguration.networking.podSubnet | Cluster.spec.clusterNetwork.pods.cidrBlocks[0] |
joinConfiguration.discovery | a short lived BootstrapToken generated by CABPK |
IMPORTANT! overriding above defaults could lead to broken Clusters.
[1] if both clusterConfiguration.KubernetesVersion and Machine.Spec.Version are empty, the latest Kubernetes
version will be installed (as defined by the default kubeadm behavior).
Examples
Valid combinations of configuration objects are:
- for KCP,
InitConfigurationandClusterConfigurationfor the first control plane node;JoinConfigurationfor additional control plane nodes - for machine deployments,
JoinConfigurationfor worker nodes
Bootstrap control plane node:
kind: KubeadmConfig
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
metadata:
name: my-control-plane1-config
Additional control plane nodes:
kind: KubeadmConfig
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
metadata:
name: my-control-plane2-config
spec:
joinConfiguration:
controlPlane: {}
worker nodes:
kind: KubeadmConfig
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
metadata:
name: my-worker1-config
Bootstrap Orchestration
CABPK supports multiple control plane machines initing at the same time. The generation of cloud-init scripts of different machines is orchestrated in order to ensure a cluster bootstrap process that will be compliant with the correct Kubeadm init/join sequence. More in detail:
- cloud-config-data generation starts only after
Cluster.Status.InfrastructureReadyflag is set totrue. - at this stage, cloud-config-data will be generated for the first control plane machine only, keeping on hold additional control plane machines existing in the cluster, if any (kubeadm init).
- after the
ControlPlaneInitializedconditions on the cluster object is set to true, the cloud-config-data for all the other machines are generated (kubeadm join/join —control-plane).
Certificate Management
The user can choose two approaches for certificate management:
- provide required certificate authorities (CAs) to use for
kubeadm init/kubeadm join --control-plane; such CAs should be provided as aSecretsobjects in the management cluster. - let KCP to generate the necessary
Secretsobjects with a self-signed certificate authority for kubeadm
See here for more info about certificate management with kubeadm.
Additional Features
The KubeadmConfig object supports customizing the content of the config-data. The following examples illustrate how to specify these options. They should be adapted to fit your environment and use case.
-
KubeadmConfig.Filesspecifies additional files to be created on the machine, either with content inline or by referencing a secret.files: - contentFrom: secret: key: node-cloud.json name: ${CLUSTER_NAME}-md-0-cloud-json owner: root:root path: /etc/kubernetes/cloud.json permissions: "0644" - path: /etc/kubernetes/cloud.json owner: "root:root" permissions: "0644" content: | { "cloud": "CustomCloud" } -
KubeadmConfig.BootCommandsspecifies a list of commands to be executed very early in the boot processbootCommands: - cloud-init-per once mymkfs mkfs /dev/vdb -
KubeadmConfig.PreKubeadmCommandsspecifies a list of commands to be executed beforekubeadm init/joinpreKubeadmCommands: - hostname "{{ ds.meta_data.hostname }}" - echo "{{ ds.meta_data.hostname }}" >/etc/hostname -
KubeadmConfig.PostKubeadmCommandssame as above, but afterkubeadm init/joinpostKubeadmCommands: - echo "success" >/var/log/my-custom-file.log -
KubeadmConfig.Usersspecifies a list of users to be created on the machineusers: - name: capiuser sshAuthorizedKeys: - '${SSH_AUTHORIZED_KEY}' sudo: ALL=(ALL) NOPASSWD:ALL -
KubeadmConfig.NTPspecifies NTP settings for the machinentp: servers: - IP_ADDRESS enabled: true -
KubeadmConfig.DiskSetupspecifies options for the creation of partition tables and file systems on devices.diskSetup: filesystems: - device: /dev/disk/azure/scsi1/lun0 extraOpts: - -E - lazy_itable_init=1,lazy_journal_init=1 filesystem: ext4 label: etcd_disk - device: ephemeral0.1 filesystem: ext4 label: ephemeral0 replaceFS: ntfs partitions: - device: /dev/disk/azure/scsi1/lun0 layout: true overwrite: false tableType: gpt -
KubeadmConfig.Mountsspecifies a list of mount points to be setup.mounts: - - LABEL=etcd_disk - /var/lib/etcddisk -
KubeadmConfig.Verbosityspecifies thekubeadmlog level verbosityverbosity: 10
For more information on cloud-init options, see cloud config examples.