Adding Nodes
This cluster uses kubeadm on AlmaLinux with Kubernetes v1.29.
On Master Node
Generate a join token:
kubeadm token create --print-join-command
Copy the output - it will look like:
kubeadm join 10.0.0.219:6443 --token xxxxxx --discovery-token-ca-cert-hash sha256:xxxxxx
note
The token expires after 24 hours by default. Use kubeadm token create to generate a new one if needed.
On New Node
Run these commands as root:
# 1. Set hostname
hostnamectl set-hostname node05
# 2. Stop firewall
systemctl stop firewalld
systemctl stop iptables
# 3. Disable SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 4. Disable swap
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
# 5. Load kernel modules
modprobe overlay
modprobe br_netfilter
# 6. Configure sysctl
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# 7. Add k8s repo
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
# 8. Add Docker CE repo and install containerd
dnf install -y dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y containerd.io
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl enable --now containerd
# 9. Install k8s components
dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# 10. Enable kubelet
systemctl enable --now kubelet
# 11. Join cluster (USE TOKEN FROM MASTER)
kubeadm join 10.0.0.219:6443 --token <TOKEN> --discovery-token-ca-cert-hash sha256:<HASH>
On Master Node Again
Approve the CSR if needed:
kubectl get nodes
kubectl get csr
# If there are pending CSRs:
kubectl certificate approve <csr-name>
Verify:
kubectl get nodes -o wide
Post-Join Verification
-
Check node status:
kubectl get nodes
# Should show Ready status -
Check system pods:
kubectl get pods -n kube-system -o wide
# Verify calico-node, kube-proxy are scheduled on new node -
Check MetalLB speaker:
kubectl get pods -n metallb-system -o wide
# Verify speaker pod is running on new node -
Check Promtail:
kubectl get pods -n monitoring -l app.kubernetes.io/name=promtail -o wide
# Verify Promtail is collecting logs from new node
Troubleshooting
Node Not Ready
# Check kubelet status
systemctl status kubelet
journalctl -u kubelet -f
# Check certificates
ls -la /etc/kubernetes/pki/
# Rejoin if needed
kubeadm reset
# Then run join command again
Pod Not Scheduled
# Check node taints
kubectl describe node <node-name> | grep Taint
# Check node labels
kubectl get node <node-name> --show-labels
Network Issues
# Check calico-node pod
kubectl get pods -n calico-system -o wide
# Check BGP peering
kubectl exec -n calico-system <calico-node-pod> -- calicoctl node status