And in addition, I also run another cluster that has all its code on GitHub and runs this site/wiki: https://www.pidramble.com/
As for how to prepare the images, you need a ramfs image with the root filesystem as a cpio file and a kernel as a vmlinuz file. You then serve these in a basic HTTP file server that your iPXE config points to.
Generating the vmlinuz file is pretty easy given a kernel. The cpio file is trickier. netboot.xyz recommends just grabbing a standard distribution. Otherwise this reduces to the problem of creating your own.
Shameless plug: After a lot of research in this, I came to the conclusion that I'd just have to make it myself, hence Covey (https://github.com/chabad360/covey) a project that's written in Go, and currently in an early alpha stage of development, but it works. More details are in the readme, feel free to email me (its on my GH profile) if you want more details than the readme provides.
EDIT: seems like your looking for something that's primarily for provisioning anyways. Whoops, I seem to have missed the middle paragraph...
EDIT 2: PXE booting may not be the best option for a relatively low ram machine like the Pi (unless you have the storage somewhere else, but that's its own can of worms), even the minimal image required to run k3s would be at least 400mb (I think I'm underestimating) there are ways to deal with that (using a compressed squashfs). But none will beat running directly on the SD card. I'd suggest following the sibling comment, and using overlayfs on top of the main fs to ensure that the image doesn't get tarnished.
In my case I only have 2 different configurations, controller node and worker node. When deploying a new worker node I use a single digit line count shell script to produce the cloud-init files for that node from my template. Basically the only changes between worker nodes are the host name and static IP assigned. I then copy the resulting files to the FAT partition of the boot sdcard.
Someday I might replace this with network booting and something like ansible but for now this is an easy solution and handles 99% of my particular needs.
You could also do something like userdata where you have a script or playbook that runs on first boot and performs additional setup.
I've been meaning to try out PXE booting but am yet to.
You can get a free license for RackN's digital rebar and use their edgelab.digital [1] project to pxe boot and build a four node raspberry pi k3s cluster in a few minutes.
But so far I've not come further than this: how to deal with the host OS?
Like, I don't want to log into N computers and manually run "sudo apt update" etc. I want them to run the same OS but with slightly different configurations.
Network booting via PXE seems to be the best alternative, but not sure how to prepare the images for distribution.
Anyone got any pointers on how this is best done?
edit: I should mention I just found http://cobbler.github.io/ but haven't had time to investigate it. A viable choice?