HomeLab – Pre-flight & Firewall (UFW) for k3s – Day 3

Goal: Prepare Linux nodes for k3s by disabling swap, setting required sysctl and kernel modules, and opening firewall ports via UFW. The actual k3s install starts in Day 4.

Reference environment: Kubuntu 25 host (fullstacklab.site), SSH user stackadmin; VMs: master 192.168.56.10, workers 192.168.56.11/.12; networking as in Day 1–2.


Step 0 — Pre-flight (Ansible playbook)

This playbook disables swap (runtime and on boot), applies required sysctl values, and ensures kernel modules overlay and br_netfilter are loaded now and at boot.

# ansible/preflight.yml
---
- name: k3s preflight (swap, sysctl, modules)
  hosts: k3s_master:k3s_workers
  become: true

  tasks:
    - name: Disable swap now (if present)
      ansible.builtin.command: swapoff -a
      when: (ansible_swaptotal_mb | int) > 0
      changed_when: false

    - name: Comment swap entries in /etc/fstab
      ansible.builtin.lineinfile:
        path: /etc/fstab
        regexp: '^[^#].*[[:space:]]swap[[:space:]]'
        line: '# \g<0>'
        backrefs: true

    - name: Sysctl - enable IP forwarding
      ansible.posix.sysctl:
        name: net.ipv4.ip_forward
        value: '1'
        sysctl_set: true
        state: present
        reload: true

    - name: Sysctl - bridge nfcall (IPv4)
      ansible.posix.sysctl:
        name: net.bridge.bridge-nf-call-iptables
        value: '1'
        sysctl_set: true
        state: present
        reload: true

    - name: Sysctl - bridge nfcall (IPv6)
      ansible.posix.sysctl:
        name: net.bridge.bridge-nf-call-ip6tables
        value: '1'
        sysctl_set: true
        state: present
        reload: true

    - name: Ensure modules load at boot
      ansible.builtin.copy:
        dest: /etc/modules-load.d/k8s.conf
        mode: '0644'
        content: |
          overlay
          br_netfilter

    - name: Load modules now
      ansible.builtin.modprobe:
        name: "{{ item }}"
        state: present
      loop:
        - overlay
        - br_netfilter

Run it:

ansible-playbook -i ansible/inventory/hosts.ini ansible/preflight.yml

Step 1 — Firewall (UFW via Ansible)

We use UFW for simplicity. SSH port 22 is explicitly allowed first, then k3s ports: API (master: 6443/TCP), VXLAN (all nodes: 8472/UDP), and NodePort range (all nodes: 30000–32767/TCP+UDP) for future services.

Note: If you have a different SSH port, adjust port: "22" accordingly.

# ansible/firewall.yml
---
- name: Ensure UFW installed and SSH allowed
  hosts: all
  become: true
  tasks:
    - name: Install UFW
      ansible.builtin.package:
        name: ufw
        state: present

    - name: Allow SSH (22/tcp) before enabling firewall
      community.general.ufw:
        rule: allow
        port: "22"
        proto: tcp

    - name: Enable UFW (keep default policies)
      community.general.ufw:
        state: enabled
        logging: 'on'

- name: Master rules (API + VXLAN + NodePort)
  hosts: k3s_master
  become: true
  tasks:
    - community.general.ufw:
        rule: allow
        port: "6443"
        proto: tcp
    - community.general.ufw:
        rule: allow
        port: "8472"
        proto: udp
    - community.general.ufw:
        rule: allow
        port: "30000:32767"
        proto: tcp
    - community.general.ufw:
        rule: allow
        port: "30000:32767"
        proto: udp

- name: Worker rules (VXLAN + NodePort)
  hosts: k3s_workers
  become: true
  tasks:
    - community.general.ufw:
        rule: allow
        port: "8472"
        proto: udp
    - community.general.ufw:
        rule: allow
        port: "30000:32767"
        proto: tcp
    - community.general.ufw:
        rule: allow
        port: "30000:32767"
        proto: udp

Run it: (First install the collection if needed)

ansible-galaxy collection install community.general
ansible-playbook -i ansible/inventory/hosts.ini ansible/firewall.yml

What’s next (Day 4)

We’ll set a strong k3s token, run the Ansible k3s role to install the master and join workers, and verify the cluster with kubectl.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.