Add a post-join control-plane readiness gate so a half-succeeded server
join on a degraded etcd can no longer pass as success. Retry the MetalLB
IPAddressPool/L2Advertisement applies to ride out the validating-webhook
startup race. Narrow the k3sup cleanup glob, quiet the final k3sup ready
tip, and clarify two comments.
README: add networking caveats (VIP/LB outside the DHCP pool, same-subnet
ARP/L2, interface naming), certName key placement, a post-run verification
section, machine-count/admin-box notes, and fix the RAW_BASE description.
The lint CI runs pre-commit on changed files, so touching these scripts
surfaced pre-existing warnings. Address them without changing behavior:
- Quote array elements (SC2206) and command substitutions (SC2046).
- Disable SC2087 on the ssh heredocs (vars are intentionally expanded
client-side) and SC1090 on 'source ~/.bashrc' (not followable).
- Keep unused config knobs (KVVERSION, interface) with a targeted
SC2034 disable; drop the genuinely-unused allnomaster1 array.
- Strip trailing whitespace.
Verified: shellcheck --severity=warning clean and pre-commit green
(ShellCheck v0.10.0) on both files; bash -n syntax OK.
The wait-loop was missing '-o' before the jsonpath template, so
'jsonpath={...}' was parsed as a service name and the query errored
to empty output, causing the loop to never wait. It also queried
.status.conditions[Pending], a shape Services do not have.
Poll the rancher-lb service and block until MetalLB assigns an
external IP instead.
- join all nodes to --server-ip $vip (the readiness-gated VIP) so no single
master is the registration SPOF; drop the dead --server-user on joins
(a --node-token is already supplied, so k3sup doesn't SSH the server)
- add --tls-san=$vip to every server's args (not just master1's install) so
master2/3 declare the VIP SAN uniformly
- pin --flannel-iface/--node-ip on workers too (correct on multi-NIC nodes)
- filter k3sup's repeated 'slicervm.com' promo tip on install/join (sed, so
pipefail still surfaces a real failure)
- guard 'kubectl expose' with || true so a re-run doesn't abort on AlreadyExists
Re-validated on the 6-VM Multipass e2e: 5 nodes Ready, VIP serves the API,
MetalLB LoadBalancer reachable.
- match the global README.md convention; update the reference in k3s.sh
- pad the options table so it reads cleanly in raw and rendered views,
kept under the 80-col markdownlint limit
Found running the deploy end-to-end on a multi-node cluster:
- k3sup: get.k3sup.dev leaves an arch-suffixed binary (k3sup-arm64) when
run unprivileged; install whichever binary it produced, not a literal
'k3sup' that may not exist.
- kube-vip: scp landed the manifest in the ssh user's home, but the mv
ran as root (sudo bash -s) where ~ is /root; scp to /tmp and mv from
the absolute path instead.
- rewrite only the server URL (https://master1:6443 -> VIP) instead of a
global regex substitution whose dots could over-match cert data
- poll the VIP /readyz after repointing the kubeconfig, so a broken
kube-vip fails early with a clear message instead of downstream
The kubeadm default mounts /etc/kubernetes/admin.conf, which does not
exist on k3s. --inCluster uses the kube-vip ServiceAccount (provided by
the applied rbac.yaml) instead, which is the correct mode for k3s.
Add CONTRIBUTING.md explaining the linting setup and how to mark the
repo's intentional dummy credentials so gitleaks does not flag them:
inline `# gitleaks:allow` for lint-clean, comment-capable files, and a
.gitleaksignore baseline otherwise.
Annotate the dummy credentials in four already-lint-clean example files
inline, as the preferred convention going forward.
- DIUN/docker-compose.yaml
- Headscale/Tailscale-Client/docker-compose,yaml
- Homepage/Homepage/services.yaml
- Kubernetes/Traefik-PiHole/Helm/Traefik/Dashboard/secret-dashboard.yaml
- added the variable for the ssh config file
- check if the file exist
- if file exist, look for the StrictHostKeyChecking value and update if needed, otherwise add the line
- if file does not exist, create it, change file permissions and add the setting