This guide will help you get started with machine-controller to manage worker nodes in your Kubernetes cluster.
By the end of this guide, you’ll know how to:
Before you begin, ensure you have:
kubectl configured to access your clusterThe easiest way to install machine-controller is through KubeOne:
# Install with KubeOne (recommended)
kubeone apply --manifest kubeone.yaml --tfjson tf.json
For manual installation, see the Installation Guide.
Create a Kubernetes secret with your cloud provider credentials:
For Hetzner Cloud:
kubectl create secret generic hcloud-credentials \
-n kube-system \
--from-literal=token=<YOUR_HCLOUD_TOKEN>
For AWS:
kubectl create secret generic aws-credentials \
-n kube-system \
--from-literal=accessKeyId=<YOUR_ACCESS_KEY> \
--from-literal=secretAccessKey=<YOUR_SECRET_KEY>
For other providers, see Cloud Providers.
Create a file named machinedeployment.yaml:
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: my-first-workers
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
name: my-first-workers
template:
metadata:
labels:
name: my-first-workers
spec:
providerSpec:
value:
cloudProvider: "hetzner"
cloudProviderSpec:
serverType: "cx21"
location: "fsn1"
labels:
kubernetesCluster: "my-cluster"
token:
secretKeyRef:
name: hcloud-credentials
key: token
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
Apply the MachineDeployment:
kubectl apply -f machinedeployment.yaml
Monitor the progress:
# Watch MachineDeployment
kubectl get machinedeployments -n kube-system -w
# Watch Machines
kubectl get machines -n kube-system -w
# Watch nodes joining
kubectl get nodes -w
After a few minutes, you should see new nodes joining your cluster!
Check that everything is working:
# List all nodes
kubectl get nodes
# Describe a machine
kubectl describe machine <machine-name> -n kube-system
# Check machine-controller logs
kubectl logs -n kube-system deployment/machine-controller
Scale up:
kubectl scale machinedeployment my-first-workers --replicas=5 -n kube-system
Scale down:
kubectl scale machinedeployment my-first-workers --replicas=2 -n kube-system
Edit the MachineDeployment to change instance types, zones, or other settings:
kubectl edit machinedeployment my-first-workers -n kube-system
This triggers a rolling update.
Update the kubelet version:
kubectl patch machinedeployment my-first-workers -n kube-system --type merge -p '
{
"spec": {
"template": {
"spec": {
"versions": {
"kubelet": "<YOUR-UPGRADED-KUBERNETES-VERSION>"
}
}
}
}
}'
Delete the MachineDeployment:
kubectl delete machinedeployment my-first-workers -n kube-system
This will:
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: aws-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: aws-workers
template:
metadata:
labels:
name: aws-workers
spec:
providerSpec:
value:
cloudProvider: "aws"
cloudProviderSpec:
region: "us-east-1"
availabilityZone: "us-east-1a"
vpcId: "vpc-xxxxx"
subnetId: "subnet-xxxxx"
instanceType: "t3.medium"
diskSize: 50
tags:
KubernetesCluster: "my-cluster"
accessKeyId:
secretKeyRef:
name: aws-credentials
key: accessKeyId
secretAccessKey:
secretKeyRef:
name: aws-credentials
key: secretAccessKey
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: azure-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: azure-workers
template:
metadata:
labels:
name: azure-workers
spec:
providerSpec:
value:
cloudProvider: "azure"
cloudProviderSpec:
location: "westeurope"
resourceGroup: "my-resource-group"
vnetName: "my-vnet"
subnetName: "my-subnet"
vmSize: "Standard_B2s"
assignPublicIP: true
tenantID:
secretKeyRef:
name: azure-credentials
key: tenantID
clientID:
secretKeyRef:
name: azure-credentials
key: clientID
clientSecret:
secretKeyRef:
name: azure-credentials
key: clientSecret
subscriptionID:
secretKeyRef:
name: azure-credentials
key: subscriptionID
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: gcp-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: gcp-workers
template:
metadata:
labels:
name: gcp-workers
spec:
providerSpec:
value:
cloudProvider: "gce"
cloudProviderSpec:
zone: "us-central1-a"
machineType: "n1-standard-2"
diskSize: 50
diskType: "pd-standard"
network: "default"
subnetwork: "default"
assignPublicIPAddress: true
serviceAccount:
secretKeyRef:
name: gcp-credentials
key: serviceAccount
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
You can create different pools for different workload types:
---
# General purpose workers
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: general-workers
namespace: kube-system
spec:
replicas: 3
template:
metadata:
labels:
pool: general
# ... spec for t3.medium instances
---
# Memory-intensive workers
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: memory-workers
namespace: kube-system
spec:
replicas: 2
template:
metadata:
labels:
pool: memory
# ... spec for r5.xlarge instances
---
# Compute-intensive workers
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: compute-workers
namespace: kube-system
spec:
replicas: 2
template:
metadata:
labels:
pool: compute
# ... spec for c5.2xlarge instances
If machines are created but not joining the cluster:
Check machine status:
kubectl describe machine <machine-name> -n kube-system
Check machine-controller logs:
kubectl logs -n kube-system deployment/machine-controller
Verify credentials are correct
Check network connectivity between nodes and API server
See the Troubleshooting Guide for more help.
If machines take too long to provision:
Now that you have machine-controller running, explore:
Need assistance?