Installing OKD with the Agent-Based Installer on spinning disks: the four walls
Setting up a compact three-node OKD cluster on Proxmox, with spinning disks, took a whole session. Every blocker looked serious and nearly all were the same thing: something designed for SSD falling short.
- OpenShift (OKD)
- Kubernetes / K3s
- Proxmox VE
1 · The ISO that wouldn't boot
The VMs always hung at the same point while loading the boot from the latest installer ISO. I tried SeaBIOS and OVMF, four different CD buses, direct kernel boot, CPU types, VMs from Terraform and by hand… and even plain QEMU, no Proxmox and no KVM. It failed the same way in all ten configurations, while a small control ISO booted fine.
Conclusion: that version's ISO had a boot bug. With the previous stable version and the same configuration it booted first time (with host CPU: QEMU's generic model gave a kernel panic).
2 · «No space left on device» with an empty disk
After writing the system to the three disks, the install went silent and the API virtual address never came up. The service managing it was in a restart loop with «No space left on device».
The coordinating node stays booted from the ISO until the end and keeps everything on a temporary RAM file system half the size of memory. With 16 GB that was about 8, and the downloaded images exceeded 17.
Fix: raise the VMs to 32 GB of RAM from Terraform. Minimum requirements are for normal operation, not the install's peak; and on slow disks the peak lasts longer.
3 · etcd, over 37 minutes without quorum
One etcd member stayed unhealthy and the rest of the control plane waited. The etcd container's logs said it plainly: writes taking up to 6.6 seconds, against the 200 ms it expects.
It wasn't hung: it was slow, with every operator starting at once on spinning disks. With a clear diagnosis, I gave it one more window before treating it as a hardware limit. It stabilised on its own and didn't restart again.
4 · A node that wouldn't join
Two nodes ready and the third not joining: its network wouldn't start and kubelet failed in a loop. rpm-ostree status said it was still on the old image: the switch to the new one had been discarded by a timeout.
Copying the configuration took about 5 minutes on the slow disk, and that service's maximum stop time was exactly 5 minutes: systemd killed it milliseconds before it finished.
# /etc/systemd/system/ostree-finalize-staged.service.d/timeout.conf
[Service]
TimeoutStopSec=20min
Result
With the longer timeout and the image switch redone by hand with the exact same identifier, the node joined: 3 of 3 nodes ready, 33 of 33 healthy operators and the console reachable. Then a test application deployed with Ansible and published with a route.