Update worker_node_install.sh

This commit is contained in:
RomanNum3ral 2026-03-27 08:48:17 +00:00
parent 7016ae1ba9
commit 56b594cdfb
1 changed files with 170 additions and 33 deletions

View File

@ -2,10 +2,25 @@
set -Eeuo pipefail set -Eeuo pipefail
######################################## ########################################
# Arch Linux Kubernetes Worker # Arch Linux Kubernetes Worker Node
# Prepares worker node for manual join # Fully automated worker node preparation
# + Official Kubernetes binaries pinned to 1.34.x
# Ready for manual kubeadm join
######################################## ########################################
# ---------- Config ----------
K8S_VERSION="${K8S_VERSION:-v1.34.6}"
K8S_SERIES_REGEX='^v1\.34\.[0-9]+$'
K8S_ARCH="${K8S_ARCH:-amd64}"
# Binary locations
KUBEADM_BIN="/usr/local/bin/kubeadm"
KUBECTL_BIN="/usr/local/bin/kubectl"
KUBELET_BIN="/usr/local/bin/kubelet"
# Optional output file for your later manual join command
JOIN_HINT_FILE="${JOIN_HINT_FILE:-/root/kubeadm-join-example.txt}"
# ---------- Logging ---------- # ---------- Logging ----------
log() { log() {
echo echo
@ -25,6 +40,83 @@ die() {
exit 1 exit 1
} }
# ---------- Helpers ----------
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "Required command not found: $1"
}
download_k8s_binary() {
local name="$1"
local tmpdir
tmpdir="$(mktemp -d)"
curl -fsSL -o "${tmpdir}/${name}" \
"https://dl.k8s.io/release/${K8S_VERSION}/bin/linux/${K8S_ARCH}/${name}"
curl -fsSL -o "${tmpdir}/${name}.sha256" \
"https://dl.k8s.io/release/${K8S_VERSION}/bin/linux/${K8S_ARCH}/${name}.sha256"
(
cd "${tmpdir}"
echo "$(cat "${name}.sha256") ${name}" | sha256sum --check --status
) || die "Checksum verification failed for ${name} ${K8S_VERSION}"
install -o root -g root -m 0755 "${tmpdir}/${name}" "/usr/local/bin/${name}"
rm -rf "${tmpdir}"
}
install_kubelet_service() {
log "Installing kubelet systemd service"
mkdir -p /etc/systemd/system/kubelet.service.d
touch /etc/default/kubelet
cat >/etc/systemd/system/kubelet.service <<'EOF'
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/
After=containerd.service network-online.target
Wants=network-online.target
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<'EOF'
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
EOF
}
cleanup_old_k8s_state() {
log "Cleaning up any previous Kubernetes worker state"
kubeadm reset -f >/dev/null 2>&1 || true
rm -rf /etc/cni/net.d \
/var/lib/cni \
/etc/kubernetes \
/var/lib/kubelet/pki \
/var/lib/kubelet/config.yaml \
/var/lib/kubelet/kubeadm-flags.env
ip link delete cni0 2>/dev/null || true
ip link delete flannel.1 2>/dev/null || true
ip link delete kube-ipvs0 2>/dev/null || true
}
# ---------- Root check ---------- # ---------- Root check ----------
if [[ "${EUID}" -ne 0 ]]; then if [[ "${EUID}" -ne 0 ]]; then
die "Run this script as root, for example: sudo ./worker_node_prepare.sh" die "Run this script as root, for example: sudo ./worker_node_prepare.sh"
@ -41,6 +133,10 @@ on_error() {
} }
trap 'on_error $LINENO' ERR trap 'on_error $LINENO' ERR
# ---------- Version guard ----------
[[ "${K8S_VERSION}" =~ ${K8S_SERIES_REGEX} ]] || die \
"This worker script is intended for Kubernetes 1.34.x to match your master node. Current K8S_VERSION=${K8S_VERSION}"
# ---------- Step 1: Disable swap ---------- # ---------- Step 1: Disable swap ----------
log "Disabling swap immediately" log "Disabling swap immediately"
swapoff -a || true swapoff -a || true
@ -62,8 +158,8 @@ if pacman -Q iptables >/dev/null 2>&1; then
pacman -Rdd --noconfirm iptables || true pacman -Rdd --noconfirm iptables || true
fi fi
# ---------- Step 4: Install required packages ---------- # ---------- Step 4: Install required Arch packages ----------
log "Installing Kubernetes worker packages" log "Installing runtime and support packages from Arch"
pacman -S --needed --noconfirm \ pacman -S --needed --noconfirm \
ca-certificates \ ca-certificates \
curl \ curl \
@ -74,11 +170,30 @@ pacman -S --needed --noconfirm \
iptables-nft \ iptables-nft \
conntrack-tools \ conntrack-tools \
socat \ socat \
kubeadm \ tar \
kubectl \ gzip \
kubelet jq \
openssl
# ---------- Step 5: Kernel modules ---------- # ---------- Step 5: Remove Arch Kubernetes packages if present ----------
log "Removing Arch-provided kubeadm/kubectl/kubelet if present"
for pkg in kubeadm kubectl kubelet; do
if pacman -Q "${pkg}" >/dev/null 2>&1; then
pacman -Rdd --noconfirm "${pkg}" || true
fi
done
# ---------- Step 6: Install pinned Kubernetes binaries ----------
log "Installing Kubernetes binaries ${K8S_VERSION}"
download_k8s_binary kubeadm
download_k8s_binary kubectl
download_k8s_binary kubelet
require_cmd "${KUBEADM_BIN}"
require_cmd "${KUBECTL_BIN}"
require_cmd "${KUBELET_BIN}"
# ---------- Step 7: Kernel modules ----------
log "Configuring required kernel modules" log "Configuring required kernel modules"
cat >/etc/modules-load.d/k8s.conf <<'EOF' cat >/etc/modules-load.d/k8s.conf <<'EOF'
overlay overlay
@ -88,7 +203,7 @@ EOF
modprobe overlay modprobe overlay
modprobe br_netfilter modprobe br_netfilter
# ---------- Step 6: Sysctl ---------- # ---------- Step 8: Sysctl ----------
log "Configuring Kubernetes sysctl settings" log "Configuring Kubernetes sysctl settings"
cat >/etc/sysctl.d/99-kubernetes-cri.conf <<'EOF' cat >/etc/sysctl.d/99-kubernetes-cri.conf <<'EOF'
net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-iptables = 1
@ -98,7 +213,7 @@ EOF
sysctl --system sysctl --system
# ---------- Step 7: Configure containerd ---------- # ---------- Step 9: Configure containerd ----------
log "Configuring containerd" log "Configuring containerd"
mkdir -p /etc/containerd mkdir -p /etc/containerd
@ -108,16 +223,21 @@ else
cp /etc/containerd/config.toml /etc/containerd/config.toml.bak.$(date +%Y%m%d%H%M%S) cp /etc/containerd/config.toml /etc/containerd/config.toml.bak.$(date +%Y%m%d%H%M%S)
fi fi
# Ensure kubelet/containerd use systemd cgroups
sed -ri 's/^\s*SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml sed -ri 's/^\s*SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# ---------- Step 8: Enable services ---------- # ---------- Step 10: Install kubelet service ----------
install_kubelet_service
# ---------- Step 11: Clean previous worker state ----------
cleanup_old_k8s_state
# ---------- Step 12: Enable services ----------
log "Enabling and starting containerd and kubelet" log "Enabling and starting containerd and kubelet"
systemctl daemon-reload systemctl daemon-reload
systemctl enable --now containerd systemctl enable --now containerd
systemctl enable --now kubelet systemctl enable --now kubelet
# ---------- Step 9: Wait for containerd ---------- # ---------- Step 13: Wait for containerd ----------
log "Waiting for containerd to become active" log "Waiting for containerd to become active"
for i in {1..20}; do for i in {1..20}; do
if systemctl is-active --quiet containerd; then if systemctl is-active --quiet containerd; then
@ -127,32 +247,49 @@ for i in {1..20}; do
done done
systemctl is-active --quiet containerd || die "containerd did not start successfully" systemctl is-active --quiet containerd || die "containerd did not start successfully"
# ---------- Step 10: Pre-pull Kubernetes images ---------- # ---------- Step 14: Verify pinned versions ----------
log "Pulling Kubernetes node images" log "Verifying installed Kubernetes component versions"
kubeadm config images pull KUBEADM_VERSION="$("${KUBEADM_BIN}" version -o short 2>/dev/null || true)"
KUBECTL_VERSION="$("${KUBECTL_BIN}" version --client -o json 2>/dev/null | jq -r '.clientVersion.gitVersion // empty')"
KUBELET_VERSION="$("${KUBELET_BIN}" --version 2>/dev/null | awk '{print $2}')"
# ---------- Step 11: Clean notice if already joined ---------- [[ "${KUBEADM_VERSION}" =~ ${K8S_SERIES_REGEX} ]] || die "kubeadm version mismatch: ${KUBEADM_VERSION}"
if [[ -f /etc/kubernetes/kubelet.conf ]]; then [[ "${KUBECTL_VERSION}" =~ ${K8S_SERIES_REGEX} ]] || die "kubectl version mismatch: ${KUBECTL_VERSION}"
warn "This node appears to have already been joined before." [[ "${KUBELET_VERSION}" =~ ${K8S_SERIES_REGEX} ]] || die "kubelet version mismatch: ${KUBELET_VERSION}"
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 ---------- # ---------- Step 15: Write join hint ----------
log "Worker node runtime status" log "Writing manual join hint"
systemctl status containerd kubelet --no-pager || true cat >"${JOIN_HINT_FILE}" <<'EOF'
Run your worker join command manually, for example:
sudo kubeadm join <CONTROL_PLANE_IP>:6443 --token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<HASH>
EOF
chmod 600 "${JOIN_HINT_FILE}"
# ---------- Final output ----------
echo echo
echo "Worker node preparation is complete." echo "Worker node preparation is complete."
echo echo
echo "This node is ready for you to run your join command manually." echo "Pinned Kubernetes version:"
echo " ${K8S_VERSION}"
echo
echo "Installed binaries:"
echo " ${KUBEADM_BIN}"
echo " ${KUBECTL_BIN}"
echo " ${KUBELET_BIN}"
echo
echo "Services:"
echo " containerd: $(systemctl is-active containerd || true)"
echo " kubelet: $(systemctl is-active kubelet || true)"
echo
echo "Next step:"
echo " Run your kubeadm join command manually on this worker."
echo
echo "Example hint saved to:"
echo " ${JOIN_HINT_FILE}"
echo echo
echo "Example:" echo "Example:"
echo " kubeadm join 10.28.24.43:6443 --token <token> \\" echo " sudo kubeadm join <CONTROL_PLANE_IP>:6443 --token <TOKEN> \\"
echo " --discovery-token-ca-cert-hash sha256:<hash>" echo " --discovery-token-ca-cert-hash sha256:<HASH>"
echo
echo "After joining, verify on the control-plane node with:"
echo " kubectl get nodes"
echo echo