2 - Install node

Install the kubernetes nodeand register it in the control node. On a server already running apps with docker and traefik.
Published

April 18, 2026

This machine stops being a “Docker app server” and becomes a Kubernetes-managed worker node.

List running container

First list running containers with docker ps -a. You need to know what will be disrupted.

My result:

CONTAINER ID   IMAGE                                                  COMMAND                  CREATED        STATUS        PORTS                                                              NAMES
05a3e66f7531   ipeseserv3.epfl.ch:88/mote-school-tool:staging         "/app/entrypoint.sh"     2 weeks ago    Up 2 weeks    0.0.0.0:4213->8501/tcp                                             mote-tool
0f1fb2e42cd7   ipeseserv3.epfl.ch:88/env-421-school-tool:staging      "/app/entrypoint.sh"     3 weeks ago    Up 3 weeks    0.0.0.0:4211->8501/tcp                                             env-421-school-tool
3b963cd402bc   ipeseserv3.epfl.ch:88/cas-sese-iaet-tool:staging       "/app/entrypoint.sh"     3 months ago   Up 3 months   0.0.0.0:4212->8501/tcp                                             iaet-tool
0faa9c6b90ba   ipeseserv3.epfl.ch:88/energyscope-calculator:staging   "streamlit run calcu…"   5 months ago   Up 5 months   0.0.0.0:6061->8501/tcp                                             energyscope-calculator
c2f15f3c4403   ipeseserv3.epfl.ch:88/reho-fm:staging                  "gunicorn --bind 0.0…"   9 months ago   Up 9 months   8000/tcp, 0.0.0.0:8000->80/tcp                                     reho-fm
ddc9031d49c3   ipeseserv3.epfl.ch:88/energyscope-quebec:staging       "streamlit run calcu…"   9 months ago   Up 9 months   0.0.0.0:6081->8501/tcp                                             energyscope-quebec
a0b0e3f21f51   ipeseserv3.epfl.ch:88/energyscope-main:staging         "/docker-entrypoint.…"   9 months ago   Up 9 months   0.0.0.0:6041->80/tcp                                               energyscope.ch
6bfaea78e14b   ipeseserv3.epfl.ch:88/flask-entra:v0.4.4               "gunicorn -w 1 -b 0.…"   9 months ago   Up 9 months   8000/tcp, 0.0.0.0:5050->5000/tcp                                   model-documentation
ad38d45342dc   traefik:v2.10                                          "/entrypoint.sh --lo…"   9 months ago   Up 6 weeks    0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8080->8080/tcp   traefik

We currently have:

  • multiple production apps (Streamlit, Flask, etc.)
  • Traefik reverse proxy
  • exposed ports (80, 443, 8080, etc.)

👉 This will NOT coexist nicely with Kubernetes workloads.

Step 1 — Stop and clean up Docker

Kubernetes uses containerd, not Docker engine. Keeping both = chaos.

Stop all running containers

sudo docker stop $(sudo docker ps -q)

Remove containers, images, volumes

sudo docker system prune -a --volumes -f

Uninstall Docker completely

sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo apt-get autoremove -y

#Remove leftover files
sudo rm -rf /var/lib/docker /etc/docker
sudo rm /etc/apt/sources.list.d/docker.list
sudo rm /etc/apt/keyrings/docker.gpg
sudo apt-get update

Step 2 — System prep

update system

sudo apt-get update && sudo apt-get upgrade -y

deactivate swap memory

Kubernetes needs predictable resources - not stricltly true anymore but gives a easier and more predictable installation

# Turn off swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

# Verify swap is off (should return empty)
free -h | grep Swap

Step 3 — Kernel modules

Preparing the Linux kernel so Kubernetes networking works properly - When the system boots, always load these kernel modules. - then load them manually for the current session

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# Verify both loaded
lsmod | grep -E 'overlay|br_netfilter'

Step 4 — Network settings

tell Linux how to handle network traffic for containers and Kubernetes pods: - “If container traffic goes through a virtual network bridge, still apply firewall rules (iptables) to it.”

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

# Verify
sysctl net.ipv4.ip_forward

Step 5 — Install containerd

This replaces Docker as the container runtime.

Kubernetes → kubelet → containerd → containers

sudo apt-get install -y containerd

Generate config

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

Enable systemd cgroups (Required on Ubuntu 24.04)

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

Restart and enable

sudo systemctl restart containerd
sudo systemctl enable containerd

# Verify
sudo systemctl status containerd

Step 6 — Install kubeadm, kubelet, kubectl

sudo apt-get install -y apt-transport-https ca-certificates curl gpg

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

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

sudo apt-mark hold kubelet kubeadm kubectl

# Verify
kubeadm version

Step 7 — Join the cluster

This node connects to the control plane and becomes a worker.

Run this on stivm0052 (control plane) if not done yet

kubeadm token create --print-join-command

This will give you the command to execute in your node to join the control pane. Something like this:

sudo kubeadm join <control-plane-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

Step 8 — Verify from control plane

On the control pane run:

kubectl get nodes

you should see your node here