#!/bin/bash set -e # Set verbosity if [ "${DEBUG}" = true ]; then set -x KUBEADM_VERBOSE="-v=5" else KUBEADM_VERBOSE="-v=3" fi BIN_DIR="/usr/local/bin" SBIN_DIR="/usr/local/sbin" COMMAND=$1 # Define global compatibility matrix declare -A versions=( ["containerd"]="v2.3.2" ["runc"]="v1.4.3" ["cni"]="v1.9.1" ["crictl"]="v1.36.0" ["kubernetes"]="v1.36.2" ["krel"]="v0.16.2" ) # Helper function to display usage information helper() { cat < You must be sudo to run this script. Commands: join: Join a node to the cluster - Installs all necessary prerequisites, container runtime, CNI plugins, and Kubernetes binaries. - Then joins the node to an existing Kubernetes cluster as a worker or control-plane node. - Requires either KUBEADM_CONFIG, or JOIN_URL + JOIN_TOKEN (JOIN_TOKEN_CACERT_HASH optional, JOIN_ASCP optional). - If KUBEADM_CONFIG is set, it is used as-is via --config and JOIN_URL/JOIN_TOKEN are not required. - If JOIN_TOKEN_CACERT_HASH is provided, it will be used for secure join. - If JOIN_TOKEN_CACERT_HASH is not provided, it will join using --discovery-token-unsafe-skip-ca-verification. - If JOIN_ASCP=true, the node joins as a control-plane node (requires JOIN_TOKEN_CERT_KEY). - Example: JOIN_URL=: JOIN_TOKEN= JOIN_TOKEN_CACERT_HASH=sha256: KUBERNETES_VERSION=v1.30.5 kjoin join - Example: JOIN_URL=: JOIN_TOKEN= JOIN_TOKEN_CERT_KEY= JOIN_TOKEN_CACERT_HASH=sha256: JOIN_ASCP=true KUBERNETES_VERSION=v1.30.5 kjoin join - Example: KUBEADM_CONFIG=/path/to/kubeadm-join-config.yaml kjoin join - Set INSTALL_PACKAGES=true to install required OS packages first (apt/dnf/yum auto-detected). help: Print this help - Displays this help message. - Example: kjoin help Environment variables: +-------------------------+-------------------------------------------------------------+------------+ | Variable | Description | Default | +-------------------------+-------------------------------------------------------------+------------+ | KUBERNETES_VERSION | Version of kubernetes to install. | v1.36.2 | | CONTAINERD_VERSION | Version of container runtime containerd. | v2.3.2 | | RUNC_VERSION | Version of runc to install. | v1.4.3 | | CNI_VERSION | Version of CNI plugins to install. | v1.9.1 | | CRICTL_VERSION | Version of crictl to install. | see matrix | | KUBEADM_CONFIG | Path to the kubeadm config file to use. | Not set | | BIND_PORT | Port to use for the api-server (control-plane join only). | 6443 | | JOIN_TOKEN | Token to join the cluster. | Not set | | JOIN_TOKEN_CACERT_HASH | Token Certificate Authority hash to join the cluster. | Not set | | JOIN_TOKEN_CERT_KEY | Token Certificate Key to join as control-plane. | Not set | | JOIN_URL | URL to join the cluster. | Not set | | JOIN_ASCP | Switch to join either as control plane or worker. | false | | INSTALL_PACKAGES | Install required OS packages via apt/dnf/yum before setup. | false | | DEBUG | Set to true for more verbosity during script execution. | false | +-------------------------+-------------------------------------------------------------+------------+ EOF } # Log functions info() { echo "[INFO] $@"; } warn() { echo "[WARN] $@" >&2; } fatal() { echo "[ERROR] $@" >&2; exit 1; } # Setup architecture setup_arch() { case ${ARCH:=$(uname -m)} in amd64|x86_64) ARCH=amd64 ;; arm64|aarch64) ARCH=arm64 ;; *) fatal "unsupported architecture ${ARCH}" ;; esac SUFFIX=$(uname -s | tr '[:upper:]' '[:lower:]')-${ARCH} } # Function to get compatible components version get_version() { local component=$1 echo "${versions[$component]}" } setup_env() { # Check if running as root [ "$(id -u)" -eq 0 ] || fatal "You need to be root to perform this install" # Set default values KUBERNETES_VERSION=${KUBERNETES_VERSION:-$(get_version "kubernetes")} RELEASE_VERSION=${RELEASE_VERSION:-$(get_version "krel")} JOIN_ASCP=${JOIN_ASCP:-false} CONTAINERD_VERSION=${CONTAINERD_VERSION:-$(get_version "containerd")} RUNC_VERSION=${RUNC_VERSION:-$(get_version "runc")} CNI_VERSION=${CNI_VERSION:-$(get_version "cni")} CRICTL_VERSION=${CRICTL_VERSION:-$(get_version "crictl")} BIND_PORT=${BIND_PORT:-6443} INSTALL_PACKAGES=${INSTALL_PACKAGES:-false} DEBUG=${DEBUG:-false} } # Install OS packages required as prerequisites (optional, gated by INSTALL_PACKAGES) install_packages() { info "installing prerequisite OS packages" if command -v apt-get &> /dev/null; then apt-get update apt-get install -y conntrack iptables socat iproute2 vim kmod procps ebtables ethtool wget curl iputils-ping apt-transport-https ca-certificates gpg bridge-utils elif command -v dnf &> /dev/null; then dnf install -y conntrack-tools iptables socat iproute vim-enhanced kmod procps-ng ebtables ethtool wget curl iputils ca-certificates gnupg2 bridge-utils elif command -v yum &> /dev/null; then yum install -y conntrack-tools iptables socat iproute vim-enhanced kmod procps-ng ebtables ethtool wget curl iputils ca-certificates gnupg2 bridge-utils else fatal "unsupported package manager: neither apt-get, dnf nor yum found" fi } # Check if prerequisites are installed check_prerequisites() { info "Checking if prerequisites are installed" # List of required commands local required_commands=("conntrack" "socat" "ip" "iptables" "modprobe" "sysctl" "systemctl" "nsenter" "ebtables" "ethtool" "wget") for cmd in "${required_commands[@]}"; do if ! command -v $cmd &> /dev/null; then info "$cmd is not installed. Please install it before proceeding." exit 1 fi done } # Configure system settings configure_system_settings() { info "Configure system settings: " info " - disable swap" swapoff -a info " - swap entry process in /etc/fstab" sed -i '/^[^#].*\sswap\s/s/^/#/' /etc/fstab info " - enable required kernel modules" cat < /etc/containerd/config.toml info "configuring containerd config imports" mkdir -p /etc/containerd/conf.d /etc/containerd/certs.d cat <