Add an HA control-plane API VIP for the k3s cluster with kube-vip, and add the VIP + all node IPs to the kube-apiserver serving-cert SANs so TLS via the VIP validates. Prepares the stable failover endpoint the operator fronts with a pfSense port-forward to 192.168.1.49:6443. roles/kube_vip + playbooks/kube-vip.yml: - Templates a single manifest (RBAC + DaemonSet kube-vip-ds) into each server's k3s auto-deploy dir (/var/lib/rancher/k3s/server/manifests) so it is reproducible and independent of Flux; k3s auto-applies it. - Control-plane ONLY (cp_enable=true, svc_enable=false): Cilium keeps ownership of Service LoadBalancing (L2 pool .53-.60) — no ARP conflict. - Runs on control-plane nodes (nodeSelector node-role.kubernetes.io/control-plane), hostNetwork, NET_ADMIN/NET_RAW, image pinned ghcr.io/kube-vip/kube-vip:v0.8.9. - vip_interface auto-detected per node (the iface holding 192.168.1.5x = eth0). - Leader election (plndr-cp-lock) with 15/10/2s lease timings. - This cluster runs without kube-proxy (Cilium replacement), so a hostNetwork pod cannot reach the kubernetes ClusterIP; kube-vip is pointed at the node-local apiserver (KUBERNETES_SERVICE_HOST=127.0.0.1:6443) so leader election works. roles/k3s_server tls-san: - New k3s_tls_sans (VIP + all three node IPs + 127.0.0.1, deduped); install args now emit one --tls-san per entry. - Persist the SAN list to /etc/rancher/k3s/config.yaml (read by a running k3s) and Restart k3s handler so an existing cluster regenerates its serving cert. - k3s.yml secondaries run serial:1 so a SAN change rolls one node at a time, keeping etcd quorum (kube-vip keeps the API reachable during each restart). Verified live: DS 3/3 ready, VIP answers on 192.168.1.49:6443, all 3 certs and an s_client against the VIP carry 192.168.1.49 + .50/.51/.52 + 127.0.0.1, all nodes Ready throughout the rolling restart. Co-Authored-By: Claude Opus 4.8 <[email protected]>
27 lines
813 B
YAML
27 lines
813 B
YAML
---
|
|
# Install the HA k3s control plane (embedded etcd, 3 servers) — ADR-0001.
|
|
# Primary founds the cluster (--cluster-init); secondaries join it in a second
|
|
# play so the primary's node-token fact is available to them.
|
|
|
|
- name: k3s primary (cluster-init)
|
|
hosts: k3s_primary
|
|
become: true
|
|
gather_facts: true
|
|
roles:
|
|
- role: k3s_server
|
|
vars:
|
|
k3s_server_mode: primary
|
|
|
|
# serial: 1 — process one secondary at a time. Matters when a config change (e.g.
|
|
# an updated tls-san set) triggers the Restart k3s handler: restarting both
|
|
# secondaries at once would drop etcd below quorum. One-at-a-time keeps 2/3 up.
|
|
- name: k3s secondaries (join)
|
|
hosts: k3s_secondary
|
|
become: true
|
|
serial: 1
|
|
gather_facts: true
|
|
roles:
|
|
- role: k3s_server
|
|
vars:
|
|
k3s_server_mode: secondary
|