k8s.github.io

Node Setup

NOTE
In this and the following sections, you will notice some groups of shell commands are enclosed in { }. This is so that you can copy the block from github with the github copy button and paste to your node terminals. Without this, a group of several commands with sudo will stop after the first command and you will probably miss this fact, leading to things not working further on.


In this section we will configure the nodes and install prerequisites such as the container runtime (containerd).

Perform all the following steps on each of controlplane, node01 and node02. For this section you can run the commands simultaneously on all nodes if using iterm2 broadcast (Mac) or tmux (others).

  1. Update the apt package index and install packages needed to use the Kubernetes apt repository:
     {
         sudo apt-get update
         sudo apt-get install -y apt-transport-https ca-certificates curl
     }
    
  2. Set up the required kernel modules and make them persistent
     {
         cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
     overlay
     br_netfilter
     EOF
    
         sudo modprobe overlay
         sudo modprobe br_netfilter
     }
    
  3. Set the required kernel parameters and make them persistent
    {
        cat <<EOF | sudo tee /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
    
        sudo sysctl --system
    }
    
  4. Install the container runtime
     sudo apt-get install -y containerd
    
  5. Configure the container runtime to use systemd Cgroups. This part is the bit many students miss, and if not done results in a controlplane that comes up, then all the pods start crashlooping. kubectl will also fail with an error like The connection to the server x.x.x.x:6443 was refused - did you specify the right host or port?

    1. Create default configuration

       {
           sudo mkdir -p /etc/containerd
           containerd config default | sed 's/SystemdCgroup = false/SystemdCgroup = true/' | sudo tee /etc/containerd/config.toml
       }
      
    2. Restart containerd

      sudo systemctl restart containerd
      
  6. Determine latest version of Kubernetes and store in a shell variable

    KUBE_LATEST=$(curl -L -s https://dl.k8s.io/release/stable.txt | awk 'BEGIN { FS="." } { printf "%s.%s", $1, $2 }')
    
  7. Download the Kubernetes public signing key
     {
         sudo mkdir -p /etc/apt/keyrings
         curl -fsSL https://pkgs.k8s.io/core:/stable:/${KUBE_LATEST}/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
     }
    
  8. Add the Kubernetes apt repository
     echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${KUBE_LATEST}/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
    
  9. Update apt package index, install kubelet, kubeadm and kubectl, and pin their version
     {
         sudo apt-get update
         sudo apt-get install -y kubelet kubeadm kubectl
         sudo apt-mark hold kubelet kubeadm kubectl
     }
    
  10. Configure crictl in case we need it to examine running containers
    sudo crictl config \
        --set runtime-endpoint=unix:///run/containerd/containerd.sock \
        --set image-endpoint=unix:///run/containerd/containerd.sock
    
  11. Prepare extra arguments for kubelet such that when it starts, it listens on the VM’s primary network address and not any NAT one that may be present. This uses the predefined PRIMARY_IP environment variable discusseed earlier

    Paste the following to the terminal

    cat <<EOF | sudo tee /etc/default/kubelet
    KUBELET_EXTRA_ARGS='--node-ip ${PRIMARY_IP}'
    EOF
    

If you used tmux or iterm2 synchronized panes for this section, you should disable the synchronization now.

Next: Control Plane setup</br> Prev: Connectivity (VirtualBox) (Apple Silicon) AWS