#!/usr/bin/env bash set -Eeuo pipefail ######################################## # Arch Linux Kubernetes Worker # Prepares worker node for manual join ######################################## # ---------- Logging ---------- log() { echo echo "============================================================" echo "[INFO] $*" echo "============================================================" } warn() { echo echo "[WARN] $*" >&2 } die() { echo echo "[ERROR] $*" >&2 exit 1 } # ---------- Root check ---------- if [[ "${EUID}" -ne 0 ]]; then die "Run this script as root, for example: sudo ./worker_node_prepare.sh" fi # ---------- Cleanup on error ---------- on_error() { local exit_code=$? warn "Script failed on line $1 with exit code ${exit_code}" warn "Useful diagnostics:" echo " journalctl -u containerd -u kubelet -b --no-pager | tail -n 200" echo " systemctl status containerd kubelet --no-pager" exit "${exit_code}" } trap 'on_error $LINENO' ERR # ---------- Step 1: Disable swap ---------- log "Disabling swap immediately" swapoff -a || true log "Disabling swap persistently in /etc/fstab" if [[ -f /etc/fstab ]]; then cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S) sed -ri '/\sswap\s/s/^/# DISABLED FOR KUBERNETES: /' /etc/fstab fi # ---------- Step 2: Update system ---------- log "Updating package databases and system packages" pacman -Syu --noconfirm # ---------- Step 3: Resolve iptables conflict automatically ---------- log "Resolving iptables backend for Kubernetes" if pacman -Q iptables >/dev/null 2>&1; then log "Removing legacy iptables package so iptables-nft can be installed" pacman -Rdd --noconfirm iptables || true fi # ---------- Step 4: Install required packages ---------- log "Installing Kubernetes worker packages" pacman -S --needed --noconfirm \ ca-certificates \ curl \ containerd \ cni-plugins \ crictl \ ethtool \ iptables-nft \ conntrack-tools \ socat \ kubeadm \ kubectl \ kubelet # ---------- Step 5: Kernel modules ---------- log "Configuring required kernel modules" cat >/etc/modules-load.d/k8s.conf <<'EOF' overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # ---------- Step 6: Sysctl ---------- log "Configuring Kubernetes sysctl settings" cat >/etc/sysctl.d/99-kubernetes-cri.conf <<'EOF' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system # ---------- Step 7: Configure containerd ---------- log "Configuring containerd" mkdir -p /etc/containerd if [[ ! -f /etc/containerd/config.toml ]]; then containerd config default >/etc/containerd/config.toml else cp /etc/containerd/config.toml /etc/containerd/config.toml.bak.$(date +%Y%m%d%H%M%S) fi # Ensure kubelet/containerd use systemd cgroups sed -ri 's/^\s*SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml # ---------- Step 8: Enable services ---------- log "Enabling and starting containerd and kubelet" systemctl daemon-reload systemctl enable --now containerd systemctl enable --now kubelet # ---------- Step 9: Wait for containerd ---------- log "Waiting for containerd to become active" for i in {1..20}; do if systemctl is-active --quiet containerd; then break fi sleep 1 done systemctl is-active --quiet containerd || die "containerd did not start successfully" # ---------- Step 10: Pre-pull Kubernetes images ---------- log "Pulling Kubernetes node images" kubeadm config images pull # ---------- Step 11: Clean notice if already joined ---------- if [[ -f /etc/kubernetes/kubelet.conf ]]; then warn "This node appears to have already been joined before." warn "If you want to re-join it cleanly, run:" echo " sudo kubeadm reset -f" echo " sudo rm -rf /etc/cni/net.d /var/lib/cni /var/lib/kubelet /etc/kubernetes" echo " sudo systemctl restart containerd kubelet" fi # ---------- Step 12: Final status ---------- log "Worker node runtime status" systemctl status containerd kubelet --no-pager || true echo echo "Worker node preparation is complete." echo echo "This node is ready for you to run your join command manually." echo echo "Example:" echo " kubeadm join 10.28.24.43:6443 --token \\" echo " --discovery-token-ca-cert-hash sha256:" echo echo "After joining, verify on the control-plane node with:" echo " kubectl get nodes" echo