#!/usr/bin/env bash # Manual equivalent of the cloud-init user_data for kube-node-33 (node_02). # Run as root on the target VM. # # Before running, generate a fresh join command on the control plane: # kubeadm token create --print-join-command # Then paste it below. set -euo pipefail JOIN_COMMAND="kubeadm join 192.168.0.31:6443 --token --discovery-token-ca-cert-hash sha256:" # --------------------------------------------------------------------------- # Hostname # --------------------------------------------------------------------------- hostnamectl set-hostname kube-node-33 # --------------------------------------------------------------------------- # Packages # --------------------------------------------------------------------------- apt-get update apt-get install -y \ qemu-guest-agent \ openssh-server \ apt-transport-https \ ca-certificates \ curl \ gnupg \ nvme-cli systemctl enable --now qemu-guest-agent systemctl enable --now ssh # --------------------------------------------------------------------------- # nvme-tcp # --------------------------------------------------------------------------- apt-get install -y linux-modules-extra-$(uname -r) modprobe nvme-tcp echo "nvme-tcp" >> /etc/modules-load.d/nvme-tcp.conf # --------------------------------------------------------------------------- # Kernel modules for Kubernetes # --------------------------------------------------------------------------- cat > /etc/modules-load.d/k8s.conf <<'EOF' overlay br_netfilter EOF modprobe overlay modprobe br_netfilter cat > /etc/sysctl.d/k8s.conf <<'EOF' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system # --------------------------------------------------------------------------- # containerd # --------------------------------------------------------------------------- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ > /etc/apt/sources.list.d/docker.list apt-get update && apt-get install -y containerd.io cat > /etc/containerd/config.toml <<'EOF' version = 2 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d" EOF # Registry mirrors pointing to Zot at 192.168.0.30:5000 mkdir -p \ /etc/containerd/certs.d/docker.io \ /etc/containerd/certs.d/registry.k8s.io \ /etc/containerd/certs.d/ghcr.io \ /etc/containerd/certs.d/quay.io cat > /etc/containerd/certs.d/docker.io/hosts.toml <<'EOF' server = "https://registry-1.docker.io" [host."http://192.168.0.30:5000/v2/docker.io"] capabilities = ["pull", "resolve"] skip_verify = true override_path = true EOF cat > /etc/containerd/certs.d/registry.k8s.io/hosts.toml <<'EOF' server = "https://registry.k8s.io" [host."http://192.168.0.30:5000/v2/registry.k8s.io"] capabilities = ["pull", "resolve"] skip_verify = true override_path = true EOF cat > /etc/containerd/certs.d/ghcr.io/hosts.toml <<'EOF' server = "https://ghcr.io" [host."http://192.168.0.30:5000/v2/ghcr.io"] capabilities = ["pull", "resolve"] skip_verify = true override_path = true EOF cat > /etc/containerd/certs.d/quay.io/hosts.toml <<'EOF' server = "https://quay.io" [host."http://192.168.0.30:5000/v2/quay.io"] capabilities = ["pull", "resolve"] skip_verify = true override_path = true EOF systemctl restart containerd # --------------------------------------------------------------------------- # kubelet systemd drop-in # --------------------------------------------------------------------------- mkdir -p /etc/systemd/system/kubelet.service.d cat > /etc/systemd/system/kubelet.service.d/10-containerd.conf <<'EOF' [Unit] After=containerd.service Requires=containerd.service [Service] ExecStartPre=/bin/bash -c 'until [ -S /var/run/containerd/containerd.sock ]; do sleep 1; done' ExecStartPre=/usr/bin/crictl info EOF # --------------------------------------------------------------------------- # kubeadm / kubelet / kubectl v1.32 # --------------------------------------------------------------------------- curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key \ | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /" \ > /etc/apt/sources.list.d/kubernetes.list apt-get update && apt-get install -y kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl # --------------------------------------------------------------------------- # kubectl shell helpers (available after next login / source) # --------------------------------------------------------------------------- cat > /etc/profile.d/kubectl.sh <<'EOF' alias k='kubectl' source <(kubectl completion bash) complete -o default -F __start_kubectl k EOF # --------------------------------------------------------------------------- # Join the cluster # --------------------------------------------------------------------------- $JOIN_COMMAND