Ansible Configuration¶
Ansible never configures a node here: it generates files on the deployment host, and Ignition applies them once, on the first boot after a node is installed.
It renders two Ignition configs per host from two templates — one the PXE
environment runs to install, one
flatcar-install embeds into the system it writes. Changing anything under
ansible/ therefore takes a rebuild of the affected node, not a reboot. The
directory layout is in Repository layout.
Inventory¶
ansible/inventory.yaml is the single source of truth for the machines; every
generated artifact comes from it, and the values are baked into the output
rather than read at boot. The variables are described in
Quickstart step 2. Every playbook targets the
k8s_nodes group, the parent of control_plane and workers, which carries
ansible_user and the SSH options.
Every edit needs a regeneration, and some need two
make config re-renders the Ignition configs, PXE menus and router config from the inventory; make download fetches what flatcar_channel, flatcar_version, syslinux_version and kubernetes_version name. The Flatcar, Kubernetes and kube-vip versions are rendered into the configs too, so a version bump needs make artifacts, which runs both. Which target reads which variable is in the Quickstart table. An edit followed by neither changes nothing at all, silently.
bootstrap_cluster in the control_plane group decides whether the first
control-plane host renders kubeadm init (true, the first install) or, like
every other control plane, kubeadm join --control-plane (false, every
rebuild). A rebuilt node that ran init would start a second cluster on the
same VIP — see Rebuilding a node.
kube_vip_version only sets the bootstrap static pod that gives kubeadm init
a VIP; once ArgoCD syncs, payload/platform/kube-vip/ takes over and its image
is what runs — see Control Plane VIP.
Playbooks¶
| Playbook | Does |
|---|---|
config.yaml |
Generates the bootstrap token, certificate key and etcd encryption key into output/credentials/ (mode 0700); renders the Ignition configs via Butane into output/http (mode 0600), the sysupdate config for running nodes beside them, the per-MAC PXE menus into output/tftp/pxelinux.cfg/, the router's FRR config into output/router/frr-bgp.conf, and a readable copy of the kubeadm config into output/tmp/ (the copy that runs is inlined into Ignition) |
download.yaml |
Fetches the Flatcar kernel, initrd, OS image and its detached signature, checked against the .DIGESTS.asc that gpgv verifies; the Kubernetes sysext image; and the syslinux bootloader files, checked the same way against sha256sums.asc. The signing keys are fetched and trusted through the primary fingerprints pinned in the playbook |
reinstall.yaml |
Rewrites DEFAULT in the generated PXE menus — install to arm, localboot to disarm. make reinstall and make reinstall-cancel are the two directions, both taking LIMIT=<host>. Arming refuses while bootstrap_cluster is true and the API VIP answers, or when an endpoint name is not the one the cluster publishes. It touches only output/tftp/pxelinux.cfg/, so the next make config regenerates the safe default. See Switching back to local boot |
kubeconfig.yaml |
Copies the admin kubeconfig over SSH to output/kubeconfig, mode 0600, with the VIP as its server |
config.yaml is safe to re-run: the password lookup reads an existing
credential file back instead of generating a new value, so the encryption key
every control-plane node shares stays the one etcd's Secrets were encrypted
with.
config.yaml renews the join credentials on the first control-plane host
that answers with a running cluster, so the node being
replaced may be any of them;
it fails when none answers while output/kubeconfig exists, since a node
booted then could not join, and skips the renewal silently only before the
first bootstrap.
kubeconfig.yaml targets control_plane[0] — the first control-plane host in
the inventory, with no fallback. If that node is down, copy
/etc/kubernetes/admin.conf off any other control-plane node by hand. Keep a
copy of the result off the cluster: it is the credential you want when the web
UIs are unreachable, and output/ is exactly as durable as the laptop it is on.