This guide demonstrates how to use machine-controller to manage worker nodes in your Kubernetes cluster.
Machine-controller uses three main Kubernetes custom resources:
Similar to Kubernetes Deployments, MachineDeployments manage a set of identical machines. They handle:
MachineSet ensures that a specified number of Machine replicas are running. It’s typically managed by MachineDeployment but can be used independently.
Machine represents a single worker node. It contains the specification for creating a cloud instance and provisioning it to join the cluster.
Here’s a minimal MachineDeployment example:
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: my-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: my-workers
template:
metadata:
labels:
name: my-workers
spec:
providerSpec:
value:
cloudProvider: "hetzner"
cloudProviderSpec:
token: "<HCLOUD_TOKEN>"
serverType: "cx21"
location: "fsn1"
labels:
kubernetesCluster: "my-cluster"
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
kubectl apply -f machinedeployment.yaml
# Check MachineDeployment
kubectl get machinedeployments -n kube-system
# Check MachineSets
kubectl get machinesets -n kube-system
# Check Machines
kubectl get machines -n kube-system
# Check nodes
kubectl get nodes
kubectl scale machinedeployment my-workers --replicas=5 -n kube-system
kubectl scale machinedeployment my-workers --replicas=2 -n kube-system
Scaling to zero is useful for temporarily removing workers while preserving configuration:
kubectl scale machinedeployment my-workers --replicas=0 -n kube-system
Edit the MachineDeployment to change instance type, operating system version, or other properties:
kubectl edit machinedeployment my-workers -n kube-system
Changes trigger a rolling update, creating new machines and deleting old ones according to the update strategy.
To upgrade the kubelet version:
kubectl patch machinedeployment my-workers -n kube-system --type merge -p '
{
"spec": {
"template": {
"spec": {
"versions": {
"kubelet": "<YOUR-UPGRADED-KUBERNETES-VERSION>"
}
}
}
}
}'
kubectl rollout status machinedeployment my-workers -n kube-system
You can create multiple MachineDeployments for different workload types:
---
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: general-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
pool: general
template:
metadata:
labels:
pool: general
spec:
providerSpec:
value:
cloudProvider: "aws"
cloudProviderSpec:
instanceType: "t3.medium"
# ... other AWS config
---
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: memory-intensive-workers
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
pool: memory
template:
metadata:
labels:
pool: memory
spec:
providerSpec:
value:
cloudProvider: "aws"
cloudProviderSpec:
instanceType: "r5.xlarge"
# ... other AWS config
Specify custom labels in the Machine spec:
spec:
template:
metadata:
labels:
name: my-workers
environment: production
workload-type: compute
Add taints to control pod scheduling:
spec:
template:
spec:
taints:
- key: "workload"
value: "gpu"
effect: "NoSchedule"
kubectl delete machinedeployment my-workers -n kube-system
This cascades deletion to MachineSets and Machines, and terminates the corresponding cloud instances.
kubectl delete machine <machine-name> -n kube-system
The owning MachineSet will create a replacement machine to maintain the desired replica count.
kubectl get machines -n kube-system -o wide
kubectl describe machine <machine-name> -n kube-system
This shows:
kubectl get machine <machine-name> -n kube-system -o jsonpath='{.status.conditions}'
Store credentials in Kubernetes secrets:
kubectl create secret generic cloud-credentials \
-n kube-system \
--from-literal=token=<your-token>
Reference in MachineDeployment:
spec:
template:
spec:
providerSpec:
value:
cloudProviderSpec:
token:
secretKeyRef:
name: cloud-credentials
key: token
Alternatively, configure credentials via environment variables on the machine-controller deployment.
Check machine events:
kubectl describe machine <machine-name> -n kube-system
Common causes:
Check machine-controller logs:
kubectl logs -n kube-system deployment/machine-controller
Verify:
Review: