NAME

Rex::Rancher::Node - Linux node preparation for Rancher Kubernetes distributions (RKE2/K3s)

VERSION

version 0.003

SYNOPSIS

use Rex::Rancher::Node;

# Full preparation with hostname
prepare_node(
  hostname => 'worker-01',
  domain   => 'k8s.local',
  timezone => 'Europe/Berlin',
);

# Minimal preparation — hostname left unchanged; timezone UTC and
# locale en_US.UTF-8 are still set (the defaults), chrony installed
prepare_node();

# Skip NTP (e.g. host is a VM with hypervisor time sync)
prepare_node(
  hostname => 'vm-01',
  domain   => 'k8s.local',
  ntp      => 0,
);

DESCRIPTION

Rex::Rancher::Node prepares a Linux node for Rancher Kubernetes distributions (RKE2 and K3s). The same "prepare_node" call is verified on Debian, Ubuntu, and RHEL/Rocky/Alma — the supported set. openSUSE Leap / SLES is unverified: the base-package step there falls through to Rex's generic pkg abstraction (zypper) and has never been exercised on real SUSE hardware, so it is unsupported and best-effort only.

The module sets OS-level configuration that Kubernetes requires:

  • Swap disabled — Kubernetes does not function correctly with swap enabled.

  • Kernel modules — br_netfilter is needed for iptables to see bridged traffic; overlay is required for containerd's overlay filesystem.

  • Sysctl parameters — IP forwarding and bridge netfilter settings required by Kubernetes networking and CNI plugins.

  • NTP — Time skew between nodes causes certificate validation failures and etcd instability. An already synchronized clock is left as it is; otherwise chrony is installed and started, with systemd-timesyncd as the fallback when that install fails on a host that has it (Debian/Ubuntu). Without either, preparation goes on with a warning that no time synchronization is active.

Called automatically by "rancher_deploy_server" in Rex::Rancher and "rancher_deploy_agent" in Rex::Rancher.

prepare_node

Prepare a Linux node for Kubernetes. Performs all OS-level configuration required before installing RKE2 or K3s:

  • On Debian/Ubuntu, stop unattended-upgrades, apt-daily.service and apt-daily-upgrade.service (they hold the apt lock on a fresh boot) and run apt-get update. They are not restarted afterwards; their timers bring them back on schedule, unattended-upgrades at the next boot.

  • Install curl and ca-certificates

  • Set hostname via hostnamectl or /etc/hostname (optional). A static hostname (/etc/hostname) that already is hostname or whose first label is hostname, compared case-insensitively, is left as it is, whatever domain says: hostname => 'worker-01' keeps worker-01.example.com. The Kubernetes node name then follows the kernel hostname, that FQDN, unless node_name is set ("install_server" in Rex::Rancher::Server, "install_agent" in Rex::Rancher::Agent).

  • Add a 127.0.1.1 entry to /etc/hosts when hostname is given: FQDN hostname with a domain, hostname alone without one (then only if no line in /etc/hosts names the host yet)

  • Set timezone via timedatectl or symlink (default: UTC). A timezone that is not shaped like a zoneinfo name (Area/City such as Europe/Berlin or America/Argentina/Buenos_Aires, UTC, Etc/GMT+5: parts of letters, digits, _, + and -, each starting with a letter, separated by /) dies before the host is touched. Whether the zone exists is left to the host.

  • Set locale via localectl or /etc/default/locale (default: en_US.UTF-8). On Debian/Ubuntu the locale is first enabled in /etc/locale.gen and generated with locale-gen (skipped for C/POSIX and when locale-gen is not installed). The charset is written the way locale.gen spells it, so de_DE.utf8 enables de_DE.UTF-8 UTF-8. A locale that is not language_TERRITORY.charset@modifier shaped (letters, digits, _, -) dies before the host is touched.

  • NTP (default: enabled): nothing is installed when timedatectl already reports the clock as NTP-synchronized; otherwise chrony is installed and started. If the chrony install fails, systemd-timesyncd is started instead where the host has it (Debian/Ubuntu; the RHEL family does not ship it). When that is not active either, prepare_node goes on with a warning that no time synchronization is active

  • Disable and remove swap entries from /etc/fstab

  • Load br_netfilter and overlay kernel modules and persist to /etc/modules-load.d/kubernetes.conf

  • Write /etc/sysctl.d/99-kubernetes.conf with net.ipv4.ip_forward, net.bridge.bridge-nf-call-iptables, and net.bridge.bridge-nf-call-ip6tables, then apply with sysctl --system

prepare_node(
  hostname => 'worker-01',      # optional — short hostname
  domain   => 'k8s.local',      # optional — domain suffix for FQDN
  timezone => 'Europe/Berlin',  # optional, default: UTC
  locale   => 'en_US.UTF-8',    # optional, default: en_US.UTF-8
  ntp      => 1,                 # optional, default: 1 (ensure NTP sync)
);

If hostname is provided without domain, /etc/hosts gets 127.0.1.1 hostname unless a line already names the host (e.g. the public IP the provider wrote), which is then left alone.

SEE ALSO

Rex::Rancher, Rex::Rancher::Server, Rex::Rancher::Agent, Rex

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/rex-rancher/issues.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <getty@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.