Chris McCall

DevOps & Software Development

Dell Control Plane

Dell Control Plane

My friend had given me this Dell laptop a while back, he was about to throw it out and I couldn't pass up a free laptop. Up until now I had just used it to play with some amateur radio stuff. It's more recent than my old Mac Mini, so this is my control plane.

Specs

Dell Inspiron 13-7378
Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz 2 Core
Intel HD Graphics 620
12GB RAM

Install Ubuntu & Prepare for the Cluster

Download the Ubuntu 26.04 image and write it to a usb drive with Balena Etcher. These are steps to prepare a node that will be joining my cluster that uses cilium as a CNI and gateway. For a different CNI the install can change slightly.

Apply Kernel Network Settings
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

# Apply
sudo sysctl --system
Disable Swap
sudo swapoff -a

# swapoff won't survive a restart so apply a permanent fix.
# Look for a swap line(look near the last line) and delete any that you see.
sudo vi /etc/fstab/

sudo systemctl daemon-reload
Install the Container Runtime

You can install from source using the directions here, but the apt install is much faster.

sudo apt-get update
sudo apt install containerd

Enable the file system overlay module

sudo modprobe overlay

Create the default config file, then edit it so that runc will use the systemd cgroup driver.

sudo mkdir /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# Search the file for
# "plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.runc.options"
# and look for the "SystemdCgroup = false" setting and change 
# it to "SystemdCgroup = true"

vi /etc/containerd/config.toml

# Restart containerd
systemctl restart containerd
Install Kubernetes components
# Configure apt for the kubernetes repo
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key | sudo 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.36/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# Update with the new repo
sudo apt-get update

sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

sudo systemctl enable --now kubelet
Use Kubeadm to Initialize the Control Plane
# Since I'll be using cilium, I don't need kube-proxy
kubeadm init --skip-phases=addon/kube-proxy

Copy the join command that kubeadm prints out, you'll be using it later on the worker nodes.

Install the kubeconfig to the default location on the control plane. You can also copy this file locally to use kubectl from your own machine.

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Install Cilium

We will use the cilium cli to install cilium.

# Install the cilium cli
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}

With the cli installed, now install cilium.

# Install cilium via the cli
cilium install \
  --helm-set kubeProxyReplacement=true  \
  --helm-set k8sServiceHost=<API_SERVER_IP> \
  --helm-set k8sServicePort=6443
  
# If kube-proxy is removed, cilium should automatically use kubeProxyReplacement
cilium install

# If you want to use BGP Control Plane
cilium install 1.20.1 --set bgpControlPlane.enabled=true

# Verify
cilium status --wait

I am going to be using the gatewayAPI to create httpRoutes for my services, so let's get those CRDs installed.

# GatewayAPI Standard channel
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml

# Update cilium to include gatewayAPI
cilium upgrade --version 1.20.0 \
    --set kubeProxyReplacement=true \
    --set gatewayAPI.enabled=true \
    --set hubble.enabled=false \

Starting off, I'm going to use L2 Announcements along with a <myhouse>.internal domain to access services on my local network.

# Update cilium to enable l2announcements
cilium upgrade --version 1.20.0 \
    --set kubeProxyReplacement=true \
    --set gatewayAPI.enabled=true \
    --set hubble.enabled=false \
    --set l2announcements.enabled=true \

Good to Go?

These are quick steps to get this node up, but there is more configuration needed for how I would like this machine to function. I will write this up in another post so that this one can stay focused on Kubernetes.