From 56bb912bd3a3a218803e8b29f238498b790c1bfe Mon Sep 17 00:00:00 2001 From: Techno Tim Date: Wed, 5 Aug 2026 07:39:00 -0500 Subject: [PATCH] feat(prereq): add toggle to disable swap on all cluster nodes (#698) k3s recommends swap be disabled on every node. Add a disable_swap toggle (default true) to the prereq role that turns swap off now and comments out the swap entries in /etc/fstab so swap stays off across reboots. The change is applied uniformly across all k3s_cluster hosts (all-or-nothing) since leaving swap on for some nodes but not others creates uneven scheduling and latency. - roles/prereq/defaults/main.yml: add disable_swap: true default - roles/prereq/tasks/main.yml: idempotent swapoff -a and fstab comment-out block gated on disable_swap - inventory/sample/group_vars/all.yml: document the new sample variable - README.md: document the disable_swap option - .github/scripts/test-disable-swap.sh: regression test - .pre-commit-config.yaml: wire the test into pre-commit Closes #670 --- .github/scripts/test-disable-swap.sh | 37 ++++++++++++++++++++++++++++ .pre-commit-config.yaml | 6 +++++ README.md | 1 + inventory/sample/group_vars/all.yml | 4 +++ roles/prereq/defaults/main.yml | 2 ++ roles/prereq/tasks/main.yml | 22 +++++++++++++++++ 6 files changed, 72 insertions(+) create mode 100755 .github/scripts/test-disable-swap.sh diff --git a/.github/scripts/test-disable-swap.sh b/.github/scripts/test-disable-swap.sh new file mode 100755 index 0000000..82f1aad --- /dev/null +++ b/.github/scripts/test-disable-swap.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +repo_root="$(git rev-parse --show-toplevel)" +prereq_defaults="$repo_root/roles/prereq/defaults/main.yml" +prereq_tasks="$repo_root/roles/prereq/tasks/main.yml" + +# #670: k3s recommends swap be disabled on all nodes. The prereq role must expose +# a disable_swap toggle (defaulting to true) that turns swap off now and comments +# out the /etc/fstab swap entries so swap stays off across reboots. +grep -Eq -- '^disable_swap: true' "$prereq_defaults" || { + printf 'prereq defaults are missing disable_swap: true\n' >&2 + exit 1 +} + +grep -Fq -- 'Disable swap on all cluster nodes' "$prereq_tasks" || { + printf 'prereq tasks are missing the swap-disable block\n' >&2 + exit 1 +} + +grep -Fq -- 'swapoff -a' "$prereq_tasks" || { + printf 'swap-disable block does not run swapoff -a\n' >&2 + exit 1 +} + +grep -Fq -- '/etc/fstab' "$prereq_tasks" || { + printf 'swap-disable block does not comment out /etc/fstab swap entries\n' >&2 + exit 1 +} + +if ! grep -Eq -- 'when: disable_swap' "$prereq_tasks"; then + printf 'swap-disable block is not gated on the disable_swap toggle\n' >&2 + exit 1 +fi + +printf 'Swap disable regression test passed\n' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 53e78b6..4858b55 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -68,6 +68,12 @@ repos: language: system pass_filenames: false files: ^site\.yml$|^\.github/scripts/test-unique-hostname-precheck\.sh$ + - id: disable-swap-test + name: Disable swap test + entry: .github/scripts/test-disable-swap.sh + language: system + pass_filenames: false + files: ^roles/prereq/(tasks/main|defaults/main)\.yml$|^\.github/scripts/test-disable-swap\.sh$ - id: cilium-bgp-manifest-test name: Cilium BGP manifest test entry: python3 .github/scripts/test-cilium-bgp-manifest.py diff --git a/README.md b/README.md index 4dbc855..90f2ef0 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,7 @@ See the commands [here](https://technotim.com/posts/k3s-etcd-ansible/#testing-yo | `reboot` (playbook) | `concurrent_reboots` | int/string | `100%` | Not required | Number (or percentage) of nodes to reboot at a time for a staggered reboot | | `reboot` (playbook) | `wait_seconds_after_reboot` | int | `0` | Not required | Pause in seconds between staggered reboot batches | | `prereq` | `system_timezone` | string | `null` | Not required | Timezone to be set on all nodes | +| `prereq` | `disable_swap` | bool | `true` | Not required | Disable swap on all cluster nodes (swapoff + comment out /etc/fstab swap entries), all-or-nothing | | `proxmox_lxc`, `reset_proxmox_lxc` | `proxmox_lxc_ct_ids` | list | ❌ | Required | Proxmox container ID list | | `raspberrypi` | `state` | string | `present` | Not required | Indicates whether the k3s prerequisites for Raspberry Pi should be set up (possible values are `present` and `absent`) | diff --git a/inventory/sample/group_vars/all.yml b/inventory/sample/group_vars/all.yml index 7b1562c..8ddff5a 100644 --- a/inventory/sample/group_vars/all.yml +++ b/inventory/sample/group_vars/all.yml @@ -7,6 +7,10 @@ systemd_dir: /etc/systemd/system # Set your timezone system_timezone: Your/Timezone +# k3s recommends swap be disabled on every cluster node. Applied uniformly to all +# nodes (all-or-nothing) in the prereq role. Set to false to leave swap enabled. +disable_swap: true + # interface which will be used for flannel # Defaults to each host's default IPv4 interface (e.g. eth0, enp1s0, ens3) # so KVM/cloud hosts without eth0 work out of the box. Override per-host if needed. diff --git a/roles/prereq/defaults/main.yml b/roles/prereq/defaults/main.yml index 850cbbf..425eeef 100644 --- a/roles/prereq/defaults/main.yml +++ b/roles/prereq/defaults/main.yml @@ -1,4 +1,6 @@ --- +disable_swap: true + secure_path: RedHat: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin Suse: /usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin diff --git a/roles/prereq/tasks/main.yml b/roles/prereq/tasks/main.yml index b5da1ef..484d4e6 100644 --- a/roles/prereq/tasks/main.yml +++ b/roles/prereq/tasks/main.yml @@ -4,6 +4,28 @@ name: "{{ system_timezone }}" when: (system_timezone is defined) and (system_timezone != "Your/Timezone") +# k3s recommends swap be disabled on all nodes. Disabling swap is all-or-nothing +# across the cluster: leaving it enabled on some nodes but not others creates +# uneven scheduling/latency behavior. This block turns swap off and comments out +# the swap entries in /etc/fstab so it stays off across reboots. It is idempotent +# and a no-op when swap is already disabled or swapoff is unavailable. +- name: Disable swap on all cluster nodes + when: disable_swap + block: + - name: Turn off swap now + ansible.builtin.command: swapoff -a + register: swapoff_result + changed_when: false + failed_when: false + + - name: Comment out swap entries in fstab + ansible.builtin.replace: + path: /etc/fstab + regexp: '^([^#][^\n]*\s+swap\s+)' + replace: '# \\1' + register: fstab_swap + + - name: Set SELinux to disabled state ansible.posix.selinux: state: disabled