Ubuntu is the most widely supported operating system across all cloud providers in machine-controller.
Machine-controller officially supports and tests the following Ubuntu LTS versions:
Ubuntu is supported on all machine-controller cloud providers:
To use Ubuntu as the operating system, set the following in your MachineDeployment:
spec:
template:
spec:
providerSpec:
value:
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
operatingSystemSpec:
# Perform distribution upgrade on first boot
distUpgradeOnBoot: false
# Disable auto-update (recommended for production)
disableAutoUpdate: true
Ubuntu instances are provisioned using cloud-init. The machine-controller generates cloud-init configuration that:
AWS provides official Ubuntu AMIs. You can either:
cloudProviderSpec:
# Optional: specify a custom Ubuntu AMI
ami: "ami-0c55b159cbfafe1f0"
# If not specified, machine-controller will use the latest Ubuntu LTS AMI
Azure provides Ubuntu images in the marketplace:
cloudProviderSpec:
# Default Ubuntu image (recommended)
imageReference:
publisher: "Canonical"
offer: "ubuntu-24_04-lts"
sku: "server-gen1"
version: "latest"
Google Cloud Platform provides Ubuntu images:
cloudProviderSpec:
# Use default Ubuntu image
# machine-controller will select: ubuntu-2404-lts
For custom images:
cloudProviderSpec:
customImage: "projects/ubuntu-os-cloud/global/images/ubuntu-2404-noble-amd64-v20250101"
Hetzner provides Ubuntu images:
cloudProviderSpec:
# The image name is automatically selected
# Available: ubuntu-24.04
DigitalOcean provides Ubuntu images:
cloudProviderSpec:
# Image slug is automatically determined based on Ubuntu version
# Available: ubuntu-24-04-x64
For vSphere, you need to prepare an Ubuntu template VM. See the vSphere Ubuntu Template Guide.
You can install additional packages during provisioning by using cloud-init user data:
spec:
template:
spec:
providerSpec:
value:
operatingSystem: "ubuntu"
cloudInit: |
#cloud-config
packages:
- htop
- vim
- curl
runcmd:
- echo "Custom initialization complete"
By default, Ubuntu has unattended-upgrades enabled. To disable:
operatingSystemSpec:
disableAutoUpdate: true
For critical kernel updates:
kubectl cordon <node-name>kubectl drain <node-name> --ignore-daemonsetssudo apt-get update && sudo apt-get upgrade -ysudo rebootkubectl uncordon <node-name>Or use a rolling update of the MachineDeployment with a newer image.
If a node fails to join the cluster, check cloud-init logs:
# View cloud-init output
sudo cat /var/log/cloud-init-output.log
# View cloud-init logs
sudo cat /var/log/cloud-init.log
# Check cloud-init status
sudo cloud-init status --long
If package installation fails:
# Check APT logs
sudo cat /var/log/apt/history.log
sudo cat /var/log/apt/term.log
# Manually update and install
sudo apt-get update
sudo apt-get install -y containerd kubelet kubeadm kubectl
Check network configuration:
# View network interfaces
ip addr show
# Check DNS resolution
systemd-resolve --status
# Test connectivity
ping -c 4 8.8.8.8
curl https://packages.cloud.google.com
To upgrade Ubuntu versions:
Example:
# Scale up new Ubuntu 24.04 deployment
kubectl scale machinedeployment ubuntu-24-workers --replicas=3 -n kube-system
# Wait for new nodes to be ready
kubectl get nodes -w
# Cordon old nodes
kubectl cordon -l ubuntu-version=old
# Drain old nodes
kubectl drain -l ubuntu-version=old --ignore-daemonsets --delete-emptydir-data
# Scale down old deployment
kubectl scale machinedeployment ubuntu-old-workers --replicas=0 -n kube-system